home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i034: Elm mail system (elm), Part09/14
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
- Mod.sources: Volume 6, Issue 34
- Archive-name: elm/Part09
-
- # Continuation of Shell Archive, created by hpldat!taylor
-
- # This is part 9
-
- # 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
-
-
- if [ ! -d src ]
- then
- echo creating directory src
- mkdir src
- fi
-
- # ---------- file src/output_utils.c ----------
-
- filename="src/output_utils.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/output_utils.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** output_utils.c **/
-
- /** This file contains routines used for output in the ELM 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();
- PutLine0(LINES,(COLUMNS-strlen(s))/2,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);
- }
-
- error3(s, a1, a2, a3)
- char *s, *a1, *a2, *a3;
- {
- /** same as error, but with three 'printf' arguments **/
- char buffer[SLEN];
-
- sprintf(buffer,s, a1, a2, a3);
- error(buffer);
- }
-
- prompt(s)
- char *s;
- {
- /** prompt user for input on LINES-3 line, left justified **/
-
- PutLine0(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
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 1987 ]
- then
- echo $filename changed - should be 1987 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/mailtime.c ----------
-
- filename="src/mailtime.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/mailtime.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** mailtime.c **/
-
- /** This set of routines is used to figure out when the user last read
- their mail and to also figure out if a given message is new or not.
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #ifdef BSD
- # include <sys/time.h>
- #else
- # include <time.h>
- #endif
-
- resolve_received(entry)
- struct header_rec *entry;
- {
- /** Entry has the data for computing the time and date the
- message was received. Fix it and return **/
-
- switch (tolower(entry->month[0])) {
- case 'j' : if (tolower(entry->month[1]) == 'a')
- entry->received.month = JANUARY;
- else if (tolower(entry->month[2]) == 'n')
- entry->received.month = JUNE;
- else
- entry->received.month = JULY;
- break;
- case 'f' : entry->received.month = FEBRUARY;
- break;
- case 'm' : if (tolower(entry->month[2]) == 'r')
- entry->received.month = MARCH;
- else
- entry->received.month = MAY;
- break;
- case 'a' : if (tolower(entry->month[1]) == 'p')
- entry->received.month = APRIL;
- else
- entry->received.month = AUGUST;
- break;
- case 's' : entry->received.month = SEPTEMBER;
- break;
- case 'o' : entry->received.month = OCTOBER;
- break;
- case 'n' : entry->received.month = NOVEMBER;
- break;
- case 'd' : entry->received.month = DECEMBER;
- break;
- }
-
- sscanf(entry->day, "%d", &(entry->received.day));
-
- sscanf(entry->year, "%d", &(entry->received.year));
- if (entry->received.year > 100) entry->received.year -= 1900;
-
- sscanf(entry->time, "%d:%d", &(entry->received.hour),
- &(entry->received.minute));
- }
-
- get_mailtime()
- {
- /** Instantiate the values of the last_read_mail stat
- variable based on the file access time/date of the
- file mailtime_file. IF the file doesn't exist,
- then assume all mail is new. **/
-
- struct stat buffer;
- struct tm *timebuf;
- char filename[SLEN];
-
- sprintf(filename, "%s/%s", home, mailtime_file);
-
- if (stat(filename, &buffer) == -1) {
- last_read_mail.month = 0;
- last_read_mail.day = 0;
- last_read_mail.year = 0;
- last_read_mail.hour = 0;
- last_read_mail.minute = 0;
- }
- else { /* stat okay... */
- timebuf = (struct tm *) localtime(&(buffer.st_mtime));
-
- last_read_mail.month = timebuf->tm_mon;
- last_read_mail.day = timebuf->tm_mday;
- last_read_mail.year = timebuf->tm_year;
- last_read_mail.hour = timebuf->tm_hour;
- last_read_mail.minute = timebuf->tm_min;
- }
- }
-
- update_mailtime()
- {
- /** This routine updates the last modified time of the
- .last_read_mail file in the users home directory.
- If the file doesn't exist, it creates it!! **/
-
- char filename[SLEN];
-
- #ifdef BSD
- struct timeval tval[2];
- struct timezone tzone;
- #endif
-
- sprintf(filename, "%s/%s", home, mailtime_file);
-
- #ifdef BSD
- gettimeofday(&tval[0], &tzone);
- gettimeofday(&tval[1], &tzone);
-
- if (utime(filename, &tval) == -1)
- #else
- if (utime(filename, NULL) == -1)
- #endif
- (void) creat(filename, 0777);
- }
-
- new_msg(entry)
- struct header_rec entry;
- {
- /** Return true if the current message is NEW. This can be
- easily tested by seeing 1) if we're reading the incoming
- mailbox and then, if so, 2) if the received_on_machine
- date is more recent than the last_read_mail date.
- **/
-
- if (mbox_specified != 0) return(FALSE); /* not incoming */
-
- /** Two tests - if received is OLDER than last read mail, then
- immediately return FALSE. If received is NEWER than last
- read mail then immediately return TRUE **/
-
- if (entry.received.year < last_read_mail.year)
- return(FALSE);
-
- if (entry.received.year > last_read_mail.year)
- return(TRUE);
-
- if (entry.received.month < last_read_mail.month)
- return(FALSE);
-
- if (entry.received.month > last_read_mail.month)
- return(TRUE);
-
- if (entry.received.day < last_read_mail.day)
- return(FALSE);
-
- if (entry.received.day > last_read_mail.day)
- return(TRUE);
-
- if (entry.received.hour < last_read_mail.hour)
- return(FALSE);
-
- if (entry.received.hour > last_read_mail.hour)
- return(TRUE);
-
- if (entry.received.minute < last_read_mail.minute)
- return(FALSE);
-
- return(TRUE);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4271 ]
- then
- echo $filename changed - should be 4271 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/encode.c ----------
-
- filename="src/encode.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/encode.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** encode.c **/
-
- /** This is a heavily mangled version of the 'cypher' program written by
- person or persons unknown.
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- #include <stdio.h>
- #include "curses.h"
- #include "headers.h"
-
- #define RS 94
- #define RN 4
- #define RMASK 0x7fff /* use only 15 bits */
-
- static char r[RS][RN]; /* rotors */
- static char ir[RS][RN]; /* inverse rotors */
- static char h[RS]; /* half rotor */
- static char s[RS]; /* shuffle vector */
- static int p[RN]; /* rotor indices */
-
- static char the_key[SLEN]; /* unencrypted key */
- static char *encrypted_key; /* encrypted key */
-
- getkey(send)
- int send;
- {
- /** this routine prompts for and returns an encode/decode
- key for use in the rest of the program. If send == 1
- then need to mess with rawmode. **/
-
- char buffer[NLEN];
- int gotkey = 0;
-
- ClearLine(21);
-
- if (send) Raw(OFF);
-
- while ( !gotkey ) {
- MoveCursor(LINES-1,0);
- ClearLine(LINES-1);
- if (send)
- strcpy( buffer, getpass( "Enter encryption key: "));
- else
- strcpy( buffer, getpass( "Enter decryption key: "));
- MoveCursor(LINES-1,0);
- if ( strcmp( buffer, getpass( "Please enter it again: "))) {
- error("Your keys were not the same!");
- sleep(1);
- clear_error();
- continue;
- }
- strcpy(the_key, buffer); /* save unencrypted key */
- makekey( buffer );
- gotkey = 1;
- }
-
- if (send) Raw(ON);
-
- setup(); /** initialize the rotors etc. **/
-
- ClearLine(LINES-1);
- clear_error();
- }
-
- get_key_no_prompt()
- {
- /** This performs the same action as get_key, but assumes that
- the current value of 'the_key' is acceptable. This is used
- when a message is encrypted twice... **/
-
- char buffer[SLEN];
-
- strcpy(buffer, the_key);
-
- makekey( buffer );
-
- setup();
- }
-
- encode(line)
- char *line;
- {
- /** encrypt or decrypt the specified line. Uses the previously
- entered key... **/
-
- register int i, index, j, ph = 0;
-
- for (index=0; index < strlen(line); index++) {
- i = (int) line[index];
-
- if ( (i >= ' ') && (i < '~') ) {
- i -= ' ';
-
- for ( j = 0; j < RN; j++ ) /* rotor forwards */
- i = r[(i+p[j])%RS][j];
-
- i = ((h[(i+ph)%RS])-ph+RS)%RS; /* half rotor */
-
- for ( j-- ; j >= 0; j-- ) /* rotor backwards */
- i = (ir[i][j]+RS-p[j])%RS;
-
- j = 0; /* rotate rotors */
- p[0]++;
- while ( p[j] == RS ) {
- p[j] = 0;
- j++;
- if ( j == RN ) break;
- p[j]++;
- }
-
- if ( ++ph == RS )
- ph = 0;
-
- i += ' ';
- }
-
- line[index] = (char) i; /* replace with altered one */
- }
- }
-
-
- makekey( rkey)
- char *rkey;
- {
- /** encrypt the key using the system routine 'crypt' **/
-
- char key[8], salt[2], *crypt();
-
- strncpy( key, rkey, 8);
- salt[0] = key[0];
- salt[1] = key[1];
- encrypted_key = crypt( key, salt);
- }
-
- /*
- * shuffle rotors.
- * shuffle each of the rotors indiscriminately. shuffle the half-rotor
- * using a special obvious and not very tricky algorithm which is not as
- * sophisticated as the one in crypt(1) and Oh God, I'm so depressed.
- * After all this is done build the inverses of the rotors.
- */
-
- setup()
- {
- register long i, j, k, temp;
- long seed;
-
- for ( j = 0; j < RN; j++ ) {
- p[j] = 0;
- for ( i = 0; i < RS; i++ )
- r[i][j] = i;
- }
-
- seed = 123;
- for ( i = 0; i < 13; i++) /* now personalize the seed */
- seed = (seed*encrypted_key[i] + i) & RMASK;
-
- for ( i = 0; i < RS; i++ ) /* initialize shuffle vector */
- h[i] = s[i] = i;
-
- for ( i = 0; i < RS; i++) { /* shuffle the vector */
- seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
- k = ((seed % 65521) & RMASK) % RS;
- temp = s[k];
- s[k] = s[i];
- s[i] = temp;
- }
-
- for ( i = 0; i < RS; i += 2 ) { /* scramble the half-rotor */
- temp = h[s[i]]; /* swap rotor elements ONCE */
- h[s[i]] = h[s[i+1]];
- h[s[i+1]] = temp;
- }
-
- for ( j = 0; j < RN; j++) { /* select a rotor */
-
- for ( i = 0; i < RS; i++) { /* shuffle the vector */
- seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
- k = ((seed % 65521) & RMASK) % RS;
- temp = r[i][j];
- r[i][j] = r[k][j];
- r[k][j] = temp;
- }
-
- for ( i = 0; i < RS; i++) /* create inverse rotors */
- ir[r[i][j]][j] = i;
- }
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4156 ]
- then
- echo $filename changed - should be 4156 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/leavembox.c ----------
-
- filename="src/leavembox.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/leavembox.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** leavembox.c **/
-
- /** leave current mailbox, updating etc. as needed...
-
- (C) Copyright 1985, Dave Taylor
- **/
-
- #include "headers.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
-
- #define ECHOIT 1 /* echo on for prompting! */
-
- /** added due to a bug in the 2.1 OS **/
-
- struct utimbuf {
- time_t actime; /** access time **/
- time_t modtime; /** modification */
- };
-
- extern int errno;
-
- char *error_name(), *error_description();
-
- int
- leave_mbox(quitting)
- int quitting;
- {
- /** Exit, saving files into mbox and deleting specified, or simply
- delete specified mail... If "quitting" is true, then output status
- regardless of what happens. Returns 1 iff mailfile was
- changed (ie messages deleted from file), 0 if not, and -1 if new
- mail has arrived in the meantime...
- **/
-
- FILE *temp;
- char outfile[SLEN], buffer[SLEN];
- struct stat buf; /* stat command */
- struct utimbuf times; /* utime command */
- register int to_delete = 0, to_save = 0, i, mode = 00644,
- pending = 0, number_saved = 0, last_sortby;
- char dflt;
- long bytes();
-
- dprint0(1,"\n\n-- leaving_mailbox --\n\n");
-
- if (message_count == 0)
- return(FALSE); /* nothing changed */
-
- for (i = 0; i < message_count; i++)
- if (ison(header_table[i].status, DELETED)) to_delete++;
- else to_save++;
-
- dprint2(2,"Count: %d to delete and %d to save\n", to_delete, to_save);
-
- if (mbox_specified == 0)
- update_mailtime();
-
- if (hp_softkeys) {
- define_softkeys(YESNO); /* YES or NO on softkeys */
- softkeys_on();
- }
-
- if (always_del) /* set up the default answer... */
- dflt = 'y';
- else
- dflt = 'n';
-
- if (to_delete)
- if (to_save) {
- sprintf(buffer, "Delete message%s? (y/n) ", plural(to_delete));
- if (want_to(buffer, dflt, ECHOIT) != 'y') {
- if (mbox_specified == 0) unlock(); /* remove lock! */
- dprint1(3,"\tDelete message%s? - answer was NO\n",
- plural(to_delete));
- error("Nothing deleted");
- return(FALSE); /* nothing was deleted! */
- }
- }
- else if (! to_save) { /* nothing to save!! */
- if (want_to("Delete all mail? (y/n) ", dflt, ECHOIT)!='y') {
- if (mbox_specified == 0) unlock(); /* remove lock! */
- dprint0(3,"Delete all mail? - answer was NO\n");
- error("Nothing deleted");
- return(FALSE); /* nothing was deleted */
- }
- }
-
- if (always_leave)
- dflt = 'y';
- else
- dflt = 'n';
-
- /** we have to check to see what the sorting order was...so that
- the order of saved messages is the same as the order of the
- messages originally (a subtle point...) **/
-
- if (sortby != RECEIVED_DATE) { /* what we want anyway! */
- last_sortby = sortby;
- sortby = RECEIVED_DATE;
- sort_mailbox(message_count, FALSE);
- sortby = last_sortby;
- }
-
- if (to_save && mbox_specified == 0)
- if (want_to("Keep mail in incoming mailbox? (y/n) ",dflt, ECHOIT)
- == 'y')
- if (to_delete) /* okay - keep undeleted as pending! */
- pending++;
- else { /* gag! nothing to delete, don't save! */
- unlock(); /* remove mailfile lock! */
- dprint0(3,"Keep mail in incoming mailbox? -- answer was YES\n");
- error("Mailbox unchanged");
- return(FALSE); /* nothing changed! */
- }
-
- /** okay...now lets do it! **/
-
- if (to_save > 0) {
- if (to_delete > 0)
- sprintf(buffer ,"[%s %d message%s, and deleting %d]",
- pending? "keeping" : "storing",
- to_save, plural(to_save), to_delete);
- else if (quitting)
- sprintf(buffer,"[%s %s]",
- pending? "keeping" : "storing",
- to_save > 1? "all messages" : "message");
- else
- buffer[0] = '\0'; /* no string! */
- }
- else {
- if (to_delete > 0)
- sprintf(buffer, "[deleting all messages]");
- else if (quitting)
- sprintf(buffer, "[no messages to %s, and none to delete]",
- pending? "keep" : "save");
- else
- buffer[0] = '\0';
- }
-
- dprint1(2,"Action: %s\n", buffer);
-
- error(buffer);
-
- if (! mbox_specified) {
- if (pending) { /* keep some messages pending! */
- sprintf(outfile,"%s%d", temp_mbox, getpid());
- unlink(outfile);
- }
- else if (mailbox_defined) /* save to specified mailbox */
- strcpy(outfile, mailbox);
- else /* save to $home/mbox */
- sprintf(outfile,"%s/mbox", home);
- }
- else {
- if (! to_delete) return(FALSE); /* no work to do! */
- sprintf(outfile, "%s%d", temp_file, getpid());
- unlink(outfile); /* ensure it's empty! */
- }
-
- if (to_save) {
- if ((errno = can_open(outfile, "a"))) {
- error1(
- "Permission to append to %s denied! Leaving mailbox intact\n",
- outfile);
- dprint2(1,
- "Error: Permission to append to outfile %s denied!! (%s)\n",
- outfile, "leavembox");
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- unlock();
- return(0);
- }
- if ((temp = fopen(outfile,"a")) == NULL) {
- if (mbox_specified == 0)
- unlock(); /* remove mailfile lock! */
- dprint1(1,"Error: could not append to file %s\n",
- outfile);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- sprintf(buffer, " Could not append to file %s! ",
- outfile);
- emergency_exit(Centerline(LINES-1, buffer));
- }
-
- for (i = 0; i < message_count; i++)
- if (! (header_table[i].status & DELETED)) {
- current = i+1;
- if (! number_saved++) {
- dprint2(2,"Saving message%s #%d, ", plural(to_save), current);
- }
- else {
- dprint1(2,"#%d, ", current);
- }
- copy_message("", temp, FALSE, FALSE);
- }
- fclose(temp);
- dprint0(2,"\n\n");
- }
-
- /* remove source file...either default mailbox or original copy of
- specified one! */
-
- if (mbox_specified == 0) {
- /** let's grab the original mode and date/time of the mailfile
- before removing it **/
-
- if (stat(infile, &buf) == 0)
- mode = buf.st_mode & 00777;
- else {
- dprint2(1,"Error: errno %s attempting to stat file %s\n",
- error_name(errno), infile);
- error2("Error %s (%s) on stat(%s)", error_name(errno),
- error_description(errno), infile);
- }
- }
-
- fclose(mailfile); /* close the baby... */
-
- if (mailfile_size != bytes(infile)) {
- sort_mailbox(message_count, FALSE); /* display sorting order! */
- unlock();
- error("New mail has just arrived - resyncing...");
- return(-1);
- }
- unlink(infile); /* and BLAMO! */
-
- if (to_save && (mbox_specified || pending)) {
- if (link(outfile, infile) != 0)
- if (errno == EXDEV) { /** different file devices! Use copy! **/
- if (copy(outfile, infile) != 0) {
- dprint2(1,"leavembox: copy(%s, %s) failed;",
- outfile, infile);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error("couldn't modify mail file!");
- sleep(1);
- sprintf(infile,"%s/%s", home, unedited_mail);
- if (copy(outfile, infile) != 0) {
- dprint1(1,"leavembox: couldn't copy to %s either!! Help;",
- infile);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error("something godawful is happening to me!!!");
- emergency_exit();
- }
- else {
- dprint1(1,"\nWoah! Confused - Saved mail in %s (leavembox)\n",
- infile);
- error1("saved mail in %s", infile);
- }
- }
- }
- else {
- dprint2(1,"link(%s, %s) failed (leavembox)\n", outfile, infile);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error2("link failed! %s - %s", error_name(errno),
- error_description(errno));
- emergency_exit();
- }
- unlink(outfile);
- }
-
- if (mbox_specified == 0) {
- if (mode != 00644) { /* if not the default mail access mode... */
- if (! pending) { /* if none still being saved */
- temp = fopen(infile, "w");
- fclose(temp);
- }
- chmod(infile,mode);
-
- /* let's set the access times of the new mail file to be
- the same as the OLD one (still sitting in 'buf') ! */
-
- times.actime = buf.st_atime;
- times.modtime= buf.st_mtime;
-
- if (utime(infile, ×) != 0) {
- dprint0(1,"Error: encountered error doing utime (leavmbox)\n");
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error2("Error %s trying to change file %s access time",
- error_name(errno), infile);
- }
- }
- unlock(); /* remove the lock on the file ASAP! */
-
- /** finally, let's change the ownership of the default
- outgoing mailbox, if needed **/
-
- if (to_save)
- chown(outfile, userid, groupid);
- }
-
- #ifdef SAVE_GROUP_MAILBOX_ID
- chown(infile, userid, getegid()); /** see the Config Guide **/
- #else
- chown(infile, userid, groupid); /** file owned by user **/
- #endif
-
- return(to_delete);
- }
-
- char lock_name[SLEN];
-
- lock(direction)
- int direction;
- {
- /** Create lock file to ensure that we don't get any mail
- while altering the mailbox contents!
- If it already exists sit and spin until
- either the lock file is removed...indicating new mail
- or
- we have iterated MAX_ATTEMPTS times, in which case we
- either fail or remove it and make our own (determined
- by if REMOVE_AT_LAST is defined in header file
-
- If direction == INCOMING then DON'T remove the lock file
- on the way out! (It'd mess up whatever created it!).
- **/
-
- register int iteration = 0, access_val;
-
- sprintf(lock_name,"%s%s.lock", mailhome, username);
-
- access_val = access(lock_name, ACCESS_EXISTS);
-
- while (access_val != -1 && iteration++ < MAX_ATTEMPTS) {
- dprint1(2,"File '%s' currently exists! Waiting...(lock)\n",
- lock_name);
- if (direction == INCOMING)
- PutLine0(LINES, 0, "\nMail being received!\twaiting...");
- else
- error1("Attempt %d: Mail being received...waiting",
- iteration);
- sleep(5);
- access_val = access(lock_name, ACCESS_EXISTS);
- }
-
- if (access_val != -1) {
-
- #ifdef REMOVE_AT_LAST
-
- /** time to waste the lock file! Must be there in error! **/
-
- dprint0(2,
- "Warning: I'm giving up waiting - removing lock file(lock)\n");
- if (direction == INCOMING)
- PutLine0(LINES, 0,"\nTimed out - removing current lock file...");
- else
- error("Throwing away the current lock file!");
-
- if (unlink(lock_name) != 0) {
- dprint3(1,"Error %s (%s)\n\ttrying to unlink file %s (%s)\n",
- error_name(errno), error_description(errno), lock_name);
- PutLine1(LINES, 0,
- "\n\rI couldn't remove the current lock file %s\n\r",
- lock_name);
- PutLine2(LINES, 0, "** %s - %s **\n\r", error_name(errno),
- error_description(errno));
- if (direction == INCOMING)
- leave();
- else
- emergency_exit();
- }
-
- /* everything is okay, so lets act as if nothing had happened... */
-
- #else
-
- /* okay...we die and leave, not updating the mailfile mbox or
- any of those! */
- if (direction == INCOMING) {
- PutLine1(LINES, 0, "\nGiving up after %d iterations...", iteration);
- PutLine0(LINES, 0,
- "Please try to read your mail again in a few minutes.\n");
- dprint1(2,"Warning:bailing out after %d iterations...(lock)\n",
- iteration);
- leave_locked();
- }
- else {
- dprint1(2,"Warning: after %d iterations, timed out! (lock)\n",
- iteration);
- leave(error("Timed out on lock file reads. Leaving program"));
- }
-
- #endif
- }
-
- /* if we get here we can create the lock file, so lets do it! */
-
- if (creat(lock_name, 0) == -1) {
- dprint2(1,"Can't create lock file: creat(%s) raises error %s (lock)\n",
- lock_name, error_name(errno));
- if (errno == EACCES)
- leave(error1(
- "Can't create lock file! I need write permission in %s!\n\r",
- mailhome));
- else {
- dprint1(1,"Error encountered attempting to create lock %s\n",
- lock_name);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- PutLine1(LINES, 0,
- "\n\rError encountered while attempting to create lock file %s;\n\r",
- lock_name);
- PutLine2(LINES, 0, "** %s - %s **\n\r", error_name(errno),
- error_description(errno));
- leave();
- }
- }
- }
-
- unlock()
- {
- /** Remove the lock file! This must be part of the interrupt
- processing routine to ensure that the lock file is NEVER
- left sitting in the mailhome directory! **/
-
- (void) unlink(lock_name);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 12538 ]
- then
- echo $filename changed - should be 12538 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/bounceback.c ----------
-
- filename="src/bounceback.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/bounceback.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** bounceback.c **/
-
- /** This set of routines implement the bounceback feature of the mailer.
- This feature allows mail greater than 'n' hops away (n specified by
- the user) to have a 'cc' to the user through the remote machine.
-
- Due to the vagaries of the Internet addressing (uucp -> internet -> uucp)
- this will NOT generate bounceback copies with mail to an internet host!
-
- (C) Copyright 1986 by Dave Taylor
- **/
-
- #include "headers.h"
-
- char *bounce_off_remote(); /* forward declaration */
-
- int
- uucp_hops(to)
- char *to;
- {
- /** Given the entire "To:" list, return the number of hops in the
- first address (a hop = a '!') or ZERO iff the address is to a
- non uucp address.
- **/
-
- register int hopcount = 0, index;
-
- for (index = 0; ! whitespace(to[index]) && to[index] != '\0'; index++) {
- if (to[index] == '!')
- hopcount++;
- else if (to[index] == '@' || to[index] == '%' || to[index] == ':')
- return(0); /* don't continue! */
- }
-
- return(hopcount);
- }
-
- char *bounce_off_remote(to)
- char *to;
- {
- /** Return an address suitable for framing (no, that's not it...)
- Er, suitable for including in a 'cc' line so that it ends up
- with the bounceback address. The method is to take the first
- address in the To: entry and break it into machines, then
- build a message up from that. For example, consider the
- following address:
- a!b!c!d!e!joe
- the bounceback address would be;
- a!b!c!d!e!d!c!b!a!ourmachine!ourname
- simple, eh?
- **/
-
- static char address[LONG_STRING]; /* BEEG address buffer! */
-
- char host[MAX_HOPS][SHORT_SLEN]; /* for breaking up addr */
- register int hostcount = 0, hindex = 0,
- index;
-
- for (index = 0; !whitespace(to[index]) && to[index] != '\0'; index++) {
- if (to[index] == '!') {
- host[hostcount][hindex] = '\0';
- hostcount++;
- hindex = 0;
- }
- else
- host[hostcount][hindex++] = to[index];
- }
-
- /* we have hostcount hosts... */
-
- strcpy(address, host[0]); /* initialize it! */
-
- for (index=1; index < hostcount; index++) {
- strcat(address, "!");
- strcat(address, host[index]);
- }
-
- /* and now the same thing backwards... */
-
- for (index = hostcount -2; index > -1; index--) {
- strcat(address, "!");
- strcat(address, host[index]);
- }
-
- /* and finally, let's tack on our machine and login name */
-
- strcat(address, "!");
- strcat(address, hostname);
- strcat(address, "!");
- strcat(address, username);
-
- /* and we're done!! */
-
- return( (char *) address );
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 2498 ]
- then
- echo $filename changed - should be 2498 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/opt_utils.c ----------
-
- filename="src/opt_utils.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/opt_utils.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** 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 <stdio.h>
-
- #ifdef BSD
- # include <pwd.h>
- #endif
-
- #ifdef UTS
- # include <sys/utsname.h>
- # include <sys/tubio.h>
-
- # define TTYIN 0 /* standard input */
-
- 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';
-
- }
-
- int
- isa3270()
- {
- /** Returns TRUE and sets LINES and COLUMNS to the correct values
- for an Amdahl (IBM) tube screen, or returns FALSE if on a normal
- terminal (of course, next to a 3270, ANYTHING is normal!!) **/
-
- struct tubiocb tubecb;
-
- dprint0(3,"Seeing if we're a 3270...");
-
- if (ioctl(TTYIN, TUBGETMOD, &tubecb) == -1) {
- dprint0(3,"We're not!\n");
- return(FALSE); /* not a tube! */
- }
-
- LINES = tubecb->line_cnt - 1;
- COLUMNS = tubecb->col_cnt;
-
- dprint2(3,"We are! %d lines and %d columns!\n",
- LINES, COLUMNS);
- return(TRUE);
- }
-
- #endif /* def UTS */
-
- #ifdef BSD
-
- cuserid(uname)
- char *uname;
- {
- /** Added for compatibility with Bell systems, this is the last-ditch
- attempt to get the users login name, after getlogin() fails. It
- instantiates "uname" to the name of the user...
- **/
-
- struct passwd *password_entry, *getpwuid();
-
- password_entry = getpwuid(getuid());
-
- strcpy(uname, 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);
- }
-
- char *strchr(buffer, ch)
- char *buffer, ch;
- {
- /** Returns a pointer to the first occurance of the character
- 'ch' in the specified string or NULL if it doesn't occur **/
-
- char *address;
-
- address = buffer;
-
- while (*address != ch) {
- if (*address == '\0')
- return (NULL);
- address++;
- }
-
- return ( (char *) address);
- }
-
- #endif
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4997 ]
- then
- echo $filename changed - should be 4997 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/softkeys.c ----------
-
- filename="src/softkeys.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/softkeys.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** softkeys.c **/
-
- /** This file and associated routines: (C) Copyright 1986, Dave Taylor **/
-
- #include <stdio.h>
- #include "headers.h"
-
- define_softkeys(level)
- int level;
- {
- if (! hp_softkeys) return;
-
- if (level == MAIN) {
- 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 ELM", "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 ELM", "q");
- }
- }
- else if (level == ALIAS) {
- 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 ELM", "r");
- }
- else if (level == YESNO) {
- 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) {
- 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 ELM", "\n");
- }
- else if (level == CHANGE) {
- 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];
-
- sprintf(buffer,"%s%s", display, send);
-
- fprintf(stderr, "%c&f%dk%dd%dL%s", ESCAPE, key,
- strlen(display), strlen(send), buffer);
- fflush(stdout);
- }
-
- softkeys_on()
- {
- /* turn on softkeys (esc&jB) and turn on MENU and USER/SYSTEM */
-
- if (hp_softkeys) {
- fprintf(stderr, "%c&jB%c&jR", ESCAPE, ESCAPE);
- fflush(stdout);
- }
-
- }
-
- softkeys_off()
- {
- /* turn off softkeys (esc&j@) */
-
- if (hp_softkeys) {
- fprintf(stderr, "%c&j@", ESCAPE);
- fflush(stdout);
- }
- }
-
- clear_key(key)
- {
- /** set a key to nothing... **/
-
- if (hp_softkeys)
- define_key(key, " ", "");
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 2696 ]
- then
- echo $filename changed - should be 2696 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/mailmsg2.c ----------
-
- filename="src/mailmsg2.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/mailmsg2.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** mailmsg2.c **/
-
- /** Interface to allow mail to be sent to users. Part of ELM **/
-
- /** (C) Copyright 1986, Dave Taylor **/
-
- #include "headers.h"
- #include <errno.h>
-
- extern int errno;
-
- char *error_name(), *error_description();
-
- char *format_long(), *strip_commas(), *tail_of_string();
- FILE *write_header_info();
-
- extern char subject[SLEN], action[SLEN], reply_to[SLEN], expires[SLEN],
- priority[SLEN], to[VERY_LONG_STRING], cc[VERY_LONG_STRING],
- in_reply_to[SLEN];
-
- int gotten_key = 0;
-
- char *bounce_off_remote();
-
- mail(expanded_to, expanded_cc, copy_msg, edit_message, batch)
- char *expanded_to, *expanded_cc;
- int copy_msg, edit_message, batch;
- {
- /** Given the addresses and various other miscellany (specifically,
- 'copy-msg' indicates whether a copy of the current message should
- be included, 'edit_message' indicates whether the message should
- be edited and 'batch' indicates that the message should be read
- from stdin) this routine will invoke an editor for the user and
- then actually mail off the message.
- **/
-
- FILE *reply, *real_reply; /* second is post-input buffer */
- char filename[SLEN], filename2[SLEN],
- very_long_buffer[VERY_LONG_STRING];
- char ret_ch, ch;
- register int retransmit = FALSE;
-
- static int cancelled_msg = 0;
-
- dprint2(4,"\nMailing to '%s' (with%s editing)\n",
- expanded_to, edit_message? "" : "out");
-
- /** first generate the temporary filename **/
-
- sprintf(filename,"%s%d",temp_file, getpid());
-
- /** if possible, let's try to recall the last message? **/
-
- if (! batch)
- retransmit = recall_last_msg(filename, copy_msg, &cancelled_msg);
-
- /** if we're not retransmitting, create the file.. **/
-
- if (! retransmit)
- if ((reply = fopen(filename,"w")) == NULL) {
- dprint2(1,
- "Attempt to write to temp file %s failed with error %s (mail)\n",
- filename, error_name(errno));
- error2("Could not create file %s (%s)",filename,
- error_name(errno));
- return(1);
- }
-
- if (batch) {
- Raw(OFF);
- ret_ch = '\n';
- if (isatty(fileno(stdin))) {
- printf("To: %s\nSubject: %s\n", expanded_to, subject);
- printf("\nPlease enter your message, ending with a ^D:\n\n");
- ret_ch = '\0';
- }
- while (gets(very_long_buffer, VERY_LONG_STRING) != NULL)
- fprintf(reply, "%s%c", very_long_buffer, ret_ch);
-
- if (isatty(fileno(stdin)))
- printf("<end-of-message>\n");
- }
-
- if (copy_msg && ! retransmit) /* if retransmit we ALREADY have it! */
- if (edit_message)
- copy_message(prefixchars, reply, noheader, FALSE);
- else
- copy_message("", reply, noheader, FALSE);
-
- if (!batch && ! retransmit && signature) {
- sprintf(filename2, "%s/%s", home, signature_file);
- (void) append(reply, filename2);
- }
-
- if (! retransmit)
- (void) fclose(reply); /* on replies, it won't be open! */
-
- /** Edit the message **/
-
- if (edit_message)
- create_readmsg_file(); /* for "readmsg" routine */
-
- ch = edit_message? 'e' : 'e'; /* drop through if needed... */
-
- if (! batch) {
- do {
- switch (ch) {
- case 'e' : if (edit_message) edit_the_message(filename);
-
- /** now let's try reading it again... **/
-
- (void) fclose(reply); /* make sure it's closed */
- if ((reply = fopen(filename,"r")) == NULL) {
- dprint2(1,
- "Attempt to open file %s for reading failed with error %s (mail)\n",
- filename, error_name(errno));
- error1("Could not open reply file (%s)",
- error_name(errno));
- return(1);
- }
- break;
-
- case 'h' : edit_headers();
- break;
- }
-
- /** ask that silly question again... **/
-
- if ((ch = verify_transmission()) == 'f') { /* cancelled it! */
- cancelled_msg = TRUE;
- return(1);
- }
- } while (ch != 's');
- }
- else if ((reply = fopen(filename,"r")) == NULL) {
- dprint2(1,
- "Attempt to open file %s for reading failed with error %s (mail)\n",
- filename, error_name(errno));
- error1("Could not open reply file (%s)", error_name(errno));
- return(1);
- }
-
- cancelled_msg = FALSE; /* it ain't cancelled, is it? */
-
- /** ask about bounceback if the user wants us to.... **/
-
- if (uucp_hops(to) > bounceback && bounceback > 0)
- if (verify_bounceback() == TRUE) {
- if (strlen(cc) > 0) strcat(cc, ", ");
- strcat(cc, bounce_off_remote(to));
- }
-
- /** grab a copy if the user so desires... **/
-
- if (auto_cc && ! batch)
- save_copy(subject, expanded_to, expanded_cc, filename, to);
-
- /** write all header information into real_reply **/
-
- sprintf(filename2,"%s%d",temp_file, getpid()+1);
-
- /** try to write headers to new temp file **/
-
- dprint2(5, "Composition file='%s' and mail buffer='%s'\n",
- filename, filename2);
-
- if ((real_reply=write_header_info(filename2, expanded_to, expanded_cc))
- == NULL) {
-
- /** IT FAILED!! MEIN GOTT! Use a dumb mailer instead! **/
-
- dprint1(3,"** write_header failed: %s\n", error_name(errno));
-
- if (cc[0] != '\0') /* copies! */
- sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
-
- sprintf(very_long_buffer, "( (%s -s \"%s\" %s ; %s %s) & ) < %s",
- mailx, subject, strip_commas(expanded_to),
- remove, filename, filename);
-
- error1("Message sent using dumb mailer - %s", mailx);
- sleep(2); /* ensure time to see this prompt! */
-
- }
- else {
- copy_message_across(reply, real_reply);
-
- fclose(real_reply);
-
- if (cc[0] != '\0') /* copies! */
- sprintf(expanded_to,"%s %s", expanded_to, expanded_cc);
-
- if (access(sendmail, EXECUTE_ACCESS) == 0) /* Yeah! Sendmail! */
- sprintf(very_long_buffer,"( (%s %s %s ; %s %s) & ) < %s",
- sendmail, smflags, strip_commas(expanded_to),
- remove, filename2, filename2);
- else /* oh well, use default mailer... */
- sprintf(very_long_buffer,"( (%s %s ; %s %s) & ) < %s",
- mailer, strip_commas(expanded_to),
- remove, filename2, filename2);
- }
-
- fclose(reply);
-
- if (mail_only) {
- printf("sending mail...");
- fflush(stdout);
- }
- else {
- PutLine0(LINES,0,"sending mail...");
- CleartoEOLN();
- }
-
- system_call(very_long_buffer, SH);
-
- if (mail_only)
- printf("\rmail sent! \n\r");
- else
- set_error("Mail sent!");
-
- return(TRUE);
- }
-
- int
- recall_last_msg(filename, copy_msg, cancelled_msg)
- char *filename;
- int copy_msg, *cancelled_msg;
- {
- /** If filename exists and we've recently cancelled a message,
- the ask if the user wants to use that message instead! This
- routine returns TRUE if the user wants to retransmit the last
- message, FALSE otherwise...
- **/
-
- register int retransmit = FALSE;
-
- if (access(filename, EDIT_ACCESS) == 0 && *cancelled_msg) {
- Raw(ON);
- CleartoEOLN();
- if (copy_msg)
- PutLine1(LINES-1,0,"Recall last kept message instead? (y/n) y%c",
- BACKSPACE);
- else
- PutLine1(LINES-1,0,"Recall last kept message? (y/n) y%c",
- BACKSPACE);
- fflush(stdout);
- if (tolower(ReadCh()) != 'n') {
- Write_to_screen("Yes",0);
- retransmit++;
- }
- else
- Write_to_screen("No",0);
-
- fflush(stdout);
-
- *cancelled_msg = 0;
- }
-
- return(retransmit);
- }
-
- edit_the_message(filename)
- char *filename;
- {
- /** Invoke the users editor on the filename. Return when done. **/
-
- char buffer[SLEN];
- register int stat;
-
- PutLine0(LINES, 0, "invoking editor..."); fflush(stdout);
-
- sprintf(buffer,"%s %s", editor, filename);
-
- Raw(OFF);
-
- chown(filename, userid, groupid); /* file was owned by root! */
-
- if (cursor_control)
- transmit_functions(OFF); /* function keys are local */
-
- if ((stat = system_call(buffer, SH)) != 0) {
- dprint1(1,"System call failed with stat %d (edit_the_message)\n",
- stat);
- error1("Can't invoke editor '%s' for composition", editor);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- ClearLine(LINES-1);
- sleep(2);
- }
-
- if (cursor_control)
- transmit_functions(ON); /* function keys are local */
-
- Raw(ON);
- }
-
- int
- verify_transmission()
- {
- /** Ensure the user wants to send this. This routine returns
- TRUE if everything is okay, FALSE if cancelled. **/
-
- char ch;
-
- if (mail_only) {
- if (isatty(fileno(stdin))) {
- printf("\n\rAre you sure you want to send this? (y/n) ");
- CleartoEOLN();
- printf("y%c", BACKSPACE);
- fflush(stdin); /* wait for answer! */
- fflush(stdout);
- if (tolower(ReadCh()) == 'n') { /* >SIGH< */
- printf("No\n\r\n\r\n\rMail not sent!!\n\r");
- return('f'); /* forget it! */
- }
- else
- printf("Yes\n\r\n\r");
- return('s'); /* send this baby! */
- }
- else
- return('s'); /* ditto */
- }
- else if (check_first) { /* used to check strlen(infile) > 0 too? */
- reprompt:
- MoveCursor(LINES,0);
- CleartoEOLN();
- ClearLine(LINES-1);
-
- PutLine1(LINES-1, 0,
- "Please choose: E)dit msg, edit H)eaders, S)end, or F)orget : s%c",
- BACKSPACE);
-
- fflush(stdin); /* wait for answer! */
- fflush(stdout);
- ch = tolower(ReadCh());
-
- switch (ch) {
- case 'f': Write_to_screen("Forget",0);
- set_error(
- "Message kept - Can be restored at next F)orward, M)ail or R)eply ");
- break;
-
- case '\n' :
- case '\r' :
- case 's' : Write_to_screen("Send",0);
- ch = 's'; /* make sure! */
- break;
-
- case 'e' : Write_to_screen("Edit",0);
- break;
- case 'h' : Write_to_screen("Headers",0);
- break;
-
- default : Write_to_screen("%c??", 1, 07); /* BEEP */
- sleep(1);
- goto reprompt; /* yech */
- }
-
- return(ch);
- }
- }
-
- FILE *
- write_header_info(filename, long_to, long_cc)
- char *filename, *long_to, *long_cc;
- {
- /** Try to open filedesc as the specified filename. If we can,
- then write all the headers into the file. The routine returns
- 'filedesc' if it succeeded, NULL otherwise **/
-
- static FILE *filedesc; /* our friendly file descriptor */
-
- FILE *headerfdesc; /* file descriptor for .elmheaders */
- char fnamebuffer[SLEN]; /* buffer for filename creation */
- char buffer[LONG_SLEN]; /* .elmheader file reading buffer */
-
- char *get_arpa_date();
-
- if ((filedesc = fopen(filename, "w")) == NULL) {
- dprint1(1,
- "Attempt to open file %s for writing failed! (write_header_info)\n",
- filename);
- dprint2(1,"** %s - %s **\n\n", error_name(errno),
- error_description(errno));
- error2("Error %s encountered trying to write to %s",
- error_name(errno), filename);
- sleep(2);
- return(NULL); /* couldn't open it!! */
- }
-
- fprintf(filedesc, "To: %s\n", format_long(long_to, strlen("To:")));
-
- fprintf(filedesc,"Date: %s\n", get_arpa_date());
-
- #ifndef DONT_ADD_FROM
- # ifdef INTERNET_ADDRESS_FORMAT
- # ifdef USE_DOMAIN
- fprintf(filedesc,"From: %s@%s%s (%s)\n", username, hostname,
- DOMAIN, full_username);
- # else
- fprintf(filedesc,"From: %s@%s (%s)\n", username, hostname,
- full_username);
- # endif
- # else
- fprintf(filedesc,"From: %s!%s (%s)\n", hostname, username,
- full_username);
- # endif
- #endif
-
- fprintf(filedesc, "Subject: %s\n", subject);
-
- if (cc[0] != '\0')
- fprintf(filedesc, "Cc: %s\n", format_long(long_cc, strlen("Cc: ")));
-
- if (strlen(action) > 0)
- fprintf(filedesc, "Action: %s\n", action);
-
- if (strlen(priority) > 0)
- fprintf(filedesc, "Priority: %s\n", priority);
-
- if (strlen(expires) > 0)
- fprintf(filedesc, "Expiration-Date: %s\n", expires);
-
- if (strlen(reply_to) > 0)
- fprintf(filedesc, "Reply-To: %s\n", reply_to);
-
- if (strlen(in_reply_to) > 0)
- fprintf(filedesc, "In-Reply-To: %s\n", in_reply_to);
-
- /*** add the users .mailheaders file if available ***/
-
- sprintf(fnamebuffer, "%s/%s", home, mailheaders);
-
- if ((headerfdesc = fopen(fnamebuffer, "r")) != NULL) {
- while (fgets(buffer, LONG_SLEN, headerfdesc) != NULL)
- if (strlen(buffer) < 2) {
- dprint0(2,
- "Strlen of line from .elmheaders is < 2 (write_header_info)");
- error1("Warning: blank line in %s ignored!", fnamebuffer);
- sleep(2);
- }
- else
- fprintf(filedesc, "%s", buffer);
-
- fclose(headerfdesc);
- }
-
- fprintf(filedesc, "X-Mailer: ELM [version %s]\n\n", VERSION);
-
- return((FILE *) filedesc);
- }
-
- copy_message_across(source, dest)
- FILE *source, *dest;
- {
- /** copy the message in the file pointed to by source to the
- file pointed to by dest. **/
-
- int crypted = FALSE; /* are we encrypting? */
- int encoded_lines = 0; /* # lines encoded */
- char buffer[LONG_SLEN]; /* file reading buffer */
-
- while (fgets(buffer, LONG_SLEN, source) != NULL) {
- if (buffer[0] == '[') {
- if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
- crypted = TRUE;
- else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
- crypted = FALSE;
- else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0)
- continue; /* next line? */
- }
- else if (crypted) {
- if (! gotten_key++)
- getkey(ON);
- else if (! encoded_lines++)
- get_key_no_prompt(); /* reinitialize.. */
-
- encode(buffer);
- }
- fputs(buffer, dest);
- }
- }
-
- int
- verify_bounceback()
- {
- /** Ensure the user wants to have a bounceback copy too. (This is
- only called on messages that are greater than the specified
- threshold hops and NEVER for non-uucp addresses.... Returns
- TRUE iff the user wants to bounce a copy back....
- **/
-
- if (mail_only) {
- printf("Would you like a copy \"bounced\" off the remote? (y/n) ");
- CleartoEOLN();
- printf("n%c", BACKSPACE);
- fflush(stdin); /* wait for answer! */
- fflush(stdout);
- if (tolower(ReadCh()) != 'y') {
- printf("No\n\r");
- return(FALSE);
- }
- else
- printf("Yes - Bounceback included\n\r");
- }
- else {
- MoveCursor(LINES,0);
- CleartoEOLN();
- PutLine1(LINES,0,
- "\"Bounce\" a copy off the remote machine? (y/n) y%c",
- BACKSPACE);
- fflush(stdin); /* wait for answer! */
- fflush(stdout);
- if (tolower(ReadCh()) != 'y') {
- Write_to_screen("No", 0);
- fflush(stdout);
- return(FALSE);
- }
- Write_to_screen("Yes!", 0);
- fflush(stdout);
- }
-
- return(TRUE);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 14200 ]
- then
- echo $filename changed - should be 14200 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/savecopy.c ----------
-
- filename="src/savecopy.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/savecopy.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** 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
-
- #include <errno.h>
-
- char *format_long(), *get_arpa_date();
- char *error_name(), *error_description();
- char *ctime();
-
- extern char in_reply_to[SLEN]; /* In-Reply-To: string */
- extern int gotten_key; /* for encryption */
- extern int errno;
-
- 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? */
-
- savename[0] = '\0';
-
- if (save_by_name) {
- get_return_name(to, buffer, FALSE);
- if (strlen(buffer) == 0) {
- dprint1(3,"Warning: get_return_name couldn't break down %s\n", to);
- savename[0] = '\0';
- }
- else {
- sprintf(savename, "%s%s%s", folders,
- lastch(folders) == '/'? "" : "/", buffer);
-
- if ((errno = can_access(savename, READ_ACCESS)))
- savename[0] = '\0';
- }
- }
-
- if (strlen(savename) == 0) {
- if (strlen(savefile) == 0)
- return(error("variable 'SAVEFILE' not defined!"));
- strcpy(savename, savefile);
- }
-
- if ((errno = can_access(savename, WRITE_ACCESS))) {
- dprint0(2,"Error: attempt to autosave to a file that can't...\n");
- dprint1(2,"\tbe appended to: %s (save_copy)\n", savename);
- dprint2(2,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error1("permission to append to %s denied!", savename);
- sleep(2);
- return(FALSE);
- }
-
- if ((save = fopen(savename, "a")) == NULL) {
- dprint2(1,"Error: Couldn't append message to file %s (%s)\n",
- savename, "save_copy");
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error1("couldn't append to %s", savename);
- sleep(2);
- return(FALSE);
- }
-
- if ((message = fopen(filename, "r")) == NULL) {
- fclose(save);
- dprint1(1,"Error: Couldn't read file %s (save_copy)\n", filename);
- dprint2(1,"** %s - %s **\n", error_name(errno),
- error_description(errno));
- error1("couldn't read file %s!", filename);
- sleep(2);
- return(FALSE);
- }
-
- 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 = (long) time(0); /* this must be here for it to work! */
-
- fprintf(save,"\nFrom To:%s %s", buffer, 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(in_reply_to) > 0)
- fprintf(save, "In-Reply-To: %s\n", in_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, groupid);
- return(TRUE);
- }
- }
- else if (crypted) {
- if (! gotten_key++)
- getkey(ON);
- encode(buffer);
- }
- fputs(buffer, save);
- }
-
- fclose(message);
- fclose(save);
-
- /* make sure save file isn't owned by root! */
- chown(savename, userid, groupid);
-
- return(TRUE);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 4059 ]
- then
- echo $filename changed - should be 4059 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- echo end of this archive file....
- exit 0
-
-