v06i035: Elm mail system (elm), Part10/14
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Wed Jul 2 01:19:55 AEST 1986
Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
Mod.sources: Volume 6, Issue 35
Archive-name: elm/Part10
# Continuation of Shell Archive, created by hpldat!taylor
# This is part 10
# 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/mailmsg1.c ----------
filename="src/mailmsg1.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/mailmsg1.c...
fi
cat << 'END-OF-FILE' > $filename
/** mailmsg1.c **/
/** Interface to allow mail to be sent to users. Part of ELM **/
/** (C) Copyright 1986, Dave Taylor **/
#include "headers.h"
/** strings defined for the hdrconfg routines **/
char subject[SLEN], action[SLEN], reply_to[SLEN], expires[SLEN], priority[SLEN];
char to[VERY_LONG_STRING], cc[VERY_LONG_STRING], in_reply_to[SLEN];
char *format_long(), *strip_commas(), *tail_of_string();
int
send(given_to, given_subject, edit_message)
char *given_to, *given_subject;
int edit_message;
{
/** Prompt for fields and then call mail() to send the specified
message. If 'edit_message' is true then don't allow the
message to be edited. **/
char address[VERY_LONG_STRING], addressII[VERY_LONG_STRING];
int copy_msg = FALSE, is_a_response = FALSE;
/* First: zero all current global message strings */
cc[0] = action[0] = reply_to[0] = expires[0] = priority[0] = '\0';
in_reply_to[0] = address[0] = addressII[0] = '\0';
strcpy(subject, given_subject); /* copy given subject */
strcpy(to, given_to); /* copy given to: */
/******* And now the real stuff! *******/
copy_msg=copy_the_msg(&is_a_response); /* copy msg into edit buffer? */
if (get_to(to, address) == 0) /* get the To: address and expand */
return(0);
/** are we by any chance just checking the addresses? **/
if (check_only) {
printf("Expands to: %s\n", format_long(address, 12));
putchar('\r'); /* don't ask... */
leave();
}
/** if we're batchmailing, let's send it and GET OUTTA HERE! **/
if (mail_only && strlen(batch_subject) > 0) {
strcpy(subject, batch_subject); /* get the batch subject */
return(mail(address, NULL, FALSE, FALSE, TRUE));
}
display_to(address); /* display the To: field on screen... */
dprint1(3,"\nMailing to %s\n", address);
if (get_subject(subject) == 0) /* get the Subject: field */
return(0);
dprint1(4,"Subject is %s\n", subject);
if (get_copies(cc, address, addressII) == 0) /* get the cc: field */
return(0);
if (strlen(cc) > 0)
dprint1(4,"Copies to %s\n", cc);
if (mail_only) /* indicate next step... */
printf("\n\r");
else
MoveCursor(LINES,0); /* you know you're hit <return> ! */
/** generate the In-Reply-To: header... **/
if (is_a_response)
generate_reply_to(current-1);
/* and mail that puppy outta here! */
mail(address, addressII, copy_msg, edit_message, FALSE);
return(edit_message);
}
get_to(to_field, address)
char *to_field, *address;
{
/** prompt for the "To:" field, expanding into address if possible.
This routine returns ZERO if errored, or non-zero if okay **/
if (strlen(to_field) == 0) {
PutLine0(LINES-2, 0, "To: ");
(void) optionally_enter(to_field, LINES-2, 4, FALSE);
if (strlen(to_field) == 0) {
ClearLine(LINES-2);
return(0);
}
build_address(strip_commas(to_field), address);
}
else if (mail_only)
build_address(strip_commas(to_field), address);
else
strcpy(address, to_field);
if (strlen(address) == 0) { /* bad address! Removed!! */
if (! mail_only)
ClearLine(LINES-2);
return(0);
}
return(1); /* everything is okay... */
}
get_subject(subject_field)
char *subject_field;
{
/** get the subject and return non-zero if all okay... **/
if (mail_only)
printf("Subject: ");
else
PutLine0(LINES-2,0,"Subject: ");
CleartoEOLN();
if (optionally_enter(subject_field, LINES-2, 9, TRUE) == -1) {
/** User hit the BREAK key! **/
MoveCursor(LINES-2,0);
CleartoEOLN();
dprint0(3,"User responded to \"Subject:\" with BREAK (get_subject)\n");
error("mail not sent");
return(0);
}
if (strlen(subject_field) == 0) { /* zero length subject?? */
if (mail_only)
printf("\n\rNo subject - Continue with message? (y/n) n%c",
BACKSPACE);
else
PutLine1(LINES-2,0,"No subject - Continue with message? (y/n) n%c",
BACKSPACE);
if (tolower(ReadCh()) != 'y') { /* user says no! */
if (mail_only) {
printf("\n\r\n\rMail Cancelled!\n\r");
return(0);
}
ClearLine(LINES-2);
dprint0(3,
"User reponded to \"Subject:\" with RETURN (get_subject)\n");
error("mail not sent");
return(0);
}
else if (! mail_only) {
PutLine0(LINES-2,0,"Subject: <none>");
CleartoEOLN();
}
}
return(1); /** everything is cruising along okay **/
}
get_copies(cc_field, address, addressII)
char *cc_field, *address, *addressII;
{
/** Get the list of people that should be cc'd, returning ZERO if
any problems arise. Address and AddressII are for expanding
the aliases out after entry!
If 'bounceback' is nonzero, add a cc to ourselves via the remote
site, but only if hops to machine are > bounceback threshold.
**/
if (mail_only)
printf("\n\rCopies To: ");
else
PutLine0(LINES-1,0,"Copies To: ");
fflush(stdout);
if (optionally_enter(cc_field, LINES-1, 11, FALSE) == -1) {
if (mail_only) {
printf("\n\r\n\rMail not sent!\n\r");
return(0);
}
ClearLine(LINES-2);
ClearLine(LINES-1);
dprint0(3,
"User responded to \"Copies To:\" with BREAK. Mail cancelled (get_copies)\n");
error("mail not sent");
return(0);
}
build_address(strip_commas(cc_field), addressII);
if (strlen(address) + strlen(addressII) > VERY_LONG_STRING) {
dprint0(2,
"String length of \"To:\" + \"Cc\" too long! (get_copies)\n");
error("Too many people. Copies ignored");
sleep(2);
cc_field[0] = '\0';
}
return(1); /* everything looks okay! */
}
int
copy_the_msg(is_a_response)
int *is_a_response;
{
/** Returns True iff the user wants to copy the message being
replied to into the edit buffer before invoking the editor!
Sets "is_a_response" to true if message is a response...
**/
int answer = FALSE;
if (strlen(to) > 0 && !mail_only) { /* predefined 'to' line! */
if (auto_copy)
answer = TRUE;
else
answer = (want_to("Copy message? (y/n) ", 'n', TRUE) == 'y');
*is_a_response = TRUE;
}
else
if (strlen(subject) > 0) /* predefined 'subject' (Forward) */
answer = TRUE;
return(answer);
}
display_to(address)
char *address;
{
/** Simple routine to display the "To:" line according to the
current configuration (etc)
**/
if (mail_only)
printf("To: %s\n\r", format_long(address));
else {
if (strlen(address) > COLUMNS-50)
PutLine1(LINES-3, COLUMNS-50, "To: (%s)",
tail_of_string(address, COLUMNS-50));
else {
PutLine1(LINES-3, COLUMNS-50, " To: %s", address);
CleartoEOLN();
}
}
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 6587 ]
then
echo $filename changed - should be 6587 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/connect_to.c ----------
filename="src/connect_to.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/connect_to.c...
fi
cat << 'END-OF-FILE' > $filename
/** connect_to.c **/
/** This contains the routine(s) needed to have the Elm mailer figure
out what machines the current machine can talk to. This can be
done in one of two ways - either the program can read the L.sys
file, or (if it fails or "UUNAME" define is present) will invoke
uuname to a file, then read the file in!
(C) Copyright Dave Taylor, 1986
**/
#include "headers.h"
get_connections()
{
/** get the direct connections that this machine has, by hook
or by crook (so to speak)
**/
#ifndef USE_UUNAME
FILE *lsysfile;
char buffer[SLEN], sysname[NLEN];
struct lsys_rec *system_record, *previous_record;
int loc_on_line;
previous_record = NULL;
if ((lsysfile = fopen(Lsys,"r")) == NULL) {
dprint1(1, "Warning: Can't open L.sys file %s (read_lsys)\n", Lsys);
#endif
if (read_uuname() == -1) {
error("Warning: couldn't figure out system connections...");
talk_to_sys = NULL;
}
#ifndef USE_UUNAME
/** ELSE: already read in uuname() output if we're here!! **/
return;
}
while (fgets(buffer, SLEN, lsysfile) != NULL) {
sscanf(buffer,"%s", sysname);
if (previous_record == NULL) {
dprint1(2, "L.sys\tdirect connection to %s, ", sysname);
loc_on_line = 30 + strlen(sysname);
previous_record = (struct lsys_rec *) malloc(sizeof *talk_to_sys);
strcpy(previous_record->name, sysname);
previous_record->next = NULL;
talk_to_sys = previous_record;
}
else if (! talk_to(sysname) && sysname[0] != '#') {
if (loc_on_line + strlen(sysname) > 80) {
dprint0(2, "\n\t");
loc_on_line = 8;
}
dprint1(2, "%s, ", sysname);
loc_on_line += (strlen(sysname) + 2);
system_record = (struct lsys_rec *) malloc(sizeof *talk_to_sys);
strcpy(system_record->name, sysname);
system_record->next = NULL;
previous_record->next = system_record;
previous_record = system_record;
}
}
fclose(lsysfile);
if (loc_on_line != 8)
dprint0(2, "\n");
dprint0(2, "\n"); /* for a nice format! Yeah! */
#endif
}
int
read_uuname()
{
/** This routine trys to use the uuname routine to get the names of
all the machines that this machine connects to...it returns
-1 on failure.
**/
FILE *fd;
char buffer[SLEN], filename[SLEN];
struct lsys_rec *system_record, *previous_record;
int loc_on_line;
sprintf(filename, "%s%d", temp_file, getpid());
sprintf(buffer,"%s > %s", uuname, filename);
if (system_call(buffer, SH) != 0) {
dprint0(1, "Can't get uuname info - system call failed!\n");
unlink(filename); /* insurance */
return(-1);
}
if ((fd = fopen(filename, "r")) == NULL) {
dprint1(1, "Can't get uuname info - can't open file %s for reading\n",
filename);
unlink(filename); /* insurance */
return(-1);
}
previous_record = NULL;
while (fgets(buffer, SLEN, fd) != NULL) {
no_ret(buffer);
if (previous_record == NULL) {
dprint1(2, "uuname\tdirect connection to %s, ", buffer);
loc_on_line = 30 + strlen(buffer);
previous_record = (struct lsys_rec *) malloc(sizeof *talk_to_sys);
strcpy(previous_record->name, buffer);
previous_record->next = NULL;
talk_to_sys = previous_record;
}
else { /* don't have to check uniqueness - uuname does that! */
if (loc_on_line + strlen(buffer) > 80) {
dprint0(2, "\n\t");
loc_on_line = 8;
}
dprint1(2, "%s, ", buffer);
loc_on_line += (strlen(buffer) + 2);
system_record = (struct lsys_rec *) malloc(sizeof *talk_to_sys);
strcpy(system_record->name, buffer);
system_record->next = NULL;
previous_record->next = system_record;
previous_record = system_record;
}
}
fclose(fd);
(void) unlink(filename); /* kill da temp file!! */
dprint0(2, "\n"); /* for a nice format! Yeah! */
return(0); /* it all went okay... */
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 3887 ]
then
echo $filename changed - should be 3887 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/remail.c ----------
filename="src/remail.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/remail.c...
fi
cat << 'END-OF-FILE' > $filename
/** remail.c **/
/** For those cases when you want to have a message continue along
to another person in such a way as they end up receiving it with
the return address the person YOU received the mail from (does
this comment make any sense yet??)...
(C) Copyright 1986 Dave Taylor
**/
#include "headers.h"
#include <errno.h>
extern int errno;
int
remail()
{
/** remail a message... returns TRUE if new foot needed ... **/
FILE *mailfd;
char entered[VERY_LONG_STRING], expanded[VERY_LONG_STRING];
char filename[SLEN], buffer[VERY_LONG_STRING];
entered[0] = '\0';
get_to(entered, expanded);
if (strlen(entered) == 0)
return(0);
display_to(expanded);
/** now the munge... **/
sprintf(filename, "%s%d", temp_file, getpid());
if ((mailfd = fopen(filename, "w")) == NULL) {
dprint1(1,"couldn't open temp file %s! (remail)\n", filename);
dprint2(1,"** %s - %s **\n", error_name(errno),
error_description(errno));
sprintf(buffer, "Sorry - couldn't open file %s for writing (%s)",
error_name(errno));
set_error(buffer);
return(1);
}
/** now let's copy the message into the newly opened
buffer... **/
copy_message("", mailfd, FALSE, TRUE);
fclose(mailfd);
/** Got the messsage, now let's ensure the person really wants to
remail it... **/
ClearLine(LINES-1);
ClearLine(LINES);
PutLine1(LINES-1,0,
"Are you sure you want to remail this message (y/n) ? y%c",
BACKSPACE);
fflush(stdin);
fflush(stdout);
if (tolower(ReadCh()) == 'n') { /* another day, another No... */
Write_to_screen("No", 0);
set_error("Bounce of message cancelled");
return(1);
}
Write_to_screen("Yes!", 0);
sprintf(buffer, "%s %s < %s", mailer, expanded, filename);
PutLine0(LINES,0,"resending mail...");
if ((errno = system_call(buffer)) != 0)
set_error("Remail failed with error %d!", errno);
else
set_error("mail resent");
return(1);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 1940 ]
then
echo $filename changed - should be 1940 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/signals.c ----------
filename="src/signals.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/signals.c...
fi
cat << 'END-OF-FILE' > $filename
/** signals.c **/
/** This set of routines traps various signals and informs the
user of the error, leaving the program in a nice, graceful
manner.
(C) Copyright 1986 Dave Taylor
**/
#include "headers.h"
#include <signal.h>
extern int pipe_abort; /* set to TRUE if receive SIGPIPE */
quit_signal()
{
dprint0(2,"\n** Received SIGQUIT **\n\n");
leave();
}
term_signal()
{
dprint0(2,"\n** Received SIGTERM **\n\n");
leave();
}
ill_signal()
{
dprint0(1,"\n** Received SIGILL **\n\n");
PutLine0(LINES, 0, "\n\rIllegal Instruction signal!\n\r");
emergency_exit();
}
fpe_signal()
{
dprint0(1,"\n** Received SIGFPE **\n\n");
PutLine0(LINES, 0,"\n\rFloating Point Exception signal!\n\r");
emergency_exit();
}
bus_signal()
{
dprint0(1,"\n** Received SIGBUS **\n\n");
PutLine0(LINES, 0,"\n\rBus Error signal!\n\r");
emergency_exit();
}
segv_signal()
{
dprint0(1,"\n** Received SIGSEGV **\n\n");
PutLine0(LINES, 0,"\n\rSegment Violation signal!\n\r");
emergency_exit();
}
alarm_signal()
{
/** silently process alarm signal for timeouts... **/
int alarm_signal();
signal(SIGALRM, alarm_signal);
}
pipe_signal()
{
/** silently process pipe signal... **/
int pipe_signal();
dprint0(2,"*** received SIGPIPE ***\n");
pipe_abort = TRUE; /* internal signal ... wheeee! */
signal(SIGPIPE, pipe_signal);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 1346 ]
then
echo $filename changed - should be 1346 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/curses.q ----------
filename="src/curses.q"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/curses.q...
fi
cat << 'END-OF-FILE' > $filename
/** curses.c **/
/** This library gives programs the ability to easily access the
termcap information and write screen oriented and raw input
programs. The routines can be called as needed, except that
to use the cursor / screen routines there must be a call to
InitScreen() first. The 'Raw' input routine can be used
independently, however.
Modified 2/86 to work (hopefully) on Berkeley systems. If
there are any problems with BSD Unix, please report them to
the author at hpcnoe!dat at HPLABS (fixed, if possible!)
(C) Copyright 1985 Dave Taylor, HP Colorado Networks
**/
#include "headers.h"
#ifdef RAWMODE
# ifdef BSD
# include <sgtty.h>
# else
# include <termio.h>
# endif
#endif
#include <ctype.h>
#ifdef BSD
#undef tolower
#endif
#include "curses.h"
#ifdef BSD
# include "/usr/include/curses.h" /* don't ask! */
#endif
#ifdef RAWMODE
# define TTYIN 0
#endif
extern int debug;
#ifdef RAWMODE
# ifndef BSD
struct termio _raw_tty,
_original_tty;
# endif
static int _inraw = 0; /* are we IN rawmode? */
static int _line = -1, /* initialize to "trash" */
_col = -1;
#ifdef UTS
static int _clear_screen = 0; /* Next i/o clear screen? */
static char _null_string[SLEN]; /* a string of nulls... */
#endif
#endif
static int _intransmit; /* are we transmitting keys? */
static
char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
*_setbold, *_clearbold, *_setunderline, *_clearunderline,
*_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
*_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off;
static
int
_lines, _columns;
static char _terminal[1024]; /* Storage for terminal entry */
static char _capabilities[256]; /* String for cursor motion */
static char *ptr = _capabilities; /* for buffering */
int outchar(); /* char output for tputs */
InitScreen()
{
/* Set up all this fun stuff: returns zero if all okay, or;
-1 indicating no terminal name associated with this shell,
-2..-n No termcap for this terminal type known
*/
int tgetent(), /* get termcap entry */
error;
char *tgetstr(), /* Get termcap capability */
termname[40];
#ifdef SUN
if (getenv("TERM") == NULL)
return(-1);
#endif
#ifdef UTS
/* use _line for lack of a better variable, what the heck! */
for (_line = 0; _line < SLEN; _line++)
_null_string[_line] = '\0';
#endif
if (strcpy(termname, getenv("TERM")) == NULL)
return(-1);
if ((error = tgetent(_terminal, termname)) != 1)
return(error-2);
_line = 1; /* where are we right now?? */
_col = 1; /* assume zero, zero... */
/* load in all those pesky values */
_clearscreen = tgetstr("cl", &ptr);
_moveto = tgetstr("cm", &ptr);
_up = tgetstr("up", &ptr);
_down = tgetstr("do", &ptr);
_right = tgetstr("nd", &ptr);
_left = tgetstr("bs", &ptr);
_setbold = tgetstr("so", &ptr);
_clearbold = tgetstr("se", &ptr);
_setunderline = tgetstr("us", &ptr);
_clearunderline = tgetstr("ue", &ptr);
_setinverse = tgetstr("so", &ptr);
_clearinverse = tgetstr("se", &ptr);
_sethalfbright = tgetstr("hs", &ptr);
_clearhalfbright = tgetstr("he", &ptr);
_cleartoeoln = tgetstr("ce", &ptr);
_cleartoeos = tgetstr("cd", &ptr);
_lines = tgetnum("li");
_columns = tgetnum("co");
_transmit_on = tgetstr("ks", &ptr);
_transmit_off = tgetstr("ke", &ptr);
if (!_left) {
_left = ptr;
*ptr++ = '\b';
*ptr++ = '\0';
}
#ifdef BSD
initscr(); /* initalize curses too! */
#endif
return(0);
}
char *return_value_of(termcap_label)
char *termcap_label;
{
/** This will return the string kept by termcap for the
specified capability. Modified to ensure that if
tgetstr returns a pointer to a transient address
that we won't bomb out with a later segmentation
fault (thanks to Dave at Infopro for this one!) **/
static char escape_sequence[20];
char *tgetstr(); /* Get termcap capability */
strcpy(escape_sequence, tgetstr(termcap_label, &ptr));
return( (char *) escape_sequence);
}
transmit_functions(newstate)
int newstate;
{
/** turn function key transmission to ON | OFF **/
if (newstate != _intransmit) {
_intransmit = ! _intransmit;
if (newstate == ON)
tputs(_transmit_on, 1, outchar);
else
tputs(_transmit_off, 1, outchar);
fflush(stdout); /* clear the output buffer */
}
}
/****** now into the 'meat' of the routines...the cursor stuff ******/
ScreenSize(lines, columns)
int *lines, *columns;
{
/** returns the number of lines and columns on the display. **/
*lines = _lines - 1; /* assume index from zero */
*columns = _columns;
}
ClearScreen()
{
/* clear the screen: returns -1 if not capable */
#ifdef UTS
if (isatube) {
_clear_screen++; /* queue up for clearing... */
return(0);
}
#endif
if (!_clearscreen)
return(-1);
tputs(_clearscreen, 1, outchar);
fflush(stdout); /* clear the output buffer */
return(0);
}
MoveCursor(row, col)
int row, col;
{
/** move cursor to the specified row column on the screen.
0,0 is the top left! **/
char *tgoto();
char *stuff;
_line = row; /* update current location... */
_col = col;
#ifdef UTS
if (isatube) {
at row, col;
return(0);
}
#endif
if (!_moveto)
return(-1);
stuff = (char *) tgoto(_moveto, col, row);
tputs(stuff, 1, outchar);
fflush(stdout);
return(0);
}
CursorUp()
{
/** move the cursor up one line **/
_line = (_line> 0? _line - 1: _line); /* up one line... */
#ifdef UTS
if (isatube) {
at _line, _col;
return(0);
}
#endif
if (!_up)
return(-1);
tputs(_up, 1, outchar);
fflush(stdout);
return(0);
}
CursorDown()
{
/** move the cursor down one line **/
_line = (_line< LINES? _line + 1: _line); /* up one line... */
#ifdef UTS
if (isatube) {
at _line, _col ;
return(0);
}
#endif
if (!_down)
return(-1);
tputs(_down, 1, outchar);
fflush(stdout);
return(0);
}
CursorLeft()
{
/** move the cursor one character to the left **/
_col = (_col > 0? _col - 1: _col); /* up one line... */
#ifdef UTS
if (isatube) {
at _line, _col;
return(0);
}
#endif
if (!_left)
return(-1);
tputs(_left, 1, outchar);
fflush(stdout);
return(0);
}
CursorRight()
{
/** move the cursor one character to the right (nondestructive) **/
_col = (_col < COLUMNS? _col + 1: _col); /* up one line... */
#ifdef UTS
if (isatube) {
at _line, _col;
return(0);
}
#endif
if (!_right)
return(-1);
tputs(_right, 1, outchar);
fflush(stdout);
return(0);
}
StartBold()
{
/** start boldface/standout mode **/
if (!_setbold)
return(-1);
tputs(_setbold, 1, outchar);
fflush(stdout);
return(0);
}
EndBold()
{
/** compliment of startbold **/
if (!_clearbold)
return(-1);
tputs(_clearbold, 1, outchar);
fflush(stdout);
return(0);
}
StartUnderline()
{
/** start underline mode **/
if (!_setunderline)
return(-1);
tputs(_setunderline, 1, outchar);
fflush(stdout);
return(0);
}
EndUnderline()
{
/** the compliment of start underline mode **/
if (!_clearunderline)
return(-1);
tputs(_clearunderline, 1, outchar);
fflush(stdout);
return(0);
}
StartHalfbright()
{
/** start half intensity mode **/
if (!_sethalfbright)
return(-1);
tputs(_sethalfbright, 1, outchar);
fflush(stdout);
return(0);
}
EndHalfbright()
{
/** compliment of starthalfbright **/
if (!_clearhalfbright)
return(-1);
tputs(_clearhalfbright, 1, outchar);
fflush(stdout);
return(0);
}
StartInverse()
{
/** set inverse video mode **/
if (!_setinverse)
return(-1);
tputs(_setinverse, 1, outchar);
fflush(stdout);
return(0);
}
EndInverse()
{
/** compliment of startinverse **/
if (!_clearinverse)
return(-1);
tputs(_clearinverse, 1, outchar);
fflush(stdout);
return(0);
}
PutLine0(x, y, line)
int x,y;
char *line;
{
/** Write a zero argument line at location x,y **/
_line = x;
_col = y;
#ifdef UTS
if (isatube) {
panel (erase=_clear_screen, cursor=_line, _col) {
#ON, line, strlen(line)-1#
}
_clear_screen = 0;
_col += (printable_chars(line) - 1);
return(0);
}
#endif
MoveCursor(x,y);
printf("%s", line); /* to avoid '%' problems */
fflush(stdout);
_col += (printable_chars(line) - 1);
}
PutLine1(x,y, line, arg1)
int x,y;
char *line;
char *arg1;
{
/** write line at location x,y - one argument... **/
char buffer[SLEN];
sprintf(buffer, line, arg1);
PutLine0(x, y, buffer);
}
PutLine2(x,y, line, arg1, arg2)
int x,y;
char *line;
char *arg1, *arg2;
{
/** write line at location x,y - one argument... **/
char buffer[SLEN];
sprintf(buffer, line, arg1, arg2);
PutLine0(x, y, buffer);
}
PutLine3(x,y, line, arg1, arg2, arg3)
int x,y;
char *line;
char *arg1, *arg2, *arg3;
{
/** write line at location x,y - one argument... **/
char buffer[SLEN];
sprintf(buffer, line, arg1, arg2, arg3);
PutLine0(x, y, buffer);
}
CleartoEOLN()
{
/** clear to end of line **/
#ifdef UTS
char buffer[SLEN];
register int cols, i = 0;
if (isatube) {
for (cols = _col; cols < COLUMNS; cols++)
buffer[i++] = ' ';
buffer[i] = '\0';
panel (noerase, cursor=_line, _col) {
#ON, buffer, strlen(buffer)-1#
}
}
#endif
if (!_cleartoeoln)
return(-1);
tputs(_cleartoeoln, 1, outchar);
fflush(stdout); /* clear the output buffer */
return(0);
}
CleartoEOS()
{
/** clear to end of screen **/
#ifdef UTS
register int line_at;
for (line_at = _line; line_at < LINES-1; line_at++) {
panel (noerase) {
#ON, _null_string, COLUMNS#
}
}
return(0);
#endif
if (!_cleartoeos)
return(-1);
tputs(_cleartoeos, 1, outchar);
fflush(stdout); /* clear the output buffer */
return(0);
}
#ifdef RAWMODE
Raw(state)
int state;
{
/** state is either ON or OFF, as indicated by call **/
if (state == OFF && _inraw) {
#ifdef BSD
echo();
nocrmode();
#else
(void) ioctl(TTYIN, TCSETAW, &_original_tty);
#endif
_inraw = 0;
}
else if (state == ON && ! _inraw) {
#ifdef BSD
noecho();
crmode();
#else
(void) ioctl(TTYIN, TCGETA, &_original_tty); /** current setting **/
(void) ioctl(TTYIN, TCGETA, &_raw_tty); /** again! **/
_raw_tty.c_iflag &= ~(INLCR | ICRNL |BRKINT);
_raw_tty.c_iflag |= IXON;
_raw_tty.c_oflag |= OPOST;
_raw_tty.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
_raw_tty.c_lflag &= ~(ICANON | ECHO);
_raw_tty.c_cc[VMIN] = '\01';
_raw_tty.c_cc[VTIME] = '\0';
(void) ioctl(TTYIN, TCSETAW, &_raw_tty);
#endif
_inraw = 1;
}
}
int
ReadCh()
{
/** read a character with Raw mode set! **/
register int result;
char ch;
result = read(0, &ch, 1);
return(result == 0? EOF : ch);
}
#endif
outchar(c)
char c;
{
/** output the given character. From tputs... **/
/** Note: this CANNOT be a macro! **/
putc(c, stdout);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 11832 ]
then
echo $filename changed - should be 11832 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/initialize.uts ----------
filename="src/initialize.uts"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/initialize.uts...
fi
sed 's/^X//' << 'END-OF-FILE' > $filename
XFrom hpccc!mcgregor at hplabs.ARPA Fri May 9 16:05:10 1986
XReceived: from hplabs.ARPA by hpldat ; Fri, 9 May 86 16:05:01 pdt
XMessage-Id: <8605092305.AA00689 at hpldat>
XReceived: by hplabs.ARPA ; Fri, 9 May 86 16:01:29 pdt
XFrom: Scott McGregor <hpccc!mcgregor at hplabs.ARPA>
XTo: taylor at hplabs
XDate: Fri, 9 May 86 15:23:16 PDT
XSubject: initialize.c
XX-Mailer: msg [version 3.3a]
X
X/** initialize.c **/
X
X/***** Initialize - read in all the defaults etc etc
X (C) Copyright 1985 Dave Taylor
X*****/
X
X#include "headers.h"
X
X#ifdef BSD
X# include <sgtty.h>
X#else
X# include <termio.h>
X#endif
X
X#include <pwd.h>
X
X#ifdef BSD
X# include <sys/time.h>
X#else
X# include <time.h>
X#endif
X
X#include <signal.h>
X#include <ctype.h>
X#include <errno.h>
X
X#ifdef BSD
X#undef tolower
X#endif
X
X
Xextern int errno; /* system error number on failure */
X
Xchar *error_name(), *error_description();
X
Xchar *expand_logname(), *getenv(), *getlogin();
X
Xinitialize(InitScreen_to)
Xint InitScreen_to;
X{
X struct passwd *pass, *getpwnam();
X
X register int i;
X int quit_signal(), term_signal(), ill_signal(),
X fpe_signal(), bus_signal(), segv_signal(),
X alarm_signal();
X char buffer[SLEN], *cp;
X
X userid = getuid();
X groupid = getgid();
X
X strcpy(home,((cp = getenv("HOME")) == NULL)? "" : cp);
X strcpy(shell,((cp = getenv("SHELL")) == NULL)? "" : cp);
X
X if (debug) { /* setup for dprintf statements! */
X char filename[SLEN];
X sprintf(filename, "%s/%s", home, DEBUG);
X if ((debugfile = fopen(filename, "w")) == NULL) {
X debug = 0; /* otherwise 'leave' will try to log! */
X leave(fprintf(stderr,"Could not open file %s for debug output!\n",
X filename));
X }
X if (InitScreen_to) {
X InitScreen();
X }
X chown(filename, userid, groupid); /* file owned by user */
X
X fprintf(debugfile, "Debug output of the MSG program. Version %s\n\n",
X VERSION);
X }
X#ifndef UTS
X signal(SIGINT, SIG_IGN);
X signal(SIGQUIT, quit_signal); /* Quit signal */
X signal(SIGTERM, term_signal); /* Terminate signal */
X signal(SIGILL, ill_signal); /* Illegal instruction */
X signal(SIGFPE, fpe_signal); /* Floating point exception */
X signal(SIGBUS, bus_signal); /* Bus error */
X signal(SIGSEGV, segv_signal); /* Segmentation Violation */
X#endif
X signal(SIGALRM, alarm_signal); /* Process Timer Alarm */
X
X if (isa3270()) {
X isatube++;
X dprint0(1, "** We're using a 3270 tube!! **\n");
X }
X
X#ifndef UTS
X get_connections(); /* who do we talk to directly?? */
X#endif
X open_domain_file(); /* if we got it, we want it! */
X
X get_term_chars();
X
X gethostname(hostname, sizeof(hostname));
X if ((cp = getlogin()) == NULL)
X cuserid(username);
X else
X strcpy(username, cp);
X
X /* now let's get the full username.. */
X
X if ((pass = getpwnam(username)) == NULL) {
X error("Couldn't read password entry??");
X strcpy(full_username, username);
X }
X else {
X for (i=0; pass->pw_gecos[i] != '\0' && pass->pw_gecos[i] != ',';
X i++)
X if (pass->pw_gecos[i] == '&') {
X full_username[i] = '\0';
X strcat(full_username, expand_logname());
X i = strlen(full_username) - 2;
X }
X else
X full_username[i] = pass->pw_gecos[i];
X full_username[i] = '\0';
X }
X
X if ((cp = getenv("EDITOR")) == NULL)
X strcpy(editor,default_editor);
X else
X strcpy(editor, cp);
X
X if (! mail_only) {
X mailbox[0] = '\0';
X strcpy(prefixchars, "> "); /* default message prefix */
X }
X
X read_rc_file(); /* reading the .msgrc next... */
X
X /** now try to expand the specified filename... **/
X
X if (strlen(infile) > 0) {
X (void) expand_filename(infile);
X if ((errno = can_access(infile, READ_ACCESS))) {
X dprint2(1,"Error: given file %s as mailbox - unreadable (%s)!\n",
X infile, error_name(errno));
X fprintf(stderr,"Can't open mailbox '%s' for reading!\n", infile);
X exit(1);
X }
X }
X
X /** check to see if the user has defined a LINES or COLUMNS
X value different to that in the termcap entry (for
X windowing systems, of course!) **/
X
X if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
X sscanf(cp, "%d", &LINES);
X LINES -= 1; /* kludge for HP Window system? ... */
X }
X
X if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
X sscanf(cp, "%d", &COLUMNS);
X
X /** fix the shell if needed **/
X
X if (shell[0] != '/') {
X sprintf(buffer, "/bin/%s", shell);
X strcpy(shell, buffer);
X }
X
X if (! mail_only) {
X mailbox_defined = (mailbox[0] != '\0');
X
X /* get the cursor control keys... */
X
X if ((cp = return_value_of("ku")) == NULL || strlen(cp) != 2)
X cursor_control = FALSE;
X else {
X strcpy(up, cp);
X if ((cp = return_value_of("kd")) == NULL || strlen(cp) != 2)
X cursor_control = FALSE;
X else {
X strcpy(down, cp);
X cursor_control = TRUE;
X transmit_functions(ON);
X }
X }
X
X strcpy(start_highlight, "->");
X end_highlight[0] = '\0';
X
X if (!arrow_cursor) { /* try to use inverse bar instead */
X if ((cp = return_value_of("so")) != NULL) {
X strcpy(start_highlight, cp);
X if ((cp = return_value_of("se")) == NULL)
X strcpy(start_highlight, "->");
X else {
X strcpy(end_highlight, cp);
X has_highlighting = TRUE;
X }
X }
X }
X }
X
X if (read_aliases)
X read_alias_files();
X
X if (! mail_only) {
X if (mini_menu)
X headers_per_page = LINES - 13;
X else
X headers_per_page = LINES - 8; /* 5 more headers! */
X
X newmbox(1,FALSE, TRUE); /* read in the mailbox! */
X }
X
X init_findnode(); /* set up the path alias stuff */
X
X dprint0(2,"\n-- end of initialization phase --\n");
X
X dprint3(2,"\thostname = %s\n\tusername = %s\n\tfull_username = \"%s\"\n",
X hostname, username, full_username);
X
X dprint3(2,"\thome = %s\n\teditor = %s\n\tmailbox = %s\n",
X home, editor, mailbox);
X
X dprint3(2,"\tinfile = %s\n\tfolder-dir = %s\n\tprintout = \"%s\"\n",
X infile, folders, printout);
X
X dprint3(2,"\tsavefile = %s\n\tprefix = \"%s\"\n\tshell = %s\n",
X savefile, prefixchars, shell);
X
X dprint0(1,"-- beginning execution phase --\n\n");
X}
X
Xget_term_chars()
X{
X /** This routine sucks out the special terminal characters
X ERASE and KILL for use in the input routine. The meaning
X of the characters are (dare I say it?) fairly obvious... **/
X
X#ifdef BSD
X struct sgttyb term_buffer;
X
X# define TCGETA TIOCGETP
X
X#else
X struct termio term_buffer;
X#endif
X
X if (ioctl(STANDARD_INPUT, TCGETA, &term_buffer) == -1) {
X dprint1(1,"Error: %s encountered on ioctl call (get_term_chars)\n",
X error_name(errno));
X /* set to defaults for terminal driver */
X backspace = BACKSPACE;
X kill_line = ctrl('U');
X }
X else {
X#ifdef BSD
X backspace = term_buffer.sg_erase;
X kill_line = term_buffer.sg_kill;
X#else
X backspace = term_buffer.c_cc[VERASE];
X kill_line = term_buffer.c_cc[VKILL];
X#endif
X }
X}
X
Xchar *expand_logname()
X{
X /** Return logname in a nice format (for expanding "&" in the
X /etc/passwd file) **/
X
X static char buffer[SLEN];
X register int i;
X
X if (strlen(username) == 0)
X buffer[0] = '\0';
X else {
X buffer[0] = toupper(username[0]);
X
X for (i=1; username[i] != '\0'; i++)
X buffer[i] = tolower(username[i]);
X
X buffer[i] = '\0';
X }
X
X return( (char *) buffer);
X}
X
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 7197 ]
then
echo $filename changed - should be 7197 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file src/edit.c ----------
filename="src/edit.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/edit.c...
fi
cat << 'END-OF-FILE' > $filename
/** edit.c **/
/** This routine is for allowing the user to edit their current mailbox
as they wish.
(C) Copyright 1986 Dave Taylor
**/
#include "headers.h"
#include <errno.h>
extern int errno;
char *error_name(), *error_description();
edit_mailbox()
{
/** Allow the user to edit their mailbox, always resynchronizing
afterwards. Due to intense laziness on the part of the
programmer, this routine will invoke $EDITOR on the entire
file. The mailer will ALWAYS resync on the mailbox file
even if nothing has changed since, not unreasonably, it's
hard to figure out what occurred in the edit session...
Also note that if the user wants to edit their incoming
mailbox they'll actually be editing the tempfile that is
an exact copy. More on how we resync in that case later
in this code.
**/
FILE *real_mailbox, *temp_mailbox;
char filename[SLEN], buffer[LONG_SLEN], temp_infile[SLEN];
PutLine0(LINES-1,0,"invoking editor...");
if (mbox_specified == 0)
sprintf(filename, "%s%s", temp_mbox, username);
else
strcpy(filename, infile);
sprintf(buffer, "%s %s", editor, filename);
Raw(OFF);
if (system_call(buffer, SH) != 0) {
error1("Problems invoking editor %s!", editor);
Raw(ON);
sleep(2);
return(0);
}
Raw(ON);
if (mbox_specified == 0) { /* uh oh... now the toughie... */
sprintf(temp_infile, "%s%s.temp", mailhome, username);
unlink(temp_infile); /* remove it if it's there... */
if (bytes(infile) != mailfile_size) {
/* SIGH. We've received mail since we invoked the editor
on the mailbox. We'll have to do some strange stuff to
remedy the problem... */
PutLine0(LINES, 0, "Warning: new mail received...");
CleartoEOLN();
if ((temp_mailbox = fopen(filename, "a")) == NULL) {
dprint2(1, "Attempt to open %s to append failed! (%s)\n",
filename, "edit_mailbox");
set_error("Couldn't reopen tempfile. Edit LOST!");
return(1);
}
/** Now let's lock the mailbox up and stream the new stuff
into the temp file... **/
lock();
if ((real_mailbox = fopen(infile, "r")) == NULL) {
dprint2(1,
"Attempt to open %s for reading new mail failed! (%s)\n",
infile, "edit_mailbox");
sprintf(buffer, "Couldn't open %s for reading! Edit LOST!",
infile);
set_error(buffer);
unlock();
return(1);
}
if (fseek(real_mailbox, mailfile_size, 0) != 0) {
dprint2(1, "Couldn't seek to end of infile (offset %ld) (%s)\n",
mailfile_size, "edit_mailbox");
set_error("Couldn't seek to end of mailbox. Edit LOST!");
unlock();
return(1);
}
/** Now we can finally stream the new mail into the tempfile **/
while (fgets(buffer, LONG_SLEN, real_mailbox) != NULL)
fprintf(temp_mailbox, "%s", buffer);
fclose(real_mailbox);
fclose(temp_mailbox);
}
else
lock(); /* create a lock file if we're replacing mailbox */
/** link to the temporary mailbox in the mailhome directory... **/
if (link(filename, temp_infile) != 0)
if (errno == EXDEV) { /* attempt to link across file systems */
if (copy(filename, temp_infile) != 0) {
error("Couldn't copy temp file to mailbox!");
emergency_exit();
}
}
else {
Write_to_screen("\n\rCouldn't link %s to mailfile %s...\n\r",2,
filename, temp_infile);
Write_to_screen("** %s - %s **\n\r", 2,
error_name(errno), error_description(errno));
emergency_exit();
}
/*** G U L P ... let's remove the incoming mail file... ***/
unlink(infile);
/** and quickly now... **/
if (link(temp_infile, infile) != 0) {
Write_to_screen(
"\n\rCouldn't internally link %s to mailfile %s...\n\r",
2, temp_infile, infile);
Write_to_screen(
"\n\rYou'll need to check out %s for your mail...\n\r",
1, temp_infile);
Write_to_screen("** %s - %s **\n\r", 2,
error_name(errno), error_description(errno));
emergency_exit();
}
/** And let's remove the lock file! We're DONE!!! **/
unlock();
unlink(temp_infile); /* remove the temp file too */
error("edit changes incorporated into new mail...");
}
else
error("Resynchronizing with new version of mailbox...");
sleep(2);
resync();
return(1);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 4451 ]
then
echo $filename changed - should be 4451 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/errno.c ----------
filename="src/errno.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/errno.c...
fi
cat << 'END-OF-FILE' > $filename
/** errno.c **/
/** This routine maps error numbers to error names and error messages.
These are all directly ripped out of the include file errno.h, and
are HOPEFULLY standardized across the different breeds of Unix!!
If (alas) yours are different, you should be able to use awk to
mangle your errno.h file quite simply...
(C) Copyright 1986 Dave Taylor
**/
#include "headers.h"
char *err_name[] = {
/* 0 */ "NOERROR", "No error status currently",
/* 1 */ "EPERM", "Not super-user",
/* 2 */ "ENOENT", "No such file or directory",
/* 3 */ "ESRCH", "No such process",
/* 4 */ "EINTR", "Interrupted system call",
/* 5 */ "EIO", "I/O error",
/* 6 */ "ENXIO", "No such device or address",
/* 7 */ "E2BIG", "Arg list too long",
/* 8 */ "ENOEXEC", "Exec format error",
/* 9 */ "EBADF", "Bad file number",
/* 10 */ "ECHILD", "No children",
/* 11 */ "EAGAIN", "No more processes",
/* 12 */ "ENOMEM", "Not enough core",
/* 13 */ "EACCES", "Permission denied",
/* 14 */ "EFAULT", "Bad address",
/* 15 */ "ENOTBLK", "Block device required",
/* 16 */ "EBUSY", "Mount device busy",
/* 17 */ "EEXIST", "File exists",
/* 18 */ "EXDEV", "Cross-device link",
/* 19 */ "ENODEV", "No such device",
/* 20 */ "ENOTDIR", "Not a directory",
/* 21 */ "EISDIR", "Is a directory",
/* 22 */ "EINVAL", "Invalid argument",
/* 23 */ "ENFILE", "File table overflow",
/* 24 */ "EMFILE", "Too many open files",
/* 25 */ "ENOTTY", "Not a typewriter",
/* 26 */ "ETXTBSY", "Text file busy",
/* 27 */ "EFBIG", "File too large",
/* 28 */ "ENOSPC", "No space left on device",
/* 29 */ "ESPIPE", "Illegal seek",
/* 30 */ "EROFS", "Read only file system",
/* 31 */ "EMLINK", "Too many links",
/* 32 */ "EPIPE", "Broken pipe",
/* 33 */ "EDOM", "Math arg out of domain of func",
/* 34 */ "ERANGE", "Math result not representable",
/* 35 */ "ENOMSG", "No message of desired type",
/* 36 */ "EIDRM", "Identifier removed"
};
char *error_name(errnumber)
int errnumber;
{
static char buffer[50];
dprint1(1,"Error Name called with error %d\n", errnumber);
if (errnumber < 0 || errnumber > 36)
sprintf(buffer,"ERR-UNKNOWN (%d)", errnumber);
else
strcpy(buffer, err_name[2*errnumber]);
return( (char *) buffer);
}
char *error_description(errnumber)
int errnumber;
{
static char buffer[50];
dprint1(1,"Error Description called with error %d\n", errnumber);
if (errnumber < 0 || errnumber > 36)
sprintf(buffer,"Unknown error - %d - No description", errnumber);
else
strcpy(buffer, err_name[2*errnumber + 1]);
return ( (char *) buffer);
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 2612 ]
then
echo $filename changed - should be 2612 bytes, not $size bytes
fi
chmod 644 $filename
fi
# ---------- file src/sort.c ----------
filename="src/sort.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/sort.c...
fi
cat << 'END-OF-FILE' > $filename
/** sort.c **/
/** Sort mailbox header table by the field specified in the global
variable "sortby"...if we're sorting by something other than
the default SENT_DATE, also put some sort of indicator on the
screen.
(C) Copyright 1986, Dave Taylor
**/
#include "headers.h"
char *sort_name();
sort_mailbox(entries, visible)
int entries, visible;
{
/** Sort the header_table definitions... If 'visible', then
put the status lines etc **/
int last_index = -1;
int compare_headers(); /* for sorting */
dprint1(2,"\n** sorting mailbox by %s **\n\n", sort_name(FALSE));
if (entries > 0)
last_index = header_table[current-1].index_number;
if (entries > 30 && visible)
error1("sorting messages by %s", sort_name(FALSE));
qsort(header_table, entries, sizeof (struct header_rec),
compare_headers);
if (last_index > -1)
find_old_current(last_index);
clear_error();
}
int
compare_headers(first, second)
struct header_rec *first, *second;
{
/** compare two headers according to the sortby value.
Sent Date uses a routine to compare two dates,
Received date is keyed on the file offsets (think about it)
Sender uses the truncated from line, same as "build headers",
and size and subject are trivially obvious!!
**/
char from1[SLEN], from2[SLEN]; /* sorting buffers... */
int sign = 1;
if (sortby < 0)
sign = -1;
switch (abs(sortby)) {
case SENT_DATE : return( sign*compare_dates(first, second) );
case RECEIVED_DATE: return (
sign*(first->index_number - second->index_number) );
case SENDER : tail_of(first->from, from1, TRUE);
tail_of(second->from, from2, TRUE);
return( sign*strcmp(from1, from2));
case SIZE : return( sign*(first->lines - second->lines));
case SUBJECT : return( sign*strcmp(first->subject,second->subject));
case STATUS : return( sign*(first->status - second->status));
}
}
char *sort_name(pad)
int pad;
{
/** return the name of the current sort option...
If 'pad' is set, then ensure all are the same length by
using trailing spaces...
**/
if (sortby < 0) {
switch (- sortby) {
case SENT_DATE : return(
pad? "Reverse Date Mail Sent " :
"Reverse Date Mail Sent");
case RECEIVED_DATE: return("Reverse Date Mail Rec'vd");
case SENDER : return(
pad? "Reverse Message Sender " :
"Reverse Message Sender");
case SIZE : return("Reverse Lines in Message");
case SUBJECT : return(
pad? "Reverse Message Subject " :
"Reverse Message Subject");
case STATUS : return(
pad? "Reverse Message Status " :
"Reverse Message Status");
}
}
else {
switch (sortby) {
case SENT_DATE : return(
pad? "Date Mail Sent " :
"Date Mail Sent");
case RECEIVED_DATE: return(
pad? "Date Mail Rec'vd " :
"Date Mail Rec'vd");
case SENDER : return(
pad? "Message Sender " :
"Message Sender");
case SIZE : return(
pad? "Lines in Message " :
"Lines in Message");
case SUBJECT : return(
pad? "Message Subject " :
"Message Subject");
case STATUS : return(
pad? "Message Status " :
"Message Status");
}
}
return("*UNKNOWN-SORT-PARAMETER*");
}
find_old_current(index)
int index;
{
/** Set current to the message that has "index" as it's
index number. This is to track the current message
when we resync... **/
register int i;
dprint1(2,"find-old-current(%d)\n", index);
for (i = 0; i < message_count; i++)
if (header_table[i].index_number == index) {
current = i+1;
dprint1(2,"\tset current to %d!\n", current);
return;
}
dprint1(2,"\tcouldn't find current index. Current left as %d\n",
current);
return; /* can't be found. Leave it alone, then */
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 4136 ]
then
echo $filename changed - should be 4136 bytes, not $size bytes
fi
chmod 666 $filename
fi
# ---------- file src/showmsg_cmd.c ----------
filename="src/showmsg_cmd.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/showmsg_cmd.c...
fi
cat << 'END-OF-FILE' > $filename
/** showmsg_cmd.c **/
/** This is an interface for the showmsg command line. The possible
functions that could be invoked from the showmsg command line are
almost as numerous as those from the main command line and include
the following;
| = pipe this message to command...
! = call Unix command
< = scan message for calendar info
b = bounce (remail) message
d = mark message for deletion
e = edit entire mailbox
f = forward message
g = group reply
j,n = move to body of next message
k = move to body of previous message
p = print this (all tagged) message
r = reply to this message
s = save this message to a maibox/folder
t = tag this message
x = Exit Elm NOW
all commands not explicitly listed here are returned as unprocessed
to be dealt with at the main command level.
This function returns 0 if it dealt with the command, or the command
otherwise.
**/
#include "headers.h"
process_showmsg_command(command)
char command;
{
switch (command) {
case '|' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: pipe");
softkeys_off();
(void) pipe(); /* do pipe regardless */
softkeys_on();
return(0); /* must have new screen */
case '!' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: system call");
softkeys_off();
(void) subshell(); /* do shell regardless */
softkeys_on();
return(0); /* must have new screen */
case '<' :
#ifdef ENABLE_CALENDAR
scan_calendar();
#else
error("can't scan for calendar entries!");
#endif
break;
case 'b' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: bounce message");
remail();
return(0); /* must have new screen */
case 'd' : delete(TRUE);
break;
case 'e' : edit_mailbox();
return(0); /* must have new screen */
case 'f' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: forward message");
(void) forward();
return(0); /* must have new screen */
case 'g' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: group reply");
(void) reply_to_everyone();
return(0); /* must have new screen */
case 'j' :
case 'n' : if (current < message_count)
show_msg(++current);
return(0);
case 'k' : if (current > 0)
show_msg(--current);
return(0);
case 'p' : printmsg();
break;
case 'r' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: reply to message");
(void) reply();
return(0); /* must have new screen */
case 's' : clear_bottom_of_screen();
PutLine0(LINES-3,0,"Command: save message");
(void) save();
break;
case 't' : tag_message();
break;
case 'x' : leave();
case '\n':
case '\r': return(0); /* avoid <return> looping */
default : return(command); /* couldn't deal with it! */
}
return(1); /* done with it! */
}
clear_bottom_of_screen()
{
/** clear the last 4 lines of the screen... **/
MoveCursor(LINES-4, 0);
CleartoEOS();
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 3188 ]
then
echo $filename changed - should be 3188 bytes, not $size bytes
fi
chmod 666 $filename
fi
echo end of this archive file....
exit 0
More information about the Mod.sources
mailing list