home *** CD-ROM | disk | FTP | other *** search
- From: decvax!hplabs!hpcnou!dat (Dave Taylor)
- Subject: Msg Shar.part.5
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 9
- Submitted by: decvax!hplabs!hpcnou!dat (Dave Taylor)
-
- # Msg Shar part 5 of 7
-
- # Shell Archive created by hpcnou!dat at Wed Feb 26 15:56:34 1986
-
- # To unpack the enclosed files, please use this file as input to the
- # Bourne (sh) shell. This can be most easily done by the command;
- # sh < thisfilename
-
- # This archive contains;
- # src/notesfile.c src/opt_utils.c src/output_utils.c src/pattern.c
- # src/quit.c src/read_rc.c src/reply.c src/return_addr.c
- # src/savecopy.c src/screen.c src/showmsg.c src/softkeys.c
-
-
- if [ ! -d src ]
- then
- echo creating directory src
- mkdir src
- fi
-
- # ---------- file src/notesfile.c ----------
-
-
- if [ -f src/notesfile.c ]
- then
- echo File 'src/notesfile.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/notesfile.c...
- cat << 'END-OF-FILE' > src/notesfile.c
- /** notesfile.c **/
-
- /** Routine that reads in a file comprised of saved messages from
- 'notes'.
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
- #include <errno.h>
-
- char *notes_machine();
-
- extern int errno;
-
- int
- read_notesfile()
- {
- /** read in the current mailfile, assuming it's actually a set
- of stored notes from the notes program... **/
-
- char buffer[LONG_STRING];
- register int line = 0, count = 0;
- long bytes = 0L, line_bytes = 0L;
- static int first_read = 0;
- int count_x , count_y = 17;
-
- dprint0("read_notesfile()\n");
-
- if (! first_read++) {
- MoveCursor(LINES-2, 0);
- CleartoEOS();
- PutLine(LINES-1, 0, "Reading in %s, message: 0", infile);
- count_x = LINES-1;
- count_y = 22 + strlen(infile);
- }
- else {
- PutLine(LINES-2, 0, "Reading message: 0");
- count_x = LINES-2;
- }
-
- while (fgets(buffer, LONG_STRING, mailfile) != NULL) {
-
- if (line == 0) {
-
- /** Double check to make sure this is okay... if the first
- word is "From " then we're actually reading a normal
- file so cruise over to the read_headers() routine
- instead! **/
-
- if (first_word(buffer, "From ")) {
- notesfile = 0; /* turn that bloody flag off! */
- rewind(mailfile); /* back up in da file... */
- return( read_headers(FALSE) );
- }
- }
-
- line_bytes = (long) strlen(buffer);
- line++;
-
- if (first_word(buffer, "/***** ")) {
- if (real_notes_header(buffer, &header_table[count])) {
- header_table[count].offset = (long) bytes;
- header_table[count].delete = 0;
- header_table[count++].lines = line;
- header_table[count].priority = 0;
- PutLine(count_x, count_y, "%d", count);
- if (count > 1)
- header_table[count-2].lines = line -header_table[count-2].lines;
- }
- }
- bytes += (long) line_bytes;
- }
-
- total_lines_in_file = line;
- header_table[count-1].lines = line - header_table[count-1].lines;
-
- rewind(mailfile);
-
- return(count);
- }
-
- int
- real_notes_header(buffer, entry)
- char *buffer;
- struct header_rec *entry;
- {
- /** confirms that we're looking at a REAL notes header,
- and if so, saves it in the appropriate data entry **/
-
- char subjectbuffer[SLEN], timebuffer[NLEN], lastbuffer[NLEN],
- am_pm[NLEN], the_day[NLEN], nullbuffer[NLEN];
-
- dprint1("real_notes_header(buffer='%s')\n", buffer);
-
- strcpy(nullbuffer, "NULL");
- strcpy(lastbuffer, "LAST");
-
- sscanf(buffer, "%*s %s %*c %s %*c %s %s %s %s %s %s",
- subjectbuffer, entry->from,
- timebuffer, am_pm, entry->month, the_day,
- lastbuffer, nullbuffer);
-
- if (strcmp(lastbuffer, "LAST") == 0)
- return(0);
-
- if (strcmp(nullbuffer,"NULL") != 0)
- return(0);
-
- if (timebuffer[1] != ':' && timebuffer[2] != ':')
- return(0);
-
- /* now let's play format! */
-
- clean_up(subjectbuffer);
-
- sprintf(entry->subject, "Note from group %s", subjectbuffer);
- sprintf(entry->day,"%d", atoi(the_day));
- sprintf(entry->year,"%d", atoi(lastbuffer) % 100);
- sprintf(entry->time,"%s %s", timebuffer, am_pm);
-
- return(1);
- }
-
- char *notes_machine()
- {
- /** For those rare notes posted by someone on the machine that
- the notesfiles are saved from, this routine will fix the
- address to ensure it's valid. The return value will be
- either 'machine!' or NULL if it's from the machine we're on
- **/
-
- static char machine_group[NLEN];
- char buffer[SLEN];
- register int i;
-
- dprint0("notes_machine()\n");
-
- if (fseek(mailfile, header_table[current-1].offset, 0L) != 0) {
- error("error [notes_machine] trying to seek!");
- dprint1("\n\tError %d trying to seek into file!\n\n", errno);
- return( NULL );
- }
-
- if (fgets(buffer, SLEN, mailfile) == NULL) {
- error("error [notes_machine] trying to read!");
- dprint1("\n\tError %d trying to read file!\n\n", errno);
- return( NULL );
- }
-
- sscanf(buffer,"%*s %s", machine_group);
-
- for (i=0; machine_group[i] != ':'; i++)
- ;
-
- machine_group[i] = '\0';
-
- return( (char *) machine_group);
- }
- END-OF-FILE
-
- size=`wc -c < src/notesfile.c`
-
- if [ $size != 3955 ]
- then
- echo Warning: src/notesfile.c changed - should be 3955 bytes, not $size bytes
- fi
-
- chmod 644 src/notesfile.c
-
- # ---------- file src/opt_utils.c ----------
-
-
- if [ -f src/opt_utils.c ]
- then
- echo File 'src/opt_utils.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/opt_utils.c...
- cat << 'END-OF-FILE' > src/opt_utils.c
- /** opt_utils.c **/
-
- /** This file contains routines that might be needed for the various
- machines that the mailer can run on. Please check the Makefile
- for more help and/or information.
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #ifdef BSD
- # include <pwd.h>
- #endif
-
- #ifdef UTS
- # include <sys/utsname.h>
-
- gethostname(hostname,size) /* get name of current host */
- int size;
- char *hostname;
- {
- /** Return the name of the current host machine. UTS only **/
-
- /** This routine compliments of Scott McGregor at the HP
- Corporate Computing Center **/
-
- int uname();
- struct utsname name;
-
- (void) uname(&name);
- (void) strncpy(hostname,name.nodename,size-1);
- hostname[size] = '\0';
-
- }
-
- #endif /* def UTS */
-
- #ifdef BSD
-
- cuserid(username)
- char *username;
- {
- /** Added for compatibility with Bell systems, this is the last-ditch
- attempt to get the users login name, after getlogin() fails. It
- instantiates "username" to the name of the user...
- **/
-
- struct passwd *password_entry, *getpwuid();
-
- password_entry = getpwuid(getuid());
-
- strcpy(username, password_entry->pw_name);
- }
-
- /** some supplementary string functions for Berkeley Unix systems **/
-
- strspn(source, keys)
- char *source, *keys;
- {
- /** This function returns the length of the substring of
- 'source' (starting at zero) that consists ENTIRELY of
- characters from 'keys'. This is used to skip over a
- defined set of characters with parsing, usually.
- **/
-
- register int loc = 0, key_index = 0;
-
- while (source[loc] != '\0') {
- key_index = 0;
- while (keys[key_index] != source[loc])
- if (keys[key_index++] == '\0')
- return(loc);
- loc++;
- }
-
- return(loc);
- }
-
- strcspn(source, keys)
- char *source, *keys;
- {
- /** This function returns the length of the substring of
- 'source' (starting at zero) that consists entirely of
- characters NOT from 'keys'. This is used to skip to a
- defined set of characters with parsing, usually.
- NOTE that this is the opposite of strspn() above
- **/
-
- register int loc = 0, key_index = 0;
-
- while (source[loc] != '\0') {
- key_index = 0;
- while (keys[key_index] != '\0')
- if (keys[key_index++] == source[loc])
- return(loc);
- loc++;
- }
-
- return(loc);
- }
-
- char *strtok(source, keys)
- char *source, *keys;
- {
- /** This function returns a pointer to the next word in source
- with the string considered broken up at the characters
- contained in 'keys'. Source should be a character pointer
- when this routine is first called, then NULL subsequently.
- When strtok has exhausted the source string, it will
- return NULL as the next word.
-
- WARNING: This routine will DESTROY the string pointed to
- by 'source' when first invoked. If you want to keep the
- string, make a copy before using this routine!!
- **/
-
- register int last_ch;
- static char *sourceptr;
- char *return_value;
-
- if (source != NULL)
- sourceptr = source;
-
- if (*sourceptr == '\0')
- return(NULL); /* we hit end-of-string last time!? */
-
- sourceptr += strspn(sourceptr, keys); /* skip leading crap */
-
- if (*sourceptr == '\0')
- return(NULL); /* we've hit end-of-string */
-
- last_ch = strcspn(sourceptr, keys); /* end of good stuff */
-
- return_value = sourceptr; /* and get the ret */
-
- sourceptr += last_ch; /* ...value */
-
- if (*sourceptr != '\0') /* don't forget if we're at END! */
- sourceptr++; /* and skipping for next time */
-
- return_value[last_ch] = '\0'; /* ..ending right */
-
- return((char *) return_value); /* and we're outta here! */
- }
-
- char *strpbrk(source, keys)
- char *source, *keys;
- {
- /** Returns a pointer to the first character of source that is any
- of the specified keys, or NULL if none of the keys are present
- in the source string.
- **/
-
- register int loc = 0, key_index = 0;
-
- while (source[loc] != '\0') {
- key_index = 0;
- while (keys[key_index] != '\0')
- if (keys[key_index++] == source[loc])
- return((char *) (source + loc));
- loc++;
- }
-
- return(NULL);
- }
-
- #endif
- END-OF-FILE
-
- size=`wc -c < src/opt_utils.c`
-
- if [ $size != 4053 ]
- then
- echo Warning: src/opt_utils.c changed - should be 4053 bytes, not $size bytes
- fi
-
- chmod 644 src/opt_utils.c
-
- # ---------- file src/output_utils.c ----------
-
-
- if [ -f src/output_utils.c ]
- then
- echo File 'src/output_utils.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/output_utils.c...
- cat << 'END-OF-FILE' > src/output_utils.c
- /** output_utils.c **/
-
- /** This file contains routines used for output in the MSG program.
-
- These routines (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
-
- static char err_buffer[SLEN]; /* store last error message */
-
- static char central_message_buffer[SLEN];
-
-
- show_last_error()
- {
- /** rewrite last error message! **/
-
- error(err_buffer);
- }
-
- clear_error()
- {
- MoveCursor(LINES,0);
- CleartoEOLN();
- err_buffer[0] = '\0';
- }
-
- set_error(s)
- char *s;
- {
- strcpy(err_buffer, s);
- }
-
- error(s)
- char *s;
- {
- /** outputs error 's' to screen at line 22, centered! **/
-
- MoveCursor(LINES,0);
- CleartoEOLN();
- PutLine(LINES,(COLUMNS-strlen(s))/2,s);
- if (strlen(s) > 0)
- dprint1("\nError: %s\n\n", s);
- fflush(stdout);
- strcpy(err_buffer, s); /* save it too! */
- }
-
- error1(s, a)
- char *s, *a;
- {
- /** same as error, but with a 'printf' argument **/
- char buffer[SLEN];
-
- sprintf(buffer,s,a);
- error(buffer);
- }
-
- error2(s, a1, a2)
- char *s, *a1, *a2;
- {
- /** same as error, but with two 'printf' arguments **/
- char buffer[SLEN];
-
- sprintf(buffer,s, a1, a2);
- error(buffer);
- }
-
- prompt(s)
- char *s;
- {
- /** prompt user for input on LINES-3 line, left justified **/
-
- PutLine(LINES-3,0,s);
- CleartoEOLN();
- }
-
- prompt1(s,a)
- char *s, *a;
- {
- /** same as prompt, but with a 'printf' argument **/
- char buffer[SLEN];
-
- sprintf(buffer,s,a);
- prompt(buffer);
- }
-
-
- set_central_message(string, arg)
- char *string, *arg;
- {
- /** set up the given message to be displayed in the center of
- the current window **/
-
- sprintf(central_message_buffer, string, arg);
- }
-
- display_central_message()
- {
- /** display the message if set... **/
-
- if (central_message_buffer[0] != '\0') {
- ClearLine(LINES-15);
- Centerline(LINES-15, central_message_buffer);
- fflush(stdout);
- }
- }
-
- clear_central_message()
- {
- /** clear the central message buffer **/
-
- central_message_buffer[0] = '\0';
- }
- END-OF-FILE
-
- size=`wc -c < src/output_utils.c`
-
- if [ $size != 1861 ]
- then
- echo Warning: src/output_utils.c changed - should be 1861 bytes, not $size bytes
- fi
-
- chmod 644 src/output_utils.c
-
- # ---------- file src/pattern.c ----------
-
-
- if [ -f src/pattern.c ]
- then
- echo File 'src/pattern.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/pattern.c...
- cat << 'END-OF-FILE' > src/pattern.c
- /** pattern.c **/
-
- /** General pattern matching for the MSG mailer.
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include <errno.h>
-
- #include "headers.h"
-
- static char pattern[SLEN] = { "" };
- static char alt_pattern[SLEN] = { "" };
-
- extern int errno;
-
- int
- pattern_match()
- {
- /** Get a pattern from the user and try to match it with the
- from/subject lines being displayed. If matched (ignoring
- case), move current message pointer to that message, if
- not, error and return ZERO **/
-
- register int i;
-
- PutLine(LINES-3,40,"/ =match anywhere in messages");
-
- PutLine(LINES-1,0, "Match Pattern:");
-
- if (pattern_enter(pattern, alt_pattern, LINES-1, 16,
- "Match Pattern (in entire mailbox):"))
- if (strlen(alt_pattern) > 0)
- return(match_in_message(alt_pattern));
- else
- return(1);
-
- if (strlen(pattern) == 0)
- return(0);
-
- for (i = current; i < message_count; i++) {
- if (from_matches(i, pattern)) {
- current = ++i;
- return(1);
- }
- else if (subject_matches(i, pattern)) {
- current = ++i;
- return(1);
- }
- }
-
- return(0);
- }
-
- int
- from_matches(message_number, pattern)
- int message_number;
- char *pattern;
- {
- /** Returns true iff the pattern occurs in it's entirety
- in the from line of the indicated message **/
-
-
- return( in_string(header_table[message_number].from, pattern) );
- }
-
- int
- subject_matches(message_number, pattern)
- int message_number;
- char *pattern;
- {
- /** Returns true iff the pattern occurs in it's entirety
- in the subject line of the indicated message **/
-
-
- return( in_string(header_table[message_number].subject, pattern) );
- }
-
- match_in_message(pattern)
- char *pattern;
- {
- /** Match a string INSIDE a message...starting at the current
- message read each line and try to find the pattern. As
- soon as we do, set current and leave!
- Returns 1 if found, 0 if not
- **/
-
- char buffer[LONG_STRING];
- int message_number;
- long location;
-
- dprint1("match_in_message(pattern='%s')\n", pattern);
-
- location = header_table[current-1].offset;
- message_number = current-1;
-
- if (fseek(mailfile, location, 0) != 0) {
-
- dprint2("\tfseek(mailfile, %ld, 0) failed with error %d\n",
- location, errno);
-
- error1("msg [match] failed looking %ld bytes into file",
- location);
- return(1); /* fake it out to avoid replacing error message */
- }
-
- error("searching for pattern...");
-
- while (fgets(buffer, LONG_STRING, mailfile) != NULL) {
-
- if (in_string(buffer, pattern)) {
- current = message_number;
- clear_error();
- return(1);
- }
-
- location += strlen(buffer);
-
- if (location > header_table[message_number].offset)
- message_number++;
- }
-
- return(0);
- }
- END-OF-FILE
-
- size=`wc -c < src/pattern.c`
-
- if [ $size != 2675 ]
- then
- echo Warning: src/pattern.c changed - should be 2675 bytes, not $size bytes
- fi
-
- chmod 644 src/pattern.c
-
- # ---------- file src/quit.c ----------
-
-
- if [ -f src/quit.c ]
- then
- echo File 'src/quit.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/quit.c...
- cat << 'END-OF-FILE' > src/quit.c
- /** quit.c **/
-
- /** quit: leave the current mailbox and quit the program.
-
- (C) Copyright 1985, Dave Taylor
- **/
-
- #ifndef TRUE
- #define TRUE 1
- #endif
-
- quit()
- {
- /* a wonderfully short routine!! */
-
- leave_mbox();
-
- leave();
- }
-
- resync()
- {
- /* leave the current mailbox and read it in again. This
- is used as needed to allow editing of messages and so
- on... */
-
- leave_mbox();
-
- error("reading mailfile in again...");
-
- newmbox(2, TRUE);
- showscreen();
- }
- END-OF-FILE
-
- size=`wc -c < src/quit.c`
-
- if [ $size != 466 ]
- then
- echo Warning: src/quit.c changed - should be 466 bytes, not $size bytes
- fi
-
- chmod 644 src/quit.c
-
- # ---------- file src/read_rc.c ----------
-
-
- if [ -f src/read_rc.c ]
- then
- echo File 'src/read_rc.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/read_rc.c...
- cat << 'END-OF-FILE' > src/read_rc.c
- /** read_rc.c **/
-
- /** (C) Copyright 1985, Dave Taylor **/
-
- /** This file contains programs to allow the user to have a .msgrc file
- in their home directory containing any of the following:
-
- fullname= <username string>
- maildir = <directory>
- mailbox = <file>
- editor = <editor>
- savemail= <savefile>
- shell = <shell>
- print = <print command>
- weedout = <list of headers to weed out>
- prefix = <copied message prefix string>
-
- alternatives = <list of addresses that forward to us>
-
- and/or the logical arguments:
-
- autocopy [on|off]
- copy [on|off]
- resolve [on|off]
- weed [on|off]
- noheader [on|off]
- titles [on|off]
- editout [on|off]
- savebyname [on|off]
- movepage [on|off]
-
- Lines starting with '#' are considered comments and are not checked
- any further!
-
- Modified 10/85 to know about "Environment" variables..
- Modified 12/85 for the 'prefix' option
- Modified 2/86 for the "movepage" flag
- **/
-
- #include <stdio.h>
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- #include "headers.h"
-
- char *shift_lower(), *strtok(), *getenv();
-
- #define NOTWEEDOUT 0
- #define WEEDOUT 1
- #define ALTERNATIVES 2
-
- read_rc_file()
- {
- /** this routine does all the actual work of reading in the
- .rc file... **/
-
- FILE *file;
- char buffer[SLEN], filename[SLEN];
- char word1[SLEN], word2[SLEN];
- int errors = 0, last = NOTWEEDOUT;
-
- dprint0("read_rc_file()\n");
-
- sprintf(filename,"%s/%s", home, msgrcfile);
-
- default_weedlist();
-
- alternative_addresses = NULL; /* none yet! */
-
- if ((file = fopen(filename, "r")) == NULL)
- return; /* we're done! */
-
- while (fgets(buffer, SLEN, file) != NULL) {
- no_ret(buffer); /* remove return */
- if (buffer[0] == '#') { /* comment */
- last = NOTWEEDOUT;
- continue;
- }
- if (strlen(buffer) < 2) { /* empty line */
- last = NOTWEEDOUT;
- continue;
- }
-
- breakup(buffer, word1, word2);
-
- strcpy(word1, shift_lower(word1)); /* to lower case */
-
- if (word2[0] == 0 && (last != WEEDOUT || last != ALTERNATIVES)) {
- fprintf(stderr, "Malformed line from .msgrc file: %s\n", buffer);
- errors++;
- continue;
- }
-
- if (equal(word1,"maildir") || equal(word1,"folders")) {
- expand_env(folders, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "fullname") || equal(word1,"username") ||
- equal(word1, "name")) {
- strcpy(full_username, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "prefix")) {
- strcpy(prefixchars, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "shell")) {
- expand_env(shell, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "mailbox")) {
- expand_env(mailbox, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "editor") || equal(word1,"mailedit")) {
- expand_env(editor, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "savemail") || equal(word1, "saveto")) {
- expand_env(savefile, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "print") || equal(word1, "printmail")) {
- expand_env(printout, word2);
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "autocopy")) {
- auto_copy = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "copy") || equal(word1, "auto_cc")) {
- auto_cc = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "resolve")) {
- resolve_mode = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "weed")) {
- filter = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "noheader")) {
- noheader = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "titles")) {
- title_messages = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "editout")) {
- edit_outbound = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "savebyname") || equal(word1, "savename")) {
- save_by_name = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "movepage") || equal(word1, "page") ||
- equal(word1, "movewhenpaged")) {
- move_when_paged = equal(shift_lower(word2), "on");
- last = NOTWEEDOUT;
- }
- else if (equal(word1, "weedout")) {
- weedout(word2);
- last = WEEDOUT;
- }
- else if (equal(word1, "alternatives")) {
- alternatives(word2);
- last = ALTERNATIVES;
- }
- else if (last == WEEDOUT) /* could be multiple line weedout */
- weedout(buffer);
- else if (last == ALTERNATIVES) /* multi-line addresses */
- alternatives(buffer);
- else {
- fprintf(stderr, "Unknown line from .rc file: %s\n", buffer);
- errors++;
- }
- }
-
- if (errors) {
- fprintf(stderr,"Msg quit from errors in .msgrc file\n");
- exit(errors);
- }
- }
-
- weedout(string)
- char *string;
- {
- /** This routine is called with a list of headers to weed out. **/
-
- register int i;
- char *strptr, *header;
-
- dprint1("weedout(string='%s')\n", string);
-
- strptr = (char *) string;
-
- while ((header = strtok(strptr, "\t ,\"'")) != NULL) {
- if (weedcount == MAX_IN_WEEDLIST)
- exit(fprintf(stderr, "Read in too many weed headers. Max is %d\n",
- MAX_IN_WEEDLIST-1));
- if (strlen(header) > 0)
- if (strlen(header) > NLEN)
- fprintf(stderr, "Bad weed header: %s. Too Long - Len is < %d!\n",
- header, NLEN);
- else {
- for (i=0; i < strlen(header); i++)
- if (header[i] == '_') header[i] = ' ';
- strncpy(weedlist[weedcount++], header, NLEN);
- }
- strptr = (char *) NULL;
- }
- }
-
- alternatives(string)
- char *string;
- {
- /** This routine is called with a list of alternative addresses
- that you may receive mail from (forwarded) **/
-
- char *strptr, *address;
- struct addr_rec *current_record, *previous_record;
-
- dprint1("alternatives(string='%s')\n", string);
-
- previous_record = NULL;
-
- strptr = (char *) string;
-
- while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
- if (previous_record == NULL) {
- previous_record = (struct addr_rec *)
- malloc(sizeof *alternative_addresses);
-
- strcpy(previous_record->address, address);
- previous_record->next = NULL;
- alternative_addresses = previous_record;
- }
- else {
- current_record = (struct addr_rec *)
- malloc(sizeof *alternative_addresses);
-
- strcpy(current_record->address, address);
- current_record->next = NULL;
- previous_record->next = current_record;
- previous_record = current_record;
- }
- strptr = (char *) NULL;
- }
- }
-
- default_weedlist()
- {
- /** install the default headers to weed out! **/
-
- dprint0("default_weedlist()\n");
-
- weedcount = 0;
-
- strncpy(weedlist[weedcount++], ">From", NLEN);
- strncpy(weedlist[weedcount++], "In-Reply-To", NLEN);
- strncpy(weedlist[weedcount++], "References", NLEN);
- strncpy(weedlist[weedcount++], "Newsgroups", NLEN);
- strncpy(weedlist[weedcount++], "Received", NLEN);
- strncpy(weedlist[weedcount++], "Apparently-To:", NLEN);
- strncpy(weedlist[weedcount++], "Message-Id:", NLEN);
- }
-
- int
- matches_weedlist(buffer)
- char *buffer;
- {
- /** returns true iff the first 'n' characters of 'buffer'
- match an entry of the weedlist **/
-
- register int i;
-
- dprint1("matches_weedlist(buffer='%s')\n", buffer);
-
- for (i=0;i < weedcount; i++)
- if (strncmp(buffer, weedlist[i], strlen(weedlist[i])) == 0)
- return(1);
-
- return(0);
- }
-
- breakup(buffer, word1, word2)
- char *buffer, *word1, *word2;
- {
- /** This routine breaks buffer down into word1, word2 where
- word1 is alpha characters only, and there is an equal
- sign delimiting the two...
- alpha = beta
- For lines with more than one 'rhs', word2 is set to the
- entire string...
- **/
-
- register int i;
-
- for (i=0;i<strlen(buffer) && isalpha(buffer[i]); i++)
- word1[i] = buffer[i];
-
- word1[i++] = '\0'; /* that's the first word! */
-
- /** spaces before equal sign? **/
-
- while (buffer[i] == ' ' || buffer[i] == '\t') i++;
-
- if (buffer[i] == '=') i++;
-
- /** spaces after equal sign? **/
-
- while (buffer[i] == ' ' || buffer[i] == '\t') i++;
-
- if (i < strlen(buffer))
- strcpy(word2, (char *) (buffer + i));
- else
- word2[0] = '\0';
- }
-
- expand_env(dest, buffer)
- char *dest, *buffer;
- {
- /** expand possible metacharacters in buffer and then copy
- to dest...
- This routine knows about "~" being the home directory,
- and "$xxx" being an environment variable.
- **/
-
- char *word, *string, next_word[SLEN];
-
- if (buffer[0] == '/') {
- dest[0] = '/';
- dest[1] = '\0';
- }
- else
- dest[0] = '\0';
- string = (char *) buffer;
-
- while ((word = strtok(string, "/")) != NULL) {
- if (word[0] == '$') {
- strcpy(next_word, getenv((char *) (word + 1)));
- if (strlen(next_word) == 0)
- leave(printf("\n\rCan't expand environment variable '%s'\n\r",
- word));
- }
- else if (word[0] == '~' && word[1] == '\0')
- strcpy(next_word, home);
- else
- strcpy(next_word, word);
-
- sprintf(dest, "%s%s%s", dest, (strlen(dest) > 0? "/":""),
- next_word);
-
- string = (char *) NULL;
- }
- }
- END-OF-FILE
-
- size=`wc -c < src/read_rc.c`
-
- if [ $size != 9083 ]
- then
- echo Warning: src/read_rc.c changed - should be 9083 bytes, not $size bytes
- fi
-
- chmod 644 src/read_rc.c
-
- # ---------- file src/reply.c ----------
-
-
- if [ -f src/reply.c ]
- then
- echo File 'src/reply.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/reply.c...
- cat << 'END-OF-FILE' > src/reply.c
- /** reply.c **/
-
- /*** routine allows replying to the sender of the current message
-
- (C) Copyright 1985, Dave Taylor
- ***/
-
- #include "headers.h"
- #ifndef BSD
- # include <sys/utsname.h>
- #endif
-
- /** Note that this routine generates automatic header information
- for the subject and (obviously) to lines, but that these can
- be altered while in the editor composing the reply message!
- **/
-
- char *strip_parens(), *get_token(), *notes_machine();
-
- int
- reply()
- {
- /** Reply to the current message. Returns non-zero iff
- the screen has to be rewritten. **/
-
- char return_address[LONG_SLEN], subject[SLEN];
- int return_value;
-
- dprint0("reply()\n");
-
- get_return(return_address);
-
- if (header_table[current-1].subject[0] != '\0') {
- if ((strncmp("Re:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("RE:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("re:", header_table[current-1].subject, 3) == 0))
- strcpy(subject, header_table[current-1].subject);
- else {
- strcpy(subject,"Re: ");
- strcat(subject,header_table[current-1].subject);
- }
- return_value = send(return_address, subject, TRUE);
- }
- else
- return_value = send(return_address, "Re: your mail", TRUE);
-
- return(return_value);
- }
-
- int
- reply_to_everyone()
- {
- /** Reply to everyone who received the current message.
- This includes other people in the 'To:' line and people
- in the 'Cc:' line too. Returns non-zero iff the screen
- has to be rewritten. **/
-
- char return_address[LONG_SLEN], subject[SLEN];
- char full_address[VERY_LONG_STRING];
- int return_value;
-
- dprint0("reply_to_everyone()\n");
-
- get_return(return_address);
-
- strcpy(full_address, return_address); /* sender gets copy */
-
- get_and_expand_everyone(return_address, full_address);
-
- if (header_table[current-1].subject[0] != '\0') {
- if ((strncmp("Re:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("RE:", header_table[current-1].subject, 3) == 0) ||
- (strncmp("re:", header_table[current-1].subject, 3) == 0))
- strcpy(subject, header_table[current-1].subject);
- else {
- strcpy(subject,"Re: ");
- strcat(subject,header_table[current-1].subject);
- }
- return_value = send(full_address, subject, TRUE);
- }
- else
- return_value = send(full_address, "Re: your mail", TRUE);
-
- return(return_value);
-
- }
-
- int
- forward()
- {
- /** Forward the current message. What this actually does is
- to set auto_copy to true, then call 'send' to get the
- address and route the mail.
- **/
-
- char subject[SLEN], address[VERY_LONG_STRING];
- int original_cc, results, edit_msg;
-
- dprint0("forward()\n");
-
- original_cc = auto_copy;
- address[0] = '\0';
-
- edit_msg = (want_to("Edit outgoing message (y/n) ? ",'y',FALSE) != 'n');
- printf("%s", edit_msg? "Yes" : "No");
-
- auto_cc = TRUE; /* we want a copy */
-
- if (strlen(header_table[current-1].subject) > 0) {
- strcpy(subject,header_table[current-1].subject);
- results = send(address, subject, edit_msg);
- }
- else
- results = send(address, "Forwarded Mail...", edit_msg);
-
- auto_copy = original_cc;
-
- return(results);
- }
-
- get_and_expand_everyone(return_address, full_address)
- char *return_address, *full_address;
- {
- /** Read the current message, extracting addresses from the 'To:'
- and 'Cc:' lines. As each address is taken, ensure that it
- isn't to the author of the message NOR to us. If neither,
- prepend with current return address and append to the
- 'full_address' string.
- **/
-
- char ret_address[LONG_SLEN], buf[LONG_SLEN], new_address[LONG_SLEN];
- char *bufptr, *address;
- int in_message = 1, first_pass = 0;
-
- dprint1("get_and_expand_everyone(return_address='%s', <buffer>)\n",
- return_address);
-
- /** First off, get to the first line of the message desired **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- error1("msg [seek] couldn't read %d bytes into file",
- header_table[current-1].offset);
- return;
- }
-
- /** okay! Now we're there! **/
-
- /** let's fix the ret_address to reflect the return address of this
- message with '%s' instead of the persons login name... **/
-
- translate_return(return_address, ret_address);
-
- /** now let's parse the actual message! **/
-
- while (in_message) {
- in_message = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
- if (first_word(buf, "From ") && first_pass++ != 0)
- in_message = FALSE;
- else if (first_word(buf, "To:") || first_word(buf, "Cc:") ||
- first_word(buf, "CC:") || first_word(buf, "cc:")) {
- do {
- no_ret(buf);
-
- bufptr = (char *) (strip_parens(buf) + 3); /* 3 = strlen of prompt */
-
- while ((address = get_token(bufptr, "\t, ", 0)) != NULL) {
- if (okay_address(address, return_address)) {
- sprintf(new_address, ret_address, address);
- optimize_and_add(new_address, full_address);
- }
- bufptr = NULL;
- }
-
- in_message = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
-
- } while (in_message && whitespace(buf[0]));
-
- }
- else if (strlen(buf) < 2) /* done with header */
- in_message = FALSE;
- }
- }
-
- int
- okay_address(address, return_address)
- char *address, *return_address;
- {
- /** This routine checks to ensure that the address we just got
- from the "To:" or "Cc:" line isn't us AND isn't the person
- who sent the message. Returns true iff neither is the case **/
-
- char our_address[SLEN];
- struct addr_rec *alternatives;
-
- if (in_string(address, return_address))
- return(FALSE);
-
- sprintf(our_address, "%s!%s", hostname, username);
-
- if (in_string(address, our_address))
- return(FALSE);
-
- sprintf(our_address, "%s@%s", username, hostname);
-
- if (in_string(address, our_address))
- return(FALSE);
-
- alternatives = alternative_addresses;
-
- while (alternatives != NULL) {
- if (in_string(address, alternatives->address))
- return(FALSE);
- alternatives = alternatives->next;
- }
-
- return(TRUE);
- }
-
- optimize_and_add(new_address, full_address)
- char *new_address, *full_address;
- {
- /** This routine will add the new address to the list of addresses
- in the full address buffer IFF it doesn't already occur. It
- will also try to fix dumb hops if possible, specifically hops
- of the form ...a!b...!a... and hops of the form a@b@b etc
- **/
-
- register int len, host_count = 0, i;
- char hosts[MAX_HOPS][SLEN]; /* array of machine names */
- char *host, *addrptr;
-
- if (in_string(full_address, new_address))
- return(1); /* duplicate address */
-
- /** optimize **/
- /* break down into a list of machine names, checking as we go along */
-
- addrptr = (char *) new_address;
-
- while ((host = get_token(addrptr, "!", 1)) != NULL) {
- for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
- ;
-
- if (i == host_count) {
- strcpy(hosts[host_count++], host);
- if (host_count == MAX_HOPS) {
- error("Can't build return address - hit MAX_HOPS limit!");
- return(1);
- }
- }
- else
- host_count = i + 1;
- addrptr = NULL;
- }
-
- /** fix the ARPA addresses, if needed **/
-
- if (chloc(hosts[host_count-1], '@') > -1)
- fix_arpa_address(hosts[host_count-1]);
-
- /** rebuild the address.. **/
-
- new_address[0] = '\0';
-
- for (i = 0; i < host_count; i++)
- sprintf(new_address, "%s%s%s", new_address,
- new_address[0] == '\0'? "" : "!",
- hosts[i]);
-
- dprint1("\tgenerated address '%s'\n", new_address);
-
- if (full_address[0] == '\0')
- strcpy(full_address, new_address);
- else {
- len = strlen(full_address);
- full_address[len ] = ',';
- full_address[len+1] = ' ';
- full_address[len+2] = '\0';
- strcat(full_address, new_address);
- }
-
- return(0);
- }
-
- get_return_name(address, name)
- char *address, *name;
- {
- /** Given the address (either a single address or a combined list
- of addresses) extract the login name of the first person on
- the list and return it as 'name'. Modified to stop at
- any non-alphanumeric character. **/
-
- /** An important note to remember is that it isn't vital that this
- always returns just the login name, but rather that it always
- returns the SAME name. If the persons' login happens to be,
- for example, joe.richards, then it's arguable if the name
- should be joe, or the full login. It's really immaterial, as
- indicated before, so long as we ALWAYS return the same name! **/
-
- /** Another note: modified to return the argument as all lowercase
- always... **/
-
- char single_address[LONG_SLEN];
- register int i, loc, index = 0;
-
- /* first step - copy address up to a comma, space, or EOLN */
-
- for (i=0; address[i] != ',' && ! whitespace(address[i]) &&
- address[i] != '\0'; i++)
- single_address[i] = address[i];
- single_address[i] = '\0';
-
- /* Now is it an ARPA address?? */
-
- if ((loc = chloc(single_address, '@')) != -1) { /* Yes */
-
- /* At this point the algorithm is to keep shifting our copy
- window left until we hit a '!'. The login name is then
- located between the '!' and the first metacharacter to
- it's right (ie '%', ':' or '@'). */
-
- for (i=loc; single_address[i] != '!' && i > -1; i--)
- if (single_address[i] == '%' ||
- single_address[i] == ':' ||
- single_address[i] == '.' || /* no domains */
- single_address[i] == '@') loc = i-1;
-
- if (single_address[i] == '!') i++;
-
- for (index = 0; index < loc - i + 1; index++)
- name[index] = tolower(single_address[index+i]);
- name[index] = '\0';
- }
- else { /* easier - standard USENET address */
-
- /* This really is easier - we just cruise left from the end of
- the string until we hit either a '!' or the beginning of the
- line. No sweat. */
-
- loc = strlen(single_address)-1; /* last char */
-
- for (i = loc; single_address[i] != '!' && single_address[i] != '.'
- && i > -1; i--)
- name[index++] = tolower(single_address[i]);
- name[index] = '\0';
- reverse(name);
- }
- }
- END-OF-FILE
-
- size=`wc -c < src/reply.c`
-
- if [ $size != 9927 ]
- then
- echo Warning: src/reply.c changed - should be 9927 bytes, not $size bytes
- fi
-
- chmod 644 src/reply.c
-
- # ---------- file src/return_addr.c ----------
-
-
- if [ -f src/return_addr.c ]
- then
- echo File 'src/return_addr.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/return_addr.c...
- cat << 'END-OF-FILE' > src/return_addr.c
- /** return_addr.c **/
-
- /** This set of routines is used to generate real return addresses
- and also return addresses suitable for inclusion in a users
- alias files (ie optimized based on the pathalias database).
-
- These routines (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
-
- char *shift_lower(), *notes_machine(), *expand_address();
-
- optimize_return(address)
- char *address;
- {
- /** This routine tries to create an optimized address, that is,
- an address that has the minimal information needed to
- route a message to this person given the current path
- database...
- **/
-
- /** first step is to figure out what sort of address we
- have... **/
-
- dprint1("\noptimize_return(address='%s')\n", address);
-
- if (chloc(address, '%') != -1)
- optimize_cmplx_arpa(address);
- else if (chloc(address, '@') != -1)
- optimize_arpa(address);
- else
- optimize_usenet(address);
- }
-
- optimize_cmplx_arpa(address)
- char *address;
- {
- /** Try to optimize a complex ARPA address. A Complex address is one
- that contains '%' (deferred '@'). For example:
- veeger!hpcnof!hplabs!joe%sytech@syte
- is a complex address (no kidding, right?). The algorithm for
- trying to resolve it is to move all the way to the right, then
- back up left until the first '!' then from there to the SECOND
- metacharacter on the right is the name@host address...(in this
- example, it would be "joe%sytech"). Check this in the routing
- table. If not present, keep backing out to the right until we
- find a host that is present, or we hit the '@' sign. Once we
- have a 'normal' ARPA address, hand it to optimize_arpa().
- **/
-
- char name[SHORT_SLEN], buffer[SLEN], junk[SLEN];
- char host[SHORT_SLEN], old_host[SHORT_SLEN];
- register int i, loc, nloc = 0, hloc = 0, passes = 1;
-
- dprint1("optimize_cmplx_arpa(address='%s')\n", address);
-
- /** first off, get the name%host... **/
-
- for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--)
- ;
-
- while (address[loc] != '\0') {
-
- if (passes == 1) {
- loc++;
-
- while (address[loc] != '%' && address[loc] != '@')
- name[nloc++] = address[loc++];
- }
- else {
- for (i=0; old_host[i] != '\0'; i++)
- name[nloc++] = old_host[i];
- }
-
- loc++;
-
- while (address[loc] != '%' && address[loc] != '@')
- host[hloc++] = address[loc++];
-
- host[hloc] = name[nloc] = '\0';
-
- dprint2("\tgot name = %s and host = %s\n", name, host);
-
- strcpy(old_host, host);
- remove_domains(host);
-
- sprintf(buffer, "%s@%s", name, shift_lower(host));
-
- if (expand_site(buffer, junk) == 0) {
- strcpy(address, buffer);
- return;
- }
- else if (address[loc] == '@') {
- optimize_arpa(address);
- return;
- }
- else
- name[nloc++] = '%'; /* for next pass through */
-
- }
- }
-
- optimize_arpa(address)
- char *address;
- {
- /** Get an arpa address and simplify it to the minimal
- route needed to get mail to this person... **/
-
- char name[SHORT_SLEN], buffer[SLEN], junk[SLEN];
- char host[SHORT_SLEN];
- register int loc, nloc = 0, hloc = 0, at_sign = 0;
-
- dprint1("optimize_arpa(address='%s')\n", address);
-
- for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--) {
- if (address[loc] == '@')
- at_sign++; /* remember this spot! */
- else if (at_sign)
- name[nloc++] = address[loc];
- else
- host[hloc++] = address[loc];
- }
-
- name[nloc] = host[hloc] = '\0';
-
- reverse(name);
- reverse(host);
-
- remove_domains(host);
-
- dprint2("\tname = %s and host = %s\n", name, shift_lower(host));
-
- sprintf(buffer,"%s@%s", name, shift_lower(host));
-
- if (expand_site(buffer, junk) == 0) {
- strcpy(address, buffer);
- return;
- }
-
- optimize_usenet(address); /* that didn't work... */
- }
-
- optimize_usenet(address)
- char *address;
- {
- /** optimize the return address IFF it's a standard usenet
- address...
- **/
-
- char name[SHORT_SLEN], new_address[SLEN], buffer[SLEN], junk[SLEN];
- register int loc, nloc = 0, aloc = 0, passes = 1;
-
- dprint1("\noptimize_usenet(address='%s')\n", address);
-
- for (loc = strlen(address)-1; address[loc] != '!' && loc > -1; loc--)
- name[nloc++] = address[loc];
- name[nloc] = '\0';
-
- reverse(name);
-
- dprint1("\tgot name = %s\n", name);
-
- new_address[0] = '\0';
-
- /* got name, now get machine until we can get outta here */
-
- while (loc > -1) {
-
- new_address[aloc++] = address[loc--]; /* the '!' char */
-
- while (address[loc] != '!' && loc > -1)
- new_address[aloc++] = address[loc--];
-
- new_address[aloc] = '\0';
-
- strcpy(buffer, new_address);
- reverse(buffer);
-
- if (expand_site(buffer, junk) == 0) {
- if (passes == 1 && chloc(name, '@') == -1) {
- buffer[strlen(buffer) - 1] = '\0'; /* remove '!' */
- dprint2("\tReturning address %s@%s\n", name, buffer);
- sprintf(address, "%s@%s", name, buffer);
- }
- else {
- dprint2("\tReturning address '%s%s'\n", buffer, name);
- sprintf(address, "%s%s", buffer, name);
- }
- return; /* success! */
- }
- else
- dprint1("\taddress %s failed!\n", buffer);
-
- passes++;
- }
-
- dprint0("\tnothing to do!\n");
- return; /* nothing to do! */
- }
-
- get_return(buffer)
- char *buffer;
- {
- /** reads 'current' message again, building up the full return
- address including all machines that might have forwarded
- the message. **/
-
- char buf[LONG_SLEN], name1[SLEN], name2[SLEN], lastname[SLEN];
- char hold_return[LONG_SLEN], alt_name2[SLEN];
- int ok = 1, lines;
-
- dprint0("get_return(<buffer>)\n");
-
- /** are we reading a notesfile file?? **/
-
- if (notesfile) {
- strcpy(buf, header_table[current-1].from);
- if (chloc(buf, '!') == -1)
- sprintf(buf, "%s!%s", notes_machine(), header_table[current-1].from);
- strcpy(buffer, expand_system(buf, 1));
- dprint1("\treturn address [notes] = %s\n", buffer);
- return;
- }
-
- /** get to the first line of the message desired **/
-
- if (fseek(mailfile, header_table[current-1].offset, 0) == -1) {
- error1("msg [seek] couldn't read %d bytes into file",
- header_table[current-1].offset);
- return;
- }
-
- /** okay! Now we're there! **/
-
- lines = header_table[current-1].lines;
-
- buffer[0] = '\0';
-
- while (ok && lines--) {
- ok = (int) (fgets(buf, LONG_SLEN, mailfile) != NULL);
- if (first_word(buf, "From ")) {
- sscanf(buf, "%*s %s", hold_return);
- }
- else if (first_word(buf, ">From")) {
- sscanf(buf,"%*s %s %*s %*s %*s %*s %*s %*s %*s %s %s",
- name1, name2, alt_name2);
- if (strcmp(name2, "from") == 0)
- strcpy(name2, alt_name2);
- add_site(buffer, name2, lastname);
- }
-
- #ifdef USE_EMBEDDED_ADDRESSES
-
- else if (first_word(buf, "From:")) {
- get_address_from("From:", buf, hold_return);
- }
- else if (first_word(buf, "Reply-To:")) {
- get_address_from("Reply-To:", buf, buffer);
- return;
- }
-
- #endif
-
- else if (strlen(buf) < 2) /* done with header */
- lines = 0; /* let's get outta here! We're done!!! */
- }
-
- if (buffer[0] == '\0')
- strcpy(buffer, hold_return); /* default address! */
- else
- add_site(buffer, name1, lastname); /* get the user name too! */
-
- dprint1("\treturn address = '%s'\n", buffer);
-
- }
- END-OF-FILE
-
- size=`wc -c < src/return_addr.c`
-
- if [ $size != 7247 ]
- then
- echo Warning: src/return_addr.c changed - should be 7247 bytes, not $size bytes
- fi
-
- chmod 644 src/return_addr.c
-
- # ---------- file src/savecopy.c ----------
-
-
- if [ -f src/savecopy.c ]
- then
- echo File 'src/savecopy.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/savecopy.c...
- cat << 'END-OF-FILE' > src/savecopy.c
- /** savecopy.c **/
-
- /** Save a copy of the specified message in the users savemail mailbox.
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- #include "headers.h"
- #ifdef BSD
- # include <sys/time.h>
- #else
- # include <time.h>
- #endif
-
- char *format_long(), *get_arpa_date();
-
- extern char reply_to[SLEN]; /* In-Reply-To: string */
- extern int gotten_key; /* for encryption */
-
- save_copy(subject, to, cc, filename, original_to)
- char *subject, *to, *cc, *filename, *original_to;
- {
- /** This routine appends a copy of the outgoing message to the
- file specified by the SAVEFILE environment variable. **/
-
- FILE *save, /* file id for file to save to */
- *message; /* the actual message body */
- long thetime; /* variable holder for time */
- char buffer[SLEN], /* read buffer */
- savename[SLEN], /* name of file saving into */
- newbuffer[SLEN]; /* first name in 'to' line */
- register int i; /* for chopping 'to' line up */
- int crypted=0; /* are we encrypting? */
-
- dprint5(
- "save_copy(subject='%s', to='%s', cc='%s', filename='%s', original-to='%s')\n",
- subject, to, cc, filename, original_to);
-
- savename[0] = '\0';
-
- if (save_by_name) {
- get_return_name(to, buffer);
- sprintf(savename, "%s%s%s", folders,
- lastch(folders) == '/'? "" : "/", buffer);
- if (access(savename, ACCESS_EXISTS) == -1) /* don't create new! */
- savename[0] = '\0';
- }
-
- if (strlen(savename) == 0) {
- if (strlen(savefile) == 0)
- return(error("variable 'SAVEFILE' not defined!"));
- strcpy(savename, savefile);
- if (save_by_name)
- error2("Not creating file '%s'...saving in %s instead",
- buffer, savename);
- }
-
- dprint1("\tsaving copy of outbound message to file '%s'\n", savename);
-
- if ((save = fopen(savename, "a")) == NULL)
- return(error1("couldn't append to %s", savename));
-
- if ((message = fopen(filename, "r")) == NULL) {
- fclose(save);
- return(error1("save_copy couldn't read file %s!", filename));
- }
-
- for (i=0; original_to[i] != '\0' && ! whitespace(original_to[i]); i++)
- newbuffer[i] = original_to[i];
-
- newbuffer[i] = '\0';
-
- tail_of(newbuffer, buffer, FALSE);
-
- thetime = time(0); /* this must be here for it to work! */
-
- fprintf(save,"\nFrom To:%s %s", buffer, (char *) ctime(&thetime));
-
- fprintf(save, "Date: %s\n", get_arpa_date());
-
- fprintf(save,"To: %s\nSubject: %s\n",
- format_long(to,strlen("To: ")), subject);
-
- if (strlen(cc) > 0)
- fprintf(save,"Cc: %s\n",
- format_long(cc, strlen("Cc:")));
-
- if (strlen(reply_to) > 0)
- fprintf(save, "In-Reply-To: %s\n", reply_to);
-
- (void) putc('\n', save); /* put another return, please! */
-
- /** now copy over the message... **/
-
- while (fgets(buffer, SLEN, message) != NULL) {
- if (buffer[0] == '[') {
- if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
- crypted = 1;
- else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
- crypted = 0;
- else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0) {
- fclose(message);
- fclose(save);
- chown(savename, userid, getgid());
- return(TRUE);
- }
- }
- else if (crypted) {
- if (! gotten_key++)
- getkey(ON);
- encode(buffer);
- }
- fputs(buffer, save);
- }
-
- dprint0("\tclosing the files...\n");
-
- fclose(message);
- fclose(save);
-
- /* make sure save file isn't owned by root! */
- chown(savename, userid, getgid());
-
- return(TRUE);
- }
- END-OF-FILE
-
- size=`wc -c < src/savecopy.c`
-
- if [ $size != 3441 ]
- then
- echo Warning: src/savecopy.c changed - should be 3441 bytes, not $size bytes
- fi
-
- chmod 644 src/savecopy.c
-
- # ---------- file src/screen.c ----------
-
-
- if [ -f src/screen.c ]
- then
- echo File 'src/screen.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/screen.c...
- cat << 'END-OF-FILE' > src/screen.c
- /** screen.c **/
-
- /** screen display routines for MSG program
-
- (C) Copyright 1985, Dave Taylor
- **/
-
- #include "headers.h"
-
- static int last_current = -1;
-
- showscreen()
- {
- char buffer[SLEN];
-
- dprint0("showscreen()\n");
-
- ClearScreen();
-
- if (notesfile)
- sprintf(buffer, "Notes from '%s' (%d note%s) [Version %s]",
- infile, message_count,
- plural(message_count), VERSION);
- else
- sprintf(buffer, "Mailbox is '%s' with %d message%s [Version %s]",
- infile, message_count,
- plural(message_count), VERSION);
- Centerline(1, buffer);
-
- last_header_page = -1; /* force a redraw regardless */
- show_headers();
-
- if (mini_menu)
- show_menu();
-
- show_last_error();
-
- if (hp_terminal)
- define_softkeys(MAIN);
- }
-
- show_menu()
- {
- /** write main system menu... **/
-
- Centerline(LINES-7,
- "|=pipe, !=shell, ?=help, <n>=set current to n, /=search pattern");
- Centerline(LINES-6,
- "A)lias, C)hange mailbox, D)elete, F)orward, G)roup reply, M)ail,");
- Centerline(LINES-5,
- "N)ext, P)rint, R)eply, S)ave to file, Q)uit, U)ndelete, or eX)it");
- }
-
- int
- show_headers()
- {
- /** display page of headers (10) if present. First check to
- ensure that header_page is in bounds, fixing silently if not.
- If out of bounds, return zero, else return non-zero **/
-
- register int first = 0, line = 4, last = 0, last_line;
- char newfrom[SLEN], buffer[SLEN];
-
- dprint0("show_headers()\n");
-
- if (fix_header_page())
- return(FALSE);
-
- if (header_page == last_header_page) /* nothing to do! */
- return(FALSE);
-
- /** compute last header to display **/
-
- first= header_page * headers_per_page;
-
- last = first + (headers_per_page - 1);
-
- if (last >= message_count) last = message_count-1;
-
- dprint2("\tdisplaying headers %d thru %d\n", first, last);
-
- /** okay, now let's show the header page! **/
-
- while (first <= last) {
- tail_of(header_table[first].from, newfrom, TRUE);
- build_header_line(buffer, &header_table[first], first+1, newfrom);
- PutLine(line,COLUMNS-80,"%s", buffer); /* avoid '%' probs */
- CleartoEOLN();
- first++;
- line++; /* for clearing up in a sec... */
- }
-
- /* clear up the rest of the screen! */
-
- if (mini_menu)
- last_line = LINES-8;
- else
- last_line = LINES-3;
-
- while (line < last_line) {
- MoveCursor(line,0);
- CleartoEOLN();
- line++;
- }
-
- display_central_message();
-
- last_current = current;
- last_header_page = header_page;
-
- return(TRUE);
- }
-
- show_current()
- {
- /** display page of headers (10) if present. First check to
- ensure that header_page is in bounds, fixing silently if not.
- Note that this will ensure that 'current' is always set to
- the top message on the screen if we go to a new screen! **/
-
- register int first = 0, last = 0, line = 4, changed;
-
- dprint0("show_current()\n");
-
- changed = fix_header_page();
-
- /** compute last header to display **/
-
- first = header_page * headers_per_page;
- last = first + (headers_per_page - 1);
-
- if (last > message_count)
- last = message_count;
-
- /** okay, now let's show the pointers... **/
-
- /** have we changed??? **/
-
- if (current == last_current) {
- dprint0("\tno change. at same message!\n");
- return;
- }
-
- /** first condition - current on this page & last too */
-
- if (last_current >= first && last_current <= last+1) {
- dprint2("\tMoving arrow from %d to (current) %d\n",
- last_current, current);
- PutLine(((last_current-1) % headers_per_page) + 4, COLUMNS-76," ");
- PutLine(((current-1) % headers_per_page) + 4, COLUMNS-76,"<-");
- }
-
- /** second condition - current on this page **/
- else if (! changed) {
- dprint1("\tMoving arrow to (current) %d\n", current);
- PutLine(((current-1) % headers_per_page) + 4, COLUMNS-76,"<-");
- }
-
- /** third condition - page changed! **/
- else {
- dprint2("\tdisplaying from message %d to %d\n", first, last);
-
- while (first <= last) {
- if (current-1 == first) PutLine(line++,COLUMNS-76,"<-");
- else PutLine(line++,COLUMNS-76," ");
- first++;
- }
- }
- last_current = current;
- }
-
- build_header_line(buffer, entry, number, from)
- char *buffer;
- struct header_rec *entry;
- int number;
- char *from;
- {
- /** Build in buffer the message header ... entry is the current
- message entry, number is the numerical ID of the message,
- and 'from' is a modified (displayable) from line... **/
-
- /** Note: using 'strncpy' allows us to output as much of the
- subject line as possible given the dimensions of the screen.
- The key is that 'strncpy' returns a 'char *' to the string
- that it is handing to the dummy variable! Neat, eh? **/
-
- char subj[LONG_SLEN]; /* to output subject */
-
- strncpy(subj, entry->subject, COLUMNS-34);
-
- subj[COLUMNS-34] = '\0'; /* insurance, eh? */
-
- sprintf(buffer, "%c%3d%s %c %3.3s %-2d %-18.18s %s",
- (entry->priority? 'U' : new_msg(entry)? 'N' : ' '),
- number, (number == current? "<-" : " "),
- (entry->delete? '*' : ' '),
- entry->month, atoi(entry->day), from, subj);
- }
-
- int
- fix_header_page()
- {
- /** this routine will check and ensure that the current header
- page being displayed contains messages! It will silently
- fix 'header-page' if wrong. Returns TRUE if changed. **/
-
- int last_page, old_header;
-
- dprint1("fix_header_page() [%d messages total]\n", message_count);
-
- old_header = header_page;
-
- last_page = (int) ((message_count-1) / headers_per_page);
-
- dprint2("\tThere are 0 to %d pages in file [%d per page]\n",
- last_page, headers_per_page);
-
- if (header_page > last_page)
- header_page = last_page;
- else if (header_page < 0)
- header_page = 0;
-
- return(old_header != header_page);
- }
- END-OF-FILE
-
- size=`wc -c < src/screen.c`
-
- if [ $size != 5636 ]
- then
- echo Warning: src/screen.c changed - should be 5636 bytes, not $size bytes
- fi
-
- chmod 644 src/screen.c
-
- # ---------- file src/showmsg.c ----------
-
-
- if [ -f src/showmsg.c ]
- then
- echo File 'src/showmsg.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/showmsg.c...
- cat << 'END-OF-FILE' > src/showmsg.c
- /** showmsg.c **/
-
- /** This file contains all the routines needed to display the specified
- message.
-
- These routines (C) Copyright 1986 Dave Taylor
- **/
-
-
- #include "headers.h"
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- int
- show_msg(number)
- int number;
- {
- /*** display number'th message. Get starting and ending lines
- of message from headers data structure, then fly through
- the file, displaying only those lines that are between the
- two!
- Returns non-zero if message shown!
- ***/
-
- dprint1("show_msg(number=%d)\n", number);
-
- if (number > message_count) {
- error1("Only %d messages!", message_count);
- return(0);
- }
- else if (number < 1) {
- error("you can't read THAT message!");
- return(0);
- }
-
- return(show_message(header_table[number-1].lines,
- header_table[number-1].offset,number));
- }
-
- int
- show_message(lines, file_loc, msgnumber)
- int lines, msgnumber;
- long file_loc;
- {
- /*** Show the indicated range of lines from mailfile
- for message 'msgnumber' by using 'display'
- Returns non-zero if it actually put something on
- the screen.
- ***/
-
- dprint3("show_message(lines=%d, loc=%ld, msg-number=%d)\n",
- lines, file_loc, msgnumber);
-
- if (fseek(mailfile, file_loc, 0) != 0) {
- error1("msg [seek] failed looking %d bytes into file",
- file_loc);
- return(FALSE);
- }
-
- /* next read will get 'this' line so must be at end of previous */
-
- Raw(OFF);
- display(lines, msgnumber);
- Raw(ON);
-
- return(TRUE); /* we did it boss! */
- }
-
-
- /** these two variables are used iff the variable 'title_message' is
- set, and are buffers for output of message title... **/
-
- static char top_of_screen_left [LONG_STRING],
- top_of_screen_right[LONG_STRING];
-
- display(lines, msgnum)
- int lines, msgnum;
- {
- /** Display specified number of lines from file mailfile.
- Note: This routine MUST be placed at the first line
- of the input file! **/
-
- char buffer[LONG_STRING], *full_month();
-
- int lines_on_screen = 0; /* display */
- int crypted = 0, gotten_key = 0; /* encryption */
- int weed_header, weeding_out = 0; /* weeding */
-
- dprint2("display(lines=%d, msgnum=%d)\n", lines, msgnum);
-
- if (title_messages) {
- tail_of(header_table[msgnum-1].from, buffer, FALSE);
- sprintf(top_of_screen_left, "%s #%d %s %s",
- notesfile? "Note" : "Message", msgnum,
- (strncmp(header_table[msgnum-1].from, "To:", 3) == 0?
- "to": "from"), buffer);
- sprintf(top_of_screen_right," %s %s %s, %d at %s",
- notesfile? "Posted" : "Mailed",
- full_month(header_table[msgnum-1].month),
- header_table[msgnum-1].day,
- atoi(header_table[msgnum-1].year) + 1900,
- header_table[msgnum-1].time);
-
- dprint1("\ttos_left: '%s'\n", top_of_screen_left);
- dprint1("\ttos_right: '%s'\n", top_of_screen_right);
- }
-
- weed_header = filter; /* allow us to change it after header */
-
- ClearScreen();
-
- if (cursor_control) transmit_functions(OFF);
-
- while (lines > 0) {
-
- if (fgets(buffer, LONG_STRING, mailfile) == NULL) {
- PutLine(LINES-1, 0, "Please press <space> to return: ");
- (void) ReadCh();
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
-
- if (strlen(buffer) > 0)
- no_ret(buffer);
-
- if (strlen(buffer) == 0) {
- weed_header = 0; /* past header! */
- weeding_out = 0;
- }
-
- lines--;
-
- if (notesfile) { /* treat notes differently! */
-
- if (filter && (first_word(buffer, NOTES_HEADER) ||
- first_word(buffer, NOTES_FOOTER)) )
- /*** weed this line out of the display! ***/;
- else if (show_line(buffer, &lines_on_screen, &lines)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
-
- else { /* "normal" message */
-
- if (weed_header && matches_weedlist(buffer))
- weeding_out = 1; /* aha! We don't want to see this! */
- else if (buffer[0] == '[') {
- if (strcmp(buffer, START_ENCODE)==0)
- crypted++;
- else if (strcmp(buffer, END_ENCODE)==0)
- crypted--;
- else if (crypted) {
- encode(buffer);
- if (show_line(buffer, &lines_on_screen, &lines)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else
- if (show_line(buffer, &lines_on_screen, &lines)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else if (crypted) {
- if (! gotten_key++) getkey(OFF);
- encode(buffer);
- if (show_line(buffer, &lines_on_screen, &lines)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else if (weeding_out) {
- weeding_out = (whitespace(buffer[0])); /* 'n' line weed */
- if (! weeding_out) /* just turned on! */
- if (show_line(buffer, &lines_on_screen, &lines)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- else
- if (show_line(buffer, &lines_on_screen, &lines)) {
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
- }
- }
-
-
- PutLine(LINES-1, 0, "Please press <space> to return: ");
- Raw(ON);
- (void) ReadCh();
- if (cursor_control) transmit_functions(ON);
- return(TRUE);
- }
-
- int
- show_line(buffer, lines_on_screen, total)
- char *buffer;
- int *lines_on_screen, *total;
- {
- /** Displays the given line if it can. if not, it will put the
- 'ole 'space to continue' prompt on the bottom of the screen
- and wait for either a 'space' or 'return'. If 'return' is
- hit (or 'q'), then it will return non-zero, otherwise it'll
- return zero.
- **/
-
- static char overlap [LONG_SLEN];
- char mybuffer[SLEN], ch;
- int last_line_loc;
-
- dprint3("show_line(buffer=%s, on-screen=%d, total=%d)\n",
- buffer, *lines_on_screen, *total);
-
- last_line_loc = *lines_on_screen; /* one back... */
-
- *lines_on_screen += ((strlen(buffer) / COLUMNS) + 1);
-
- if (last_line_loc == 0 && title_messages) {
- display_title(*total);
- last_line_loc = 2;
- *lines_on_screen += 2;
- }
-
-
- if (*lines_on_screen > LINES-2) {
- if (*total > 0) {
- sprintf(mybuffer, "%d line%s left", *total, plural(*total));
- PutLine(LINES-1, COLUMNS-20, "%s", mybuffer);
- PutLine(LINES-1, 0, "Press <space> to continue: ");
- }
- else
- PutLine(LINES-1, 0, "Please press <space> to return: ");
- Raw(ON);
- ch = ReadCh();
- if (ch == '\n' || ch == '\r' || tolower(ch) == 'q')
- return(TRUE);
- if (ch == ' ' && *total == 0) /* don't want '0' lines left */
- return(TRUE);
- Raw(OFF);
- ClearScreen();
- *lines_on_screen = 0;
-
- if (title_messages) {
- display_title(*total);
- *lines_on_screen = 2;
- }
-
- PutLine(*lines_on_screen, 0, "%s", overlap);
- *lines_on_screen += ((strlen(overlap) / COLUMNS) + 1);
- last_line_loc = *lines_on_screen;
- *lines_on_screen += ((strlen(buffer) / COLUMNS) + 1);
- }
-
- PutLine(last_line_loc, 0, "%s", buffer);
-
- if (*lines_on_screen > LINES-6) /* in case next is too LONG */
- strcpy(overlap, buffer);
-
- return(FALSE);
- }
-
- display_title(lines_into_message)
- int lines_into_message;
- {
- /** Display top title, including "Page N" **/
-
- register int page;
-
- dprint1("displaytitle(lines-into-message=%d)\n", lines_into_message);
-
- page = (int) (lines_into_message) / (LINES - 4);
-
- PutLine(0,0,top_of_screen_left);
-
- PutLine(0, COLUMNS-strlen(top_of_screen_right),
- top_of_screen_right, page);
- }
- END-OF-FILE
-
- size=`wc -c < src/showmsg.c`
-
- if [ $size != 7604 ]
- then
- echo Warning: src/showmsg.c changed - should be 7604 bytes, not $size bytes
- fi
-
- chmod 644 src/showmsg.c
-
- # ---------- file src/softkeys.c ----------
-
-
- if [ -f src/softkeys.c ]
- then
- echo File 'src/softkeys.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/softkeys.c...
- cat << 'END-OF-FILE' > src/softkeys.c
- /** softkeys.c **/
-
- /** This file and associated routines: (C) Copyright 1986, Dave Taylor **/
-
- #include <stdio.h>
- #include "headers.h"
-
- define_softkeys(level)
- int level;
- {
- dprint0("define_softkeys(level=");
-
- if (! hp_softkeys) {
- dprint0("0) [error: no softkeys!]\n");
- return;
- }
-
- if (level == MAIN) {
- dprint0("MAIN)\n");
- if (notesfile) {
- define_key(f1, " Show Note", "\r");
- define_key(f2, " Reply to Note", "r");
- define_key(f3, " Change Mailbox", "c");
- define_key(f4, " Save Note", "s");
- define_key(f5, " Delete/Undelete", "^");
- define_key(f6, " Print Note", "p");
- define_key(f7, " HELP", "?");
- define_key(f8, " Quit Msg", "q");
- }
- else {
- define_key(f1, " Show Msg", "\r");
- define_key(f2, " Mail Msg", "m");
- define_key(f3, " Reply to Msg", "r");
- define_key(f4, " Change Mailbox", "c");
- define_key(f5, " Save Msg", "s");
- define_key(f6, " Delete/Undelete", "^");
- define_key(f7, " Print Msg", "p");
- define_key(f8, " Quit Msg", "q");
- }
- }
- else if (level == ALIAS) {
- dprint0("ALIAS)\n");
- define_key(f1, " Alias Current", "a");
- define_key(f2, " Check Alias", "c");
- define_key(f3, " Make Alias", "m");
- clear_key(f4);
- clear_key(f5);
- clear_key(f6);
- clear_key(f7);
- define_key(f8, " Return to Msg", "r");
- }
- else if (level == YESNO) {
- dprint0("YES-NO)\n");
- define_key(f1, " Yes", "y");
- clear_key(f2);
- clear_key(f3);
- clear_key(f4);
- clear_key(f5);
- clear_key(f6);
- clear_key(f7);
- define_key(f8, " No", "n");
- }
- else if (level == READ) {
- dprint0("READ)\n");
- define_key(f1, " Next Page ", " ");
- clear_key(f2);
- clear_key(f3);
- clear_key(f4);
- clear_key(f5);
- clear_key(f6);
- clear_key(f7);
- define_key(f8, " Return to Msg", "\n");
- }
- else if (level == CHANGE) {
- dprint0("CHANGE)\n");
- define_key(f1, " Mail Directry", "=/");
- define_key(f2, " Home Directry", "~/");
- clear_key(f3);
- define_key(f4, "Incoming Mailbox", "!\n");
- clear_key(f5);
- clear_key(f6);
- clear_key(f7);
- define_key(f8, " Cancel", "\n");
- }
-
- softkeys_on();
- }
-
- define_key(key, display, send)
- int key;
- char *display, *send;
- {
-
- char buffer[30];
-
- dprint3("define-key(key=%d, display='%s', send='%s'\n",
- key, display, send);
-
- sprintf(buffer,"%s%s", display, send);
-
- printf("%c&f%dk%dd%dL%s", ESCAPE, key,
- strlen(display), strlen(send), buffer);
- }
-
- softkeys_on()
- {
- /* turn on softkeys (esc&jB) and turn on MENU and USER/SYSTEM */
-
- if (hp_softkeys)
- printf("%c&jB%c&jR", ESCAPE, ESCAPE);
- }
-
- softkeys_off()
- {
- /* turn off softkeys (esc&j@) */
-
- if (hp_softkeys)
- printf("%c&j@", ESCAPE);
- }
-
- clear_key(key)
- {
- /** set a key to nothing... **/
-
- if (hp_softkeys)
- define_key(key, " ", "");
- }
- END-OF-FILE
-
- size=`wc -c < src/softkeys.c`
-
- if [ $size != 2900 ]
- then
- echo Warning: src/softkeys.c changed - should be 2900 bytes, not $size bytes
- fi
-
- chmod 644 src/softkeys.c
-
- echo done
-
- exit 0
-
-
-
-
-