syd@dsinc.UUCP (Syd Weinstein) (12/14/88)
---- Cut Here and unpack ----
#!/bin/sh
# this is part 18 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/screen.c continued
#
CurArch=18
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file src/screen.c"
sed 's/^X//' << 'SHAR_EOF' >> src/screen.c
X return(FALSE);
X
X /** compute last header to display **/
X
X this_msg = header_page * headers_per_page;
X last = this_msg + (headers_per_page - 1);
X }
X
X if (last >= message_count) last = message_count-1;
X
X /** Okay, now let's show the header page! **/
X
X ClearLine(line); /* Clear the top line... */
X
X MoveCursor(line, 0); /* and move back to the top of the page... */
X
X while ((selected && displayed < last) || this_msg <= last) {
X tail_of(header_table[this_msg].from, newfrom, TRUE);
X
X if (selected) {
X if (this_msg == current-1)
X build_header_line(buffer, &header_table[this_msg], ++displayed,
X TRUE, newfrom);
X else
X build_header_line(buffer, &header_table[this_msg],
X ++displayed, FALSE, newfrom);
X }
X else {
X if (this_msg == current-1)
X build_header_line(buffer, &header_table[this_msg], this_msg+1,
X TRUE, newfrom);
X else
X build_header_line(buffer, &header_table[this_msg],
X this_msg+1, FALSE, newfrom);
X }
X
X if (this_msg == current-1 && has_highlighting && ! arrow_cursor) {
X StartInverse();
X Write_to_screen("%s\r\n", 1, buffer); /* avoid '%' probs */
X EndInverse();
X } else
X Write_to_screen("%s\r\n", 1, buffer); /* avoid '%' probs */
X CleartoEOLN();
X line++; /* for clearing up in a sec... */
X
X if (selected) {
X if ((this_msg = next_visible(this_msg+1)-1) < 0)
X break; /* GET OUTTA HERE! */
X
X /* the preceeding looks gross because we're using an INDEX
X variable to pretend to be a "current" counter, and the
X current counter is always 1 greater than the actual
X index. Does that make sense??
X */
X }
X else
X this_msg++; /* even dumber... */
X }
X
X if (mini_menu)
X last_line = LINES-8;
X else
X last_line = LINES-4;
X
X while (line < last_line) {
X CleartoEOLN();
X Writechar('\r');
X Writechar('\n');
X line++;
X }
X
X display_central_message();
X
X last_current = current;
X last_header_page = header_page;
X
X return(TRUE);
X}
X
Xshow_current()
X{
X /** Show the new header, with all the usual checks **/
X
X register int first = 0, last = 0, last_line, new_line, i=0, j=0;
X char newfrom[SLEN], old_buffer[SLEN], new_buffer[SLEN];
X
X (void) fix_header_page(); /* Who cares what it does? ;-) */
X
X /** compute last header to display **/
X
X first = header_page * headers_per_page;
X last = first + (headers_per_page - 1);
X
X if (last > message_count)
X last = message_count;
X
X /** okay, now let's show the pointers... **/
X
X /** have we changed??? **/
X
X if (current == last_current)
X return;
X
X if (selected) {
X last_line = ((i=compute_visible(last_current-1)-1) %
X headers_per_page)+4;
X new_line = ((j=compute_visible(current-1)-1) % headers_per_page)+4;
X }
X else {
X last_line = ((last_current-1) % headers_per_page)+4;
X new_line = ((current-1) % headers_per_page)+4;
X }
X
X if (has_highlighting && ! arrow_cursor) {
X /** build the old and new header lines... **/
X
X tail_of(header_table[current-1].from, newfrom, TRUE);
X build_header_line(new_buffer, &header_table[current-1],
X (selected? compute_visible(current-1) : current),
X TRUE, newfrom);
X
X if (last_current > 0 &&
X (last_current-1 <= last && last_current >= first)) {
X
X dprint(5, (debugfile,
X "\nlast_current = %d ... clearing [1] before we add [2]\n",
X last_current));
X dprint(5, (debugfile, "first = %d, and last = %d\n\n",
X first, last));
X
X tail_of(header_table[last_current-1].from, newfrom, TRUE);
X build_header_line(old_buffer, &header_table[last_current-1],
X (selected? compute_visible(last_current-1) : last_current),
X FALSE, newfrom);
X
X ClearLine(last_line);
X PutLine0(last_line, 0, old_buffer);
X }
X MoveCursor(new_line, 0);
X StartInverse();
X Write_to_screen("%s", 1, new_buffer);
X EndInverse();
X }
X else {
X if (on_page(last_current))
X PutLine0(last_line,0," "); /* remove old pointer... */
X if (on_page(current))
X PutLine0(new_line, 0,"->");
X }
X
X last_current = current;
X}
X
Xbuild_header_line(buffer, entry, message_number, highlight, from)
Xchar *buffer;
Xstruct header_rec *entry;
Xint message_number, highlight;
Xchar *from;
X{
X /** Build in buffer the message header ... entry is the current
X message entry, 'from' is a modified (displayable) from line,
X 'highlight' is either TRUE or FALSE, and 'message_number'
X is the number of the message.
X **/
X
X /** Note: using 'strncpy' allows us to output as much of the
X subject line as possible given the dimensions of the screen.
X The key is that 'strncpy' returns a 'char *' to the string
X that it is handing to the dummy variable! Neat, eh? **/
X
X char subj[LONG_SLEN]; /* to output subject */
X
X strncpy(subj, entry->subject, COLUMNS-44);
X
X subj[COLUMNS-45] = '\0'; /* insurance, eh? */
X
X /* now THIS is a frightening format statement!!! */
X
X sprintf(buffer, "%s%s%c%-3d %3.3s %-2d %-18.18s (%d) %s%s",
X (highlight && arrow_cursor)? "->" : " ",
X show_status(entry->status),
X (entry->status & TAGGED? '+' : ' '),
X message_number,
X entry->month,
X atoi(entry->day),
X from,
X entry->lines,
X (entry->lines / 1000 > 0? "" : /* spacing the */
X entry->lines / 100 > 0? " " : /* same for the */
X entry->lines / 10 > 0? " " : /* lines in () */
X " "), /* [wierd] */
X subj);
X}
X
Xint
Xfix_header_page()
X{
X /** this routine will check and ensure that the current header
X page being displayed contains messages! It will silently
X fix 'header-page' if wrong. Returns TRUE if changed. **/
X
X int last_page, old_header;
X
X old_header = header_page;
X
X last_page = (int) ((message_count-1) / headers_per_page);
X
X if (header_page > last_page)
X header_page = last_page;
X else if (header_page < 0)
X header_page = 0;
X
X return(old_header != header_page);
X}
X
Xint
Xon_page(message)
Xint message;
X{
X /** Returns true iff the specified message is on the displayed page. **/
X
X if (selected) message = compute_visible(message-1);
X
X if (message >= header_page * headers_per_page)
X if (message <= ((header_page+1) * headers_per_page))
X return(TRUE);
X
X return(FALSE);
X}
X
Xchar *show_status(status)
Xint status;
X{
X /** This routine returns a pair of characters indicative of
X the status of this message. The first character represents
X the interim status of the message (e.g. the status within
X the mail system):
X
X E = Expired message
X N = New message
X D = Deleted message
X _ = (space) default
X
X and the second represents the permanent attributes of the
X message:
X
X C = Company Confidential message
X U = Urgent (or Priority) message
X P = Private message
X A = Action associated with message
X F = Form letter
X _ = (space) default
X **/
X
X static char mybuffer[3];
X
X /** the first character, please **/
X
X if (status & DELETED) mybuffer[0] = 'D';
X else if (status & EXPIRED) mybuffer[0] = 'E';
X else if (status & NEW) mybuffer[0] = 'N';
X else mybuffer[0] = ' ';
X
X /** and the second... **/
X
X if (status & CONFIDENTIAL) mybuffer[1] = 'C';
X else if (status & URGENT) mybuffer[1] = 'U';
X else if (status & PRIVATE) mybuffer[1] = 'P';
X else if (status & ACTION) mybuffer[1] = 'A';
X else if (status & FORM_LETTER) mybuffer[1] = 'F';
X else mybuffer[1] = ' ';
X
X mybuffer[2] = '\0';
X
X return( (char *) mybuffer);
X}
SHAR_EOF
echo "File src/screen.c is complete"
chmod 0444 src/screen.c || echo "restore of src/screen.c fails"
echo "x - extracting src/showmsg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/showmsg.c &&
X
Xstatic char rcsid[] = "@(#)$Id: showmsg.c,v 2.1.1.2 88/09/23 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: showmsg.c,v $
X * Revision 2.1 88/09/15 20:29:43 syd
X * checked in with -k by syd at 88.09.15.20.29.43.
X *
X * 88/08/27 ssw
X * add deluth patches
X *
X * Revision 2.1 88/07/21 09:59:34 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:36 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This file contains all the routines needed to display the specified
X message.
X
X
X Modified 6/86 to use pager variable!!! Hurrah!!!!
X Modified 7/86 to have secure pipes.. *sigh*
X and again 10/87 to do more interesting things with the screen w.r.t.
X end of message prompting and so on...
X**/
X
X#include "headers.h"
X#include <ctype.h>
X#include <errno.h>
X#include <signal.h>
X
X#ifdef BSD
X# include <sys/wait.h>
X# undef tolower
X#endif
X
Xextern int errno;
X
Xchar *error_name(), *strcat(), *strcpy();
Xvoid _exit();
X
Xint memory_lock = FALSE; /* is it available?? */
Xint pipe_abort = FALSE; /* did we receive a SIGNAL(SIGPIPE)? */
X
Xextern int lines_displayed, /* defined in "builtin" */
X lines_put_on_screen; /* ditto too! */
X
Xint
Xshow_msg(number)
Xint number;
X{
X /*** display number'th message. Get starting and ending lines
X of message from headers data structure, then fly through
X the file, displaying only those lines that are between the
X two!
X Returns non-zero iff the screen was changed, or the
X character pressed at the 'end-of-screen' prompt (to be
X processed via process_showmsg_cmd()).
X ***/
X
X dprint(8, (debugfile, "show_msg called\n"));
X
X if (number > message_count) {
X error1("Only %d messages!", message_count);
X return(0);
X }
X else if (number < 1) {
X error("you can't read THAT message!");
X return(0);
X }
X
X clearit(header_table[number-1].status, NEW); /* it's been read now! */
X
X memory_lock = FALSE;
X
X /* some explanation for that last one - We COULD use memory locking
X to speed up the paging, but the action of "ClearScreen" on a screen
X with memory lock turned on seems to vary considerably (amazingly so)
X so it's safer to only allow memory lock to be a viable bit of
X trickery when dumping text to the screen in scroll mode.
X Philosophical arguments should be forwarded to Bruce at the
X University of Walamazoo, Australia, via ACSNet *wry chuckle* */
X
X return(show_message(header_table[number-1].lines,
X header_table[number-1].offset,number));
X}
X
Xint
Xshow_message(lines, file_loc, msgnumber)
Xint lines, msgnumber;
Xlong file_loc;
X{
X /*** Show the indicated range of lines from mailfile
X for message 'msgnumber' by using 'display'
X Returns non-zero iff screen was altered, or the char
X pressed (see previous routine header comment).
X ***/
X int retval;
X
X dprint(9, (debugfile, "show_message(%d,%ld,%d)\n",
X lines, file_loc, msgnumber));
X
X if (fseek(mailfile, file_loc, 0) == -1) {
X dprint(1, (debugfile,
X "Error: seek %d bytes into file, errno %s (show_message)\n",
X file_loc, error_name(errno)));
X error2("ELM failed seeking %d bytes into file (%s)",
X file_loc, error_name(errno));
X return(0);
X }
X
X if (feof(mailfile))
X dprint(1, (debugfile, "\n*** seek put us at END OF FILE!!! ***\n"));
X
X
X /* next read will get 'this' line so must be at end of previous */
X
X if (first_word(pager,"builtin") || first_word(pager,"internal"))
X retval = display(lines, msgnumber);
X else
X retval = secure_display(lines, msgnumber);
X
X if (memory_lock) EndMemlock(); /* turn it off!! */
X
X return(retval == 0? 1 : retval); /* we did it boss! */
X}
X
X
X/** This next one is the 'pipe' file descriptor for writing to the
X pager process... **/
X
XFILE *output_pipe, *popen();
X
Xint
Xdisplay(lines, msgnum)
Xint lines, msgnum;
X{
X /** Display specified number of lines from file mailfile.
X Note: This routine MUST be placed at the first line
X of the input file!
X Returns the same as the routine above (namely zero or one)
X **/
X
X char title1[SLEN], title2[SLEN], *p;
X char from_buffer[LONG_STRING], buffer[VERY_LONG_STRING];
X
X int crypted = 0, gotten_key = 0; /* encryption */
X int weed_header, weeding_out = 0; /* weeding */
X int mail_sent, /* misc use */
X form_letter = FALSE, /* Form ltr? */
X form_letter_section = 0, /* section */
X padding = 0, /* counter */
X builtin = FALSE, /* our pager? */
X val = 0; /* return val */
X
X dprint(4, (debugfile,"displaying %d lines from message %d using %s\n",
X lines, msgnum, pager));
X
X ClearScreen();
X
X if (cursor_control) transmit_functions(OFF);
X
X pipe_abort = FALSE;
X
X builtin =(first_word(pager,"builtin") || first_word(pager,"internal"));
X
X if (form_letter = (header_table[msgnum-1].status&FORM_LETTER)) {
X if (filter)
X form_letter_section = 1; /* initialize to section 1 */
X }
X
X if (builtin)
X start_builtin(lines);
X else {
X lines_displayed = 0;
X Raw(OFF);
X if ((output_pipe = popen(pager,"w")) == NULL) {
X error2("Can't create pipe to %s [%s]", pager,
X error_name(errno));
X dprint(1, (debugfile,
X "\n*** Can't create pipe to %s - error %s ***\n\n",
X pager, error_name(errno)));
X Raw(ON);
X return(0);
X }
X dprint(4, (debugfile,
X "Opened a write-only pipe to pager %s \n", pager));
X }
X
X if (title_messages && filter) {
X
X mail_sent = (strncmp(header_table[msgnum-1].from, "To:", 3) == 0);
X
X tail_of(header_table[msgnum-1].from, from_buffer, FALSE);
X
X sprintf(title1, "%s %d/%d %s %s%s",
X header_table[msgnum-1].status & DELETED ? "[deleted]" :
X form_letter? "Form": "Message",
X msgnum, message_count,
X mail_sent? "to" : "from", from_buffer,
X strlen(from_buffer) > 26? "\n": "");
X
X sprintf(title2, " %s %s '%d at %s\n",
X header_table[msgnum-1].month,
X header_table[msgnum-1].day,
X atoi(header_table[msgnum-1].year),
X header_table[msgnum-1].time);
X
X /** and now let's add some spaces between the two parts, please **/
X
X if (strlen(from_buffer) > 26) {
X if (builtin)
X display_line(title1);
X else
X fprintf(output_pipe, "%s", title1);
X title1[0] = '\0';
X padding = COLUMNS - strlen(title2) - 1;
X }
X else
X padding = COLUMNS - strlen(title1) - strlen(title2) - 1;
X
X p = title1 + strlen(title1);
X while (padding-- > 0)
X *p++ = ' ';
X *p = '\0';
X strcat(title1, title2);
X
X if (builtin)
X display_line(title1);
X else
X fprintf(output_pipe, "%s", title1);
X
X /** if there's a subject, let's next output it, centered. **/
X
X if (strlen(header_table[current-1].subject) > 0 &&
X matches_weedlist("Subject:")) {
X padding = (COLUMNS - strlen(header_table[current-1].subject)) / 2;
X p = buffer;
X while (padding-- > 0)
X *p++ = ' ';
X *p = '\0';
X strcat(buffer, header_table[current-1].subject);
X strcat(buffer, "\n");
X }
X else
X strcpy(buffer, "\n");
X
X if (builtin)
X display_line(buffer);
X else
X fprintf(output_pipe, "%s", buffer);
X
X /** was this message address to us? if not, then to whom? **/
X
X if (! mail_sent && matches_weedlist("To:") && filter &&
X strcmp(header_table[current-1].to,username) != 0 &&
X strlen(header_table[current-1].to) > 0) {
X if (strlen(header_table[current-1].to) > 60)
X sprintf(buffer, "%s(message addressed to %.60s)\n",
X strlen(header_table[current-1].subject) > 0 ? "\n" : "",
X header_table[current-1].to);
X else
X sprintf(buffer, "%s(message addressed to %s)\n",
X strlen(header_table[current-1].subject) > 0 ? "\n" : "",
X header_table[current-1].to);
X if (builtin)
X display_line(buffer);
X else
X fprintf(output_pipe, "%s", buffer);
X }
X
X /** The test above is: if we didn't originally send the mail
X (e.g. we're not reading "mail.sent") AND the user is currently
X weeding out the "To:" line (otherwise they'll get it twice!)
X AND the user is actually weeding out headers AND the message
X wasn't addressed to the user AND the 'to' address is non-zero
X (consider what happens when the message doesn't HAVE a "To:"
X line...the value is NULL but it doesn't match the username
X either. We don't want to display something ugly like
X "(message addressed to )" which will just clutter up the
X screen!).
X
X And you thought programming was EASY!!!!
X **/
X
X /** one more friendly thing - output a line indicating what sort
X of status the message has (e.g. Urgent etc). Mostly added
X for X.400 support, this is nonetheless generally useful to
X include...
X **/
X
X buffer[0] = '\0';
X
X /* we want to flag Urgent, Confidential, Private and Expired tags */
X
X if (header_table[current-1].status & PRIVATE)
X strcpy(buffer, "\n(** This message is tagged Private");
X else if (header_table[current-1].status & CONFIDENTIAL)
X strcpy(buffer, "\n(** This message is tagged Company Confidential");
X
X if (header_table[current-1].status & URGENT) {
X if (buffer[0] == '\0')
X strcpy(buffer, "\n(** This message is tagged Urgent");
X else if (header_table[current-1].status & EXPIRED)
X strcat(buffer, ", Urgent");
X else
X strcat(buffer, " and Urgent");
X }
X
X if (header_table[current-1].status & EXPIRED) {
X if (buffer[0] == '\0')
X strcpy(buffer, "\n(** This message has Expired");
X else
X strcat(buffer, ", and has Expired");
X }
X
X if (buffer[0] != '\0') {
X strcat(buffer, " **)\n");
X if (builtin)
X display_line(buffer);
X else
X fprintf(output_pipe, buffer);
X }
X
X if (builtin) /* this is for a one-line blank */
X display_line("\n"); /* separator between the title */
X else /* stuff and the actual message */
X fprintf(output_pipe, "\n"); /* we're trying to display */
X
X }
X
X weed_header = filter; /* allow us to change it after header */
X
X while (lines > 0 && pipe_abort == FALSE) {
X
X if (fgets(buffer, VERY_LONG_STRING, mailfile) == NULL) {
X if (lines_displayed == 0) {
X
X /* AUGH! Why do we get this occasionally??? */
X
X dprint(1, (debugfile,
X "\n\n** Out of Sync!! EOF with nothing read (display) **\n"));
X dprint(1, (debugfile,
X "** closing and reopening mailfile... **\n\n"));
X
X if (!builtin) {
X pclose(output_pipe); /* close pipe NOW! */
X Raw(ON);
X }
X
X if (mailfile != NULL)
X fclose(mailfile); /* huh? */
X
X if ((mailfile = fopen(infile, "r")) == NULL) {
X error("Sync error: can't re-open mailbox!!");
X show_mailfile_stats();
X emergency_exit();
X }
X return(show_message(lines,
X header_table[msgnum-1].offset,
X msgnum));
X }
X
X if (!builtin) {
X pclose(output_pipe);
X Raw(ON);
X }
X
X if (lines == 0 && pipe_abort == FALSE) { /* displayed it all */
X MoveCursor(LINES,0);
X StartBold();
X Write_to_screen(" Please press <return> to return to Elm : ",0);
X EndBold();
X fflush(stdout);
X val = ReadCh();
X }
X return(val);
X }
X
X if (strlen(buffer) > 0)
X no_ret(buffer);
X
X if (strlen(buffer) == 0) {
X weed_header = 0; /* past header! */
X weeding_out = 0;
X }
X
X if (form_letter && weed_header)
X /* skip it. NEVER display random headers in forms! */;
X else if (weed_header && matches_weedlist(buffer))
X weeding_out = 1; /* aha! We don't want to see this! */
X else if (buffer[0] == '[') {
X if (strcmp(buffer, START_ENCODE)==0)
X crypted++;
X else if (strcmp(buffer, END_ENCODE)==0)
X crypted--;
X else if (crypted) {
X encode(buffer);
X val = show_line(buffer, builtin);
X }
X else
X val = show_line(buffer, builtin);
X }
X else if (crypted) {
X if (! gotten_key++) getkey(OFF);
X encode(buffer);
X val = show_line(buffer, builtin);
X }
X else if (weeding_out) {
X weeding_out = (whitespace(buffer[0])); /* 'n' line weed */
X if (! weeding_out) /* just turned on! */
X val = show_line(buffer, builtin);
X }
X else if (form_letter && first_word(buffer,"***") && filter) {
X strcpy(buffer,
X"\n------------------------------------------------------------------------------\n");
X val = show_line(buffer, builtin); /* hide '***' */
X form_letter_section++;
X }
X else if (form_letter_section == 1 || form_letter_section == 3)
X /** skip this stuff - we can't deal with it... **/;
X else
X val = show_line(buffer, builtin);
X
X if (val != 0) { /* let's get back to the top level ... */
X if (! builtin) {
X pclose(output_pipe);
X Raw(ON);
X }
X return(val);
X }
X
X lines--;
X lines_displayed++;
X }
X
X if (cursor_control) transmit_functions(ON);
X
X if (! builtin) {
X pclose(output_pipe);
X Raw(ON);
X }
X
X if (lines == 0 && pipe_abort == FALSE) { /* displayed it all! */
X MoveCursor(LINES,0);
X StartBold();
X Write_to_screen(" Please press <return> to return to Elm : ", 0);
X EndBold();
X fflush(stdout);
X val = ReadCh();
X }
X
X return(val);
X}
X
Xint
Xshow_line(buffer, builtin)
Xchar *buffer;
Xint builtin;
X{
X /** Hands the given line to the output pipe. 'builtin' is true if
X we're using the builtin pager. We will return 'val' as the
X intermediate value from the builtin pager if the user chooses
X to do something else at the end-of-page prompt! **/
X
X register int val;
X
X if (builtin) {
X strcat(buffer, "\n");
X if ((val = display_line(buffer)) > 1) {
X return(val);
X }
X else
X pipe_abort = val;
X
X }
X else {
X errno = 0;
X fprintf(output_pipe, "%s\n", buffer);
X
X if (errno != 0)
X dprint(1, (debugfile, "\terror %s hit!\n", error_name(errno)));
X }
X
X return(0);
X}
X
Xint
Xsecure_display(lines, msgnumber)
Xint lines, msgnumber;
X{
X /** This is the cheap way to implement secure pipes - spawn a
X child process running under the old userid, then open the
X pager and feed the message to it. When the subprocess ends
X (the routine returns) simply return. Simple and effective.
X (too bad it's this much of a hassle to implement secure
X pipes, though - I can imagine it being a constant problem!)
X **/
X
X int pid, w;
X#ifdef BSD
X union wait status;
X#else
X int status;
X#endif
X register int (*istat)(), (*qstat)();
X
X#ifdef NO_VM /* machine without virtual memory! */
X if ((pid = fork()) == 0) {
X#else
X# ifdef hp9000s500 /* done this way for portability */
X if ((pid = fork()) == 0) {
X# else
X if ((pid = vfork()) == 0) {
X# endif
X#endif
X
X setgid(groupid); /* and group id */
X setuid(userid); /* back to the normal user! */
X
X _exit(display(lines, msgnumber));
X }
X
X istat = signal(SIGINT, SIG_IGN);
X qstat = signal(SIGQUIT, SIG_IGN);
X
X while ((w = wait(&status)) != pid && w != -1)
X ;
X
X signal(SIGINT, istat);
X signal(SIGQUIT, qstat);
X
X /** used to return status, but who cares? Just get BACK! **/
X
X return(0);
X}
SHAR_EOF
chmod 0444 src/showmsg.c || echo "restore of src/showmsg.c fails"
echo "x - extracting src/showmsg_c.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/showmsg_c.c &&
X
Xstatic char rcsid[] = "@(#)$Id: showmsg_c.c,v 2.1 88/09/15 20:29:46 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: showmsg_c.c,v $
X * Revision 2.1 88/09/15 20:29:46 syd
X * checked in with -k by syd at 88.09.15.20.29.46.
X *
X * 88/08/27 ssw
X * add deluth patches
X *
X * 88/08/27 ssw
X * split tolower and ReadCh due to macro calls
X *
X * Revision 2.1 88/07/21 09:59:37 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:38 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This is an interface for the showmsg command line. The possible
X functions that could be invoked from the showmsg command line are
X almost as numerous as those from the main command line and include
X the following;
X
X | = pipe this message to command...
X ! = call Unix command
X < = scan message for calendar info
X b = bounce (remail) message
X d = mark message for deletion
X f = forward message
X g = group reply
X h = redisplay this message from line #1, showing headers
X i = move back to the index page (simply returns from function)
X j,n = move to body of next message
X k = move to body of previous message
X m = mail a message out to someone
X p = print this (all tagged) message
X r = reply to this message
X s = save this message to a maibox/folder
X t = tag this message
X u = undelete message
X x = Exit Elm NOW
X
X all commands not explicitly listed here are beeped at. Use I)ndex
X to get back to the main index page, please.
X
X This function returns when it is ready to go back to the index
X page.
X**/
X
X#include "headers.h"
X
X#ifdef BSD
X#undef tolower
X#endif
X
Xint screen_mangled = 0;
X
Xint
Xprocess_showmsg_cmd(command)
Xint command;
X{
X int i, intbuf; /* for dummy parameters...etc */
X int ch; /* for arrow keys */
X int key_offset; /* for arrow keys */
X char error_line[SLEN]; /* for stat line messsages */
X
X Raw(ON);
X
X while (TRUE) {
X clear_error();
X switch (command) {
X case '|' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: pipe");
X (void) do_pipe(); /* do pipe - ignore return val */
X break;
X
X case '!' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: system call");
X (void) subshell(); /* do shell regardless */
X break;
X
X case '<' :
X#ifdef ENABLE_CALENDAR
X scan_calendar();
X#else
X strcpy(error_line, "can't scan for calendar entries!");
X goto show_prompt_again;
X#endif
X break;
X
X case '%' : clear_bottom_of_screen();
X get_return(error_line);
X error1("%s", error_line);
X/*
X PutLine1(LINES-3, (COLUMNS-strlen(error_line))/2,
X "%78s", error_line);
X*/
X goto show_prompt_again;
X break;
X
X case 'b' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: bounce message");
X remail();
X break;
X
X case 'd' : delete_msg(TRUE, FALSE); /* really delete it, silent */
X if (! resolve_mode) {
X if (screen_mangled)
X strcpy(error_line,"message marked for deletion");
X else {
X ClearLine(LINES-1);
X PutLine0(LINES-1, 0,
X "Message marked for deletion. Command ? ");
X CleartoEOLN();
X }
X } else goto move_to_next_message;
X break;
X
X case 'f' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: forward message");
X (void) forward();
X break;
X
X case 'g' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: group reply");
X (void) reply_to_everyone();
X break;
X
X case 'h' : screen_mangled = 0;
X if (filter) {
X filter = 0;
X intbuf = show_msg(current);
X filter = 1;
X return(intbuf);
X }
X else
X return(show_msg(current));
X
Xmove_to_next_message : /* a target for resolve mode actions */
X
X case 'j' :
X case 'n' : if (current < message_count) {
X screen_mangled = 0;
X i = current;
X while (++current <= message_count &&
X header_table[current-1].status & DELETED)
X /* continue looking... */ ;
X if (current > message_count) {
X current = i;
X return(0); /* no more! */
X }
X else
X return(show_msg(current));
X }
X else
X return(0);
X
X case 'J' : if (current < message_count) {
X screen_mangled = 0;
X return(show_msg(++current));
X }
X else
X return(0);
X
X case 'k' : if (current > 0) {
X screen_mangled = 0;
X i = current;
X while (--current > 0 &&
X header_table[current-1].status & DELETED)
X /* continue looking... */ ;
X if (current <= 0) {
X current = i;
X return(0); /* no more! */
X }
X else
X return(show_msg(current));
X }
X else
X return(0);
X
X case 'K' : if (current > 0) {
X screen_mangled = 0;
X return(show_msg(--current));
X }
X else
X return(0);
X
X case 'm' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: Mail message");
X (void) sendmsg("","","", TRUE, allow_forms, FALSE);
X break;
X
X case 'p' : print_msg();
X if (screen_mangled) {
X strcpy(error_line, "queued for printing");
X goto show_prompt_again;
X }
X else {
X ClearLine(LINES-1);
X PutLine0(LINES-1, 0,
X "Queued for printing. Command ? ");
X CleartoEOLN();
X }
X break;
X
X case 'r' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: reply to message");
X (void) reply();
X break;
X
X case 's' : clear_bottom_of_screen();
X PutLine0(LINES-3,0,"Command: save message");
X (void) save(&intbuf, TRUE);
X if (resolve_mode) goto move_to_next_message;
X break;
X
X case 't' : tag_message();
X if (screen_mangled) {
X strcpy(error_line, "message tagged");
X goto show_prompt_again;
X }
X else {
X ClearLine(LINES-1);
X PutLine0(LINES-1, 0,
X "Message tagged. Command ? ");
X CleartoEOLN();
X }
X break;
X
X case 'u' : undelete_msg(FALSE); /* undelete it, silently */
X if (! resolve_mode) {
X if (screen_mangled)
X strcpy(error_line, "message undeleted");
X else {
X ClearLine(LINES-1);
X PutLine0(LINES-1, 0,
X "Message undeleted. Command ? ");
X CleartoEOLN();
X }
X }
X else {
X/******************************************************************************
X ** We're special casing the U)ndelete command here *not* to move to the next
X ** undeleted message ; instead it'll blindly move to the next message in the
X ** list. See 'elm.c' and the command by "case 'u'" for further information.
X ** The old code was:
X goto move_to_next_message;
X*******************************************************************************/
X if (current == message_count)
X return(0); /* we're at the last message! */
X else
X return(show_msg(++current)); /* move forward 1 */
X }
X break;
X
X case 'x' : fflush(stdout); leave();
X
X case 'q' :
X case 'i' :
X case ' ' :
X case '\n':
X case '\r': (void) get_page(current);
X clear_error(); /* zero out pending msg */
X if (cursor_control)
X transmit_functions(ON);
X return(0); /* avoid <return> looping */
X
X case ctrl('L') : screen_mangled = 0;
X return(show_msg(current));
X
X case ESCAPE : if (cursor_control) {
X
X key_offset = 1;
X
X ch = ReadCh();
X
X if (ch == ESCAPE)
X ch = ReadCh();
X
X if ( ch == '[' || ch == 'O')
X {
X ch = ReadCh();
X key_offset++;
X }
X
X if (ch == up[key_offset]) {
X if (current > 0) {
X screen_mangled = 0;
X return(show_msg(--current));
X }
X else
X return(0);
X
X }
X else if (ch == down[key_offset]) {
X if (current < message_count) {
X screen_mangled = 0;
X return(show_msg(++current));
X }
X else
X return(0);
X
X }
X else
X {
X return(0);
X }
X }
X else /* Eat 2 chars for escape codes */
X {
X ch = ReadCh();
X ch = ReadCh();
X putchar((char) 007);
X fflush(stdout);
X return(0);
X }
X break;
X
X default : putchar((char) 007); /* BEEP! */
X fflush(stdout);
X }
X
X if (screen_mangled) {
X clear_bottom_of_screen();
Xshow_prompt_again:
X PutLine0(LINES-3, 0, "Request (return to I)ndex page) ? ");
X/**
X if (error_line[0] != '\0')
X error(error_line);
X**/
X }
X
X command = GetPrompt();
X command = tolower(command);
X }
X}
X
Xclear_bottom_of_screen()
X{
X /** clear the last 4 lines of the screen... **/
X
X screen_mangled = 1;
X
X MoveCursor(LINES-4, 0);
X CleartoEOS();
X PutLine0(LINES-4, 0,
X"--------------------------------------------------------------------------\n");
X
X show_last_error();
X}
SHAR_EOF
chmod 0444 src/showmsg_c.c || echo "restore of src/showmsg_c.c fails"
echo "x - extracting src/signals.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/signals.c &&
X
Xstatic char rcsid[] = "@(#)$Id: signals.c,v 2.1 88/07/21 09:59:39 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: signals.c,v $
X * Revision 2.1 88/07/21 09:59:39 edc
X * checked in with -k by syd at 88.09.15.20.29.49.
X *
X * Revision 2.1 88/07/21 09:59:39 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:39 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** This set of routines traps various signals and informs the
X user of the error, leaving the program in a nice, graceful
X manner.
X
X**/
X
X#include "headers.h"
X#include <signal.h>
X
Xextern int pipe_abort; /* set to TRUE if receive SIGPIPE */
X
Xquit_signal()
X{
X dprint(1, (debugfile, "\n\n** Received SIGQUIT **\n\n\n\n"));
X leave();
X}
X
Xhup_signal()
X{
X dprint(1, (debugfile, "\n\n** Received SIGHUP **\n\n\n\n"));
X leave();
X}
X
Xterm_signal()
X{
X dprint(1, (debugfile, "\n\n** Received SIGTERM **\n\n\n\n"));
X leave();
X}
X
Xill_signal()
X{
X dprint(1, (debugfile, "\n\n** Received SIGILL **\n\n\n\n"));
X PutLine0(LINES, 0, "\n\nIllegal Instruction signal!\n\n");
X emergency_exit();
X}
X
Xfpe_signal()
X{
X dprint(1, (debugfile, "\n\n** Received SIGFPE **\n\n\n\n"));
X PutLine0(LINES, 0,"\n\nFloating Point Exception signal!\n\n");
X emergency_exit();
X}
X
Xbus_signal()
X{
X dprint(1, (debugfile, "\n\n** Received SIGBUS **\n\n\n\n"));
X PutLine0(LINES, 0,"\n\nBus Error signal!\n\n");
X emergency_exit();
X}
X
Xsegv_signal()
X{
X dprint(1, (debugfile,"\n\n** Received SIGSEGV **\n\n\n\n"));
X PutLine0(LINES, 0,"\n\nSegment Violation signal!\n\n");
X emergency_exit();
X}
X
Xalarm_signal()
X{
X /** silently process alarm signal for timeouts... **/
X
X int alarm_signal();
X
X signal(SIGALRM, alarm_signal);
X}
X
Xpipe_signal()
X{
X /** silently process pipe signal... **/
X
X int pipe_signal();
X
X dprint(2, (debugfile, "*** received SIGPIPE ***\n\n"));
X
X pipe_abort = TRUE; /* internal signal ... wheeee! */
X
X signal(SIGPIPE, pipe_signal);
X}
X
X#ifdef SIGTSTP
Xint was_in_raw_state;
X
Xsig_user_stop()
X{
X /* This is called when the user presses a ^Z to stop the
X process within BSD
X */
X if (signal(SIGTSTP, SIG_DFL) != SIG_DFL) {
X signal(SIGTSTP, SIG_DFL);
X was_in_raw_state = RawState();
X }
X
X Raw(OFF); /* turn it off regardless */
X
X printf("\n\nStopped. Use \"fg\" to return to Elm\n\n");
X
X kill(0, SIGSTOP);
X}
X
Xsig_return_from_user_stop()
X{
X /** this is called when returning from a ^Z stop **/
X
X int sig_user_stop();
X
X if (signal(SIGTSTP, sig_user_stop) == SIG_DFL)
X signal(SIGTSTP, sig_user_stop);
X
X printf(
X "\nBack in Elm. (you might need to explicitly request a redraw)\n\n");
X
X if (was_in_raw_state)
X Raw(ON);
X}
X#endif
SHAR_EOF
chmod 0444 src/signals.c || echo "restore of src/signals.c fails"
echo "x - extracting src/softkeys.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/softkeys.c &&
X
Xstatic char rcsid[] = "@(#)$Id: softkeys.c,v 2.1 88/07/21 09:59:40 edc Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: softkeys.c,v $
X * Revision 2.1 88/07/21 09:59:40 edc
X * checked in with -k by syd at 88.09.15.20.29.51.
X *
X * Revision 2.1 88/07/21 09:59:40 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:40 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X
X#include <stdio.h>
X#include "headers.h"
X
Xdefine_softkeys(level)
Xint level;
X{
X if (! hp_softkeys) return;
X
X if (level == MAIN) {
X
X define_key(f1, " Read Msg", "\r");
X define_key(f2, " Mail Msg", "m");
X define_key(f3, " Reply to Msg", "r");
X
X if (user_level == 0) {
X define_key(f4, " Save Msg", "s");
X define_key(f5, " Delete Msg", "d");
X define_key(f6, "Undelete Msg", "u");
X }
X else {
X define_key(f4, " Change Mailbox", "c");
X define_key(f5, " Save Msg", "s");
X define_key(f6, " Delete/Undelete", "^");
X }
X
X define_key(f7, " Print Msg", "p");
X define_key(f8, " Quit Elm", "q");
X }
X else if (level == ALIAS) {
X define_key(f1, " Alias Current", "a");
X define_key(f2, " Check Person", "p");
X define_key(f3, " Check System", "s");
X define_key(f4, " Make Alias", "m");
X clear_key(f5);
X clear_key(f6);
X clear_key(f7);
X define_key(f8, " Return to Elm", "r");
X }
X else if (level == YESNO) {
X define_key(f1, " Yes", "y");
X clear_key(f2);
X clear_key(f3);
X clear_key(f4);
X clear_key(f5);
X clear_key(f6);
X clear_key(f7);
X define_key(f8, " No", "n");
X }
X else if (level == READ) {
X define_key(f1, " Next Page ", " ");
X clear_key(f2);
X define_key(f3, " Next Msg ", "j");
X define_key(f4, " Prev Msg ", "k");
X define_key(f5, " Reply to Msg ", "r");
X define_key(f6, " Delete Msg ", "d");
X define_key(f7, " Send Msg ", "m");
X define_key(f8, " Return to Elm ", "q");
X }
X else if (level == CHANGE) {
X define_key(f1, " Mail Directry", "=/");
X define_key(f2, " Home Directry", "~/");
X clear_key(f3);
X define_key(f4, "Incoming Mailbox", "!\n");
X clear_key(f5);
X clear_key(f6);
X clear_key(f7);
X define_key(f8, " Cancel", "\n");
X }
X
X softkeys_on();
X}
X
Xdefine_key(key, display, send)
Xint key;
Xchar *display, *send;
X{
X
X char buffer[30];
X
X sprintf(buffer,"%s%s", display, send);
X
X fprintf(stderr, "%c&f%dk%dd%dL%s", ESCAPE, key,
X strlen(display), strlen(send), buffer);
X fflush(stdout);
X}
X
Xsoftkeys_on()
X{
X /* enable (esc&s1A) turn on softkeys (esc&jB) and turn on MENU
X and USER/SYSTEM options. */
X
X if (hp_softkeys) {
X fprintf(stderr, "%c&s1A%c&jB%c&jR", ESCAPE, ESCAPE, ESCAPE);
X fflush(stdout);
X }
X
X}
X
Xsoftkeys_off()
X{
X /* turn off softkeys (esc&j@) */
X
X if (hp_softkeys) {
X fprintf(stderr, "%c&s0A%c&j@", ESCAPE, ESCAPE);
X fflush(stdout);
X }
X}
X
Xclear_key(key)
X{
X /** set a key to nothing... **/
X
X if (hp_softkeys)
X define_key(key, " ", "");
X}
SHAR_EOF
chmod 0444 src/softkeys.c || echo "restore of src/softkeys.c fails"
echo "x - extracting src/sort.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/sort.c &&
X
Xstatic char rcsid[] = "@(#)$Id: sort.c,v 2.1 88/09/15 20:29:53 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.1 $ $State: Exp $
X *
X * Copyright (c) 1986 Dave Taylor
X *******************************************************************************
X * Bug reports, patches, comments, suggetions should be sent to:
X *
X * Syd Weinstein, Elm Corrdinator
X * syd@dsinc.UUCP dsinc!syd
X *
X *******************************************************************************
X * $Log: sort.c,v $
X * Revision 2.1 88/09/15 20:29:53 syd
X * checked in with -k by syd at 88.09.15.20.29.53.
X *
X * 88/09/01 Rob Bernardo <gatech!pbhyf.PacBell.COM!rob>
X * fix mismatch between the displayed sort criteria and the
X * actual criteria used and listed
X *
X * Revision 2.1 88/07/21 09:59:41 edc
X * Final hacks and cleanup to the 2.1 alpha test release.
X *
X * Revision 2.0 88/06/27 17:25:41 edc
X * The original 2.0 gamma sources as leaked from HP
X *
X *
X *
X ******************************************************************************/
X
X/** Sort mailbox header table by the field specified in the global
X variable "sortby"...if we're sorting by something other than
X the default SENT_DATE, also put some sort of indicator on the
X screen.
X
X**/
X
X#include "headers.h"
X
Xchar *sort_name(), *skip_re();
Xvoid qsort();
X
Xsort_mailbox(entries, visible)
Xint entries, visible;
X{
X /** Sort the header_table definitions... If 'visible', then
X put the status lines etc **/
X
X int last_index = -1;
X int compare_headers(); /* for sorting */
X
X dprint(2, (debugfile, "\n** sorting mailbox by %s **\n\n",
X sort_name(FULL)));
X
X if (entries > 0)
X last_index = header_table[current-1].index_number;
X
X if (entries > 30 && visible)
X error1("sorting messages by %s", sort_name(FULL));
X
X qsort(header_table, (unsigned) entries, sizeof (struct header_rec),
X compare_headers);
X
X if (last_index > -1)
X find_old_current(last_index);
X
X clear_error();
X}
X
Xint
Xcompare_headers(first, second)
Xstruct header_rec *first, *second;
X{
X /** compare two headers according to the sortby value.
X
X Sent Date uses a routine to compare two dates,
X Received date is keyed on the file offsets (think about it)
X Sender uses the truncated from line, same as "build headers",
X and size and subject are trivially obvious!!
X (actually, subject has been modified to ignore any leading
X patterns [rR][eE]*:[ \t] so that replies to messages are
X sorted with the message (though a reply will always sort to
X be 'greater' than the basenote)
X **/
X
X char from1[SLEN], from2[SLEN]; /* sorting buffers... */
X int sign = 1;
X
X if (sortby < 0)
X sign = -1;
X
X switch (abs(sortby)) {
X
X case SENT_DATE : return( sign*compare_dates(first, second));
X
X case RECEIVED_DATE: return( sign*
X compare_parsed_dates(first->received,
X second->received));
X
X case SENDER : tail_of(first->from, from1, TRUE);
X tail_of(second->from, from2, TRUE);
X return( sign*strcmp(from1, from2));
X
X case SIZE : return( sign*(first->lines - second->lines));
X
X case MAILBOX_ORDER : return( sign*
X (first->index_number - second->index_number));
X
X case SUBJECT : /* need some extra work 'cause of STATIC buffers */
X strcpy(from1, skip_re(shift_lower(first->subject)));
X return( sign*
X strcmp(from1,
X skip_re(shift_lower(second->subject))));
X
X case STATUS : return( sign*(first->status - second->status));
X }
X
X return(0); /* never get this! */
X}
X
Xchar *sort_name(type)
Xint type;
X{
X /** return the name of the current sort option...
X type can be "FULL", "SHORT" or "PAD"
X **/
X int pad, abr;
X
X pad = (type == PAD);
X abr = (type == SHORT);
X
X if (sortby < 0) {
X switch (- sortby) {
X case SENT_DATE : return(
X pad? "Reverse Date Mail Sent " :
X abr? "Reverse-Sent" :
X "Reverse Date Mail Sent");
X case RECEIVED_DATE: return(
X abr? "Reverse-Received":
X "Reverse Date Mail Rec'vd" );
X
X case MAILBOX_ORDER: return(
X pad? "Reverse Mailbox Order " :
X abr? "Reverse-Mailbox":
X "Reverse Mailbox Order");
X
X case SENDER : return(
X pad? "Reverse Message Sender " :
X abr? "Reverse-From":
X "Reverse Message Sender");
X case SIZE : return(
X abr? "Reverse-Lines" :
X "Reverse Lines in Message");
X case SUBJECT : return(
X pad? "Reverse Message Subject " :
X abr? "Reverse-Subject" :
X "Reverse Message Subject");
X case STATUS : return(
X pad? "Reverse Message Status " :
X abr? "Reverse-Status":
X "Reverse Message Status");
X }
X }
X else {
X switch (sortby) {
X case SENT_DATE : return(
X pad? "Date Mail Sent " :
X abr? "Sent" :
X "Date Mail Sent");
X case RECEIVED_DATE: return(
X pad? "Date Mail Rec'vd " :
X abr? "Received" :
X "Date Mail Rec'vd");
X case MAILBOX_ORDER: return(
X pad? "Mailbox Order " :
X abr? "Mailbox" :
X "Mailbox Order");
X case SENDER : return(
X pad? "Message Sender " :
X abr? "From" :
X "Message Sender");
X case SIZE : return(
X pad? "Lines in Message " :
X abr? "Lines" :
X "Lines in Message");
X case SUBJECT : return(
X pad? "Message Subject " :
X abr? "Subject" :
X "Message Subject");
X case STATUS : return(
X pad? "Message Status " :
X abr? "Status" :
X "Message Status");
X }
X }
X
X return("*UNKNOWN-SORT-PARAMETER*");
X}
X
Xfind_old_current(index)
Xint index;
X{
X /** Set current to the message that has "index" as it's
X index number. This is to track the current message
X when we resync... **/
X
X register int i;
X
X dprint(4, (debugfile, "find-old-current(%d)\n", index));
X
X for (i = 0; i < message_count; i++)
X if (header_table[i].index_number == index) {
X current = i+1;
X dprint(4, (debugfile, "\tset current to %d!\n", current));
X return;
X }
X
X dprint(4, (debugfile,
X "\tcouldn't find current index. Current left as %d\n",
X current));
X return; /* can't be found. Leave it alone, then */
X}
X
Xchar *skip_re(string)
Xchar *string;
X{
X /** this routine returns the given string minus any sort of
SHAR_EOF
echo "End of part 18"
echo "File src/sort.c is continued in part 19"
echo "19" > s2_seq_.tmp
exit 0
--
=====================================================================
Sydney S. Weinstein, CDP, CCP Elm Coordinator
Datacomp Systems, Inc. Voice: (215) 947-9900
{allegra,bellcore,bpa,vu-vlsi}!dsinc!syd FAX: (215) 938-0235