home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume22
/
elm2.3
/
part16
< prev
next >
Wrap
Text File
|
1990-06-07
|
50KB
|
1,814 lines
Subject: v22i075: ELM mail syste, release 2.3, Part16/26
Newsgroups: comp.sources.unix
Approved: rsalz@uunet.UU.NET
X-Checksum-Snefru: ff7bd791 91ac6a0c 5c8879f1 c04da152
Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
Posting-number: Volume 22, Issue 75
Archive-name: elm2.3/part16
---- Cut Here and unpack ----
#!/bin/sh
# this is part 16 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/hdrconfg.c continued
#
CurArch=16
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/hdrconfg.c"
sed 's/^X//' << 'SHAR_EOF' >> src/hdrconfg.c
X (void) build_address(strip_commas(cc), expanded_cc);
X put_cc();
X break;
X
X case 'r' : PutLine0(INPUT_LINE, 0, "Reply-To: "); CleartoEOLN();
X if(optionally_enter(reply_to,
X INPUT_LINE, 10, FALSE, FALSE) == -1)
X return(0);
X put_replyto();
X break;
X
X case 'a' : PutLine0(INPUT_LINE, 0, "Action: "); CleartoEOLN();
X if (optionally_enter(action,
X INPUT_LINE, 8, FALSE, FALSE) == -1)
X return(0);
X put_action();
X break;
X
X case 'p' : PutLine0(INPUT_LINE, 0, "Priority: "); CleartoEOLN();
X if (optionally_enter(priority,
X INPUT_LINE, 10, FALSE, FALSE)==-1)
X return(0);
X put_priority();
X break;
X
X case 'e' : enter_date(expires);
X put_expires();
X break;
X
X case 'u' : PutLine0(EXTRA_PROMPT_LINE, 0, "User defined header: ");
X CleartoEOLN();
X if (optionally_enter(user_defined_header,
X INPUT_LINE, 0, FALSE, FALSE)==-1)
X return(0);
X check_user_header(user_defined_header);
X put_userdefined();
X ClearLine(EXTRA_PROMPT_LINE);
X break;
X
X case 'i' : if (strlen(in_reply_to) > 0) {
X PutLine0(INPUT_LINE, 0, "In-Reply-To: "); CleartoEOLN();
X if (optionally_enter(in_reply_to,
X INPUT_LINE, 13, FALSE, FALSE) == -1)
X return(0);
X put_inreplyto();
X break;
X }
X
X#ifdef ALLOW_SUBSHELL
X case '!': if (subshell())
X display_headers();
X continue;
X#endif
X
X default : Centerline(ERROR_LINE, "No such header!");
X displayed_error = YES;
X }
X }
X}
X
Xdisplay_headers()
X{
X char buffer[SLEN];
X
X ClearScreen();
X
X Centerline(0,"Message Header Edit Screen");
X
X put_to();
X put_cc();
X put_bcc();
X put_subject();
X put_replyto();
X put_action();
X put_expires();
X put_priority();
X if (in_reply_to[0])
X put_inreplyto();
X if (user_defined_header[0])
X put_userdefined();
X
X strcpy(buffer, "Choose first letter of header, u)ser defined header, ");
X#ifdef ALLOW_SUBSHELL
X strcat(buffer, "!)shell, ");
X#endif
X strcat(buffer, "or <return>.");
X Centerline(INSTRUCT_LINE, buffer);
X}
X
Xstatic
Xput_header(hline, hcount, field, value)
Xint hline, hcount;
Xchar *field, *value;
X{
X char *p;
X int x, y;
X
X MoveCursor(hline, 0);
X
X if (field) {
X for (p = field; *p; ++p)
X Writechar(*p);
X Writechar(':');
X Writechar(' ');
X }
X
X GetXYLocation(&x, &y);
X
X for (p = value; *p; ++p) {
X if (x >= (hline + hcount))
X break;
X /* neat hack alert -- danger will robinson */
X if ((x + 1) == (hline + hcount)
X && (y + 4) == COLUMNS && strlen(p) > 4)
X p = " ...";
X Writechar(*p);
X ++y;
X if (*p < 0x20 || *p >= 0x7F || y >= COLUMNS)
X GetXYLocation(&x, &y);
X }
X
X if (x < (hline + hcount)) {
X CleartoEOLN();
X
X while (++x < (hline + hcount)) {
X MoveCursor(x, 0);
X CleartoEOLN();
X }
X }
X}
X
Xenter_date(datebuf)
Xchar *datebuf;
X{
X /** Enter the number of days this message is valid for, then
X display at (x,y) the actual date of expiration. This
X routine relies heavily on the routine 'days_ahead()' in
X the file date.c
X **/
X
X int days;
X char numdaysbuf[SLEN];
X
X static char prompt[] =
X "How many days in the future should this message expire? ";
X
X PutLine0(INPUT_LINE,0, prompt);
X CleartoEOLN();
X *datebuf = *numdaysbuf = '\0';
X
X optionally_enter(numdaysbuf, INPUT_LINE, strlen(prompt), FALSE, FALSE);
X sscanf(numdaysbuf, "%d", &days);
X if (days < 1)
X Centerline(ERROR_LINE, "That doesn't make sense!");
X else if (days > 56)
X Centerline(ERROR_LINE,
X "Expiration date must be within eight weeks of today.");
X else {
X days_ahead(days, datebuf);
X }
X}
X
Xcheck_user_header(header)
Xchar *header;
X{
X /** check the header format...if bad print error and erase! **/
X
X register int i = -1;
X
X if (strlen(header) == 0)
X return;
X
X if (whitespace(header[0])) {
X error ("You can't have leading white space in a header!");
X header[0] = '\0';
X ClearLine(USER_DEFINED_HDR_LINE);
X return;
X }
X
X if (header[0] == ':') {
X error ("You can't have a colon as the first character!");
X header[0] = '\0';
X ClearLine(USER_DEFINED_HDR_LINE);
X return;
X }
X
X while (header[++i] != ':') {
X if (header[i] == '\0') {
X Centerline(ERROR_LINE, "You need to have a colon ending the field name!");
X header[0] = '\0';
X ClearLine(USER_DEFINED_HDR_LINE);
X return;
X }
X else if (whitespace(header[i])) {
X Centerline(ERROR_LINE, "You can't have white space imbedded in the header name!");
X header[0] = '\0';
X ClearLine(USER_DEFINED_HDR_LINE);
X return;
X }
X }
X
X return;
X}
SHAR_EOF
echo "File src/hdrconfg.c is complete"
chmod 0444 src/hdrconfg.c || echo "restore of src/hdrconfg.c fails"
echo "x - extracting src/help.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/help.c &&
X
Xstatic char rcsid[] = "@(#)$Id: help.c,v 4.1 90/04/28 22:43:11 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: help.c,v $
X * Revision 4.1 90/04/28 22:43:11 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/*** help routine for ELM program
X
X***/
X
X#include <ctype.h>
X#include "headers.h"
X
Xhelp(pager_help)
Xint pager_help;
X{
X /** Process the request for help [section] from the user.
X If pager_help is TRUE, then act a little differently from
X if pager_help is FALSE (index screen)
X **/
X
X char ch; /* character buffer for input */
X char *s; /* string pointer... */
X int prompt_line, info_line;
X static char help_message[] =
X "Press the key you want help for, '?' for a key list, or '.' to exit help";
X static char help_prompt[] = "Help for key: ";
X
X MoveCursor(LINES-4,0);
X CleartoEOS();
X
X if(pager_help) {
X put_border();
X Centerline(LINES, help_message);
X prompt_line = LINES-3;
X } else {
X Centerline(LINES-4, "ELM Help System");
X Centerline(LINES-3, help_message);
X prompt_line = LINES-2;
X }
X info_line = prompt_line + 1;
X
X PutLine0(prompt_line, 0, help_prompt);
X
X do {
X MoveCursor(prompt_line, strlen(help_prompt));
X ch = ReadCh();
X
X if (ch == '.') return(0); /* zero means footer rewrite only */
X
X s = "Unknown command. Use '?' for a list of commands.";
X
X switch (ch) {
X
X case '?': display_helpfile(pager_help? PAGER_HELP : MAIN_HELP);
X return(1);
X
X case '$': if(!pager_help) s =
X"$ = Force resynchronization of the current folder. This will purge deleted mail.";
X break;
X
X case '!': s =
X "! = Escape to the Unix shell of your choice, or just to enter commands.";
X break;
X
X case '@': if(!pager_help) s =
X "@ = Debug - display a summary of the messages on the header page.";
X break;
X
X case '|': s =
X "| = Pipe the current message or tagged messages to the command specified.";
X break;
X
X case '#': if(!pager_help) s =
X "# = Debug - display all information known about current message.";
X break;
X
X case '%': s =
X "% = Debug - display the computed return address of the current message.";
X break;
X
X case '*': if(!pager_help)
X s = "* = Go to the last message in the current folder.";
X break;
X
X case '-': if(!pager_help) s =
X"- = Go to the previous page of messages. This is the same as the LEFT arrow.";
X break;
X
X case '=': if(!pager_help) s =
X "'=' = Go to the first message in the current folder.";
X break;
X
X case ' ': if(pager_help) s =
X "<space> = Display next screen of current message (or first screen of next).";
X else s = "<space> = Display the current message.";
X break;
X
X case '+': if(!pager_help)
X s =
X "+ = Go to the next page of messages. This is the same as the RIGHT arrow.";
X break;
X
X case '/': if(!pager_help)
X s = "/ = Search for specified pattern in folder.";
X break;
X
X case '<': s =
X "< = Scan current message for calendar entries (if enabled).";
X break;
X
X case '>': s =
X "> = Save current message or tagged messages to specified file.";
X break;
X
X case '^': if(!pager_help) s =
X "^ = Toggle the Delete/Undelete status of the current message.";
X break;
X
X case 'a': if(!pager_help) s =
X "a = Enter the alias sub-menu section. Create and display aliases.";
X break;
X
X case 'b': s =
X "b = Bounce (remail) a message to someone as if you have never seen it.";
X break;
X
X case 'C': s =
X "C = Copy current message or tagged messages to specified file.";
X break;
X
X case 'c': if(!pager_help) s =
X "c = Change folders, leaving the current folder as if 'quitting'.";
X break;
X
X case 'd': s = "d = Mark the current message for future deletion.";
X break;
X
X case ctrl('D') : if(!pager_help) s =
X "^D = Mark for deletion all messages with the specified pattern.";
X break;
X
X case 'e': if(!pager_help) s =
X "e = Invoke the editor on the entire folder, resynchronizing when done.";
X break;
X
X case 'f': s =
X "f = Forward the current message to someone, return address is yours.";
X break;
X
X case 'g': s =
X "g = Group reply not only to the sender, but to everyone who received msg.";
X break;
X
X case 'h': s =
X "h = Display message with all Headers (ignore weedout list).";
X break;
X
X case 'i': if(pager_help) s = "i = Return to the index.";
X break;
X
X case 'J': s = "J = Go to the next message.";
X break;
X
X case 'j': s =
X "j = Go to the next undeleted message. This is the same as the DOWN arrow.";
X break;
X
X case 'K': s = "K = Go to the previous message.";
X break;
X
X case 'k': s =
X"k = Go to the previous undeleted message. This is the same as the UP arrow.";
X break;
X
X case 'l': if(!pager_help) s =
X "l = Limit displayed messages based on the specified criteria.";
X break;
X
X case 'm': s =
X "m = Create and send mail to the specified person or persons.";
X break;
X
X case 'n': if(pager_help)
X s = "n = Display the next message.";
X else
X s =
X "n = Display the current message, then move current to next messge.";
X break;
X
X case 'o': if(!pager_help) s = "o = Go to the options submenu.";
X break;
X
X case 'p': s =
X "p = Print the current message or the tagged messages.";
X break;
X
X case 'q': if(pager_help) s =
X "q = Quit the pager and return to the index.";
X else s =
X "q = Quit the mailer, asking about deletion, saving, etc.";
X break;
X
X case 'r': s =
X"r = Reply to the message. This only sends to the originator of the message.";
X break;
X
X case 's': s =
X "s = Save current message or tagged messages to specified file.";
X break;
X
X case 't': s =
X "t = Tag a message for further operations (or untag if tagged).";
X break;
X
X case ctrl('T') : if(!pager_help) s =
X "^T = Tag all messages with the specified pattern.";
X break;
X
X case 'u': s =
X "u = Undelete - remove the deletion mark on the message.";
X break;
X
X case 'x': s = "x = Exit the mail system quickly.";
X break;
X
X case 'Q': if(!pager_help) s =
X "Q = Quick quit the mailer, save read, leave unread, delete deleted.";
X break;
X
X case '\n':
X case '\r': if(pager_help)
X s =
X "<return> = Display current message, or (builtin pager only) scroll forward.";
X else
X s = "<return> = Display the current message.";
X break;
X
X case ctrl('L'): if(!pager_help) s = "^L = Rewrite the screen.";
X break;
X
X case ctrl('?'): /* DEL */
X case ctrl('Q'): if(!pager_help) s = "Exit the mail system quickly.";
X break;
X
X default : if (isdigit(ch) && !pager_help)
X s = "<number> = Make specified number the current message.";
X }
X
X ClearLine(info_line);
X Centerline(info_line, s);
X
X } while (ch != '.');
X
X /** we'll never actually get here, but that's okay... **/
X
X return(0);
X}
X
Xdisplay_helpfile(section)
Xint section;
X{
X /*** Help me! Read file 'helpfile.<section>' and echo to screen ***/
X
X char buffer[SLEN];
X
X sprintf(buffer, "%s/%s.%d", helphome, helpfile, section);
X return(display_file(buffer));
X}
X
Xdisplay_file(file)
Xchar *file;
X{
X /*** Display file to screen ***/
X
X FILE *fileptr;
X int lines=0;
X char buffer[SLEN];
X
X if ((fileptr = fopen(file,"r")) == NULL) {
X dprint(1, (debugfile,
X "Error: Couldn't open file %s (help)\n", file));
X error1("Couldn't open file %s.",file);
X return(FALSE);
X }
X
X ClearScreen();
X
X while (fgets(buffer, SLEN, fileptr) != NULL) {
X if (lines > LINES-3) {
X PutLine0(LINES,0,"Press <space> to continue, 'q' to return.");
X if(ReadCh() == 'q') {
X clear_error();
X fclose(fileptr);
X return(TRUE);
X }
X lines = 0;
X ClearScreen();
X Write_to_screen("%s\r", 1, buffer);
X }
X else
X Write_to_screen("%s\r", 1, buffer);
X
X lines += strlen(buffer)/COLUMNS + 1;
X }
X
X PutLine0(LINES,0,"Press any key to return.");
X
X (void) ReadCh();
X clear_error();
X
X fclose(fileptr);
X return(TRUE);
X}
SHAR_EOF
chmod 0444 src/help.c || echo "restore of src/help.c fails"
echo "x - extracting src/in_utils.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/in_utils.c &&
X
Xstatic char rcsid[] = "@(#)$Id: in_utils.c,v 4.1 90/04/28 22:43:13 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: in_utils.c,v $
X * Revision 4.1 90/04/28 22:43:13 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** Mindless I/O routines for ELM
X
X**/
X
X#include "headers.h"
X#include <errno.h>
X#include <ctype.h>
X
X#ifdef BSD
X# undef tolower
X#endif
X
Xextern int errno; /* system error number */
X
Xunsigned alarm();
X
X#define isstopchar(c) (c == ' ' || c == '\t' || c == '/')
X#define isslash(c) (c == '/')
X#define erase_a_char() { Writechar(BACKSPACE); Writechar(' '); \
X Writechar(BACKSPACE); fflush(stdout); }
X
Xint
Xwant_to(question, dflt)
Xchar *question, dflt;
X{
X /** Ask 'question' on LINES-2 left enough to just leave room for an
X answer, returning the answer in lower case.
X Echo answer as full "Yes" or "No". 'dflt' is the
X default answer if <return> is pressed. (Note: 'dflt' is also what
X will be returned if <return> is pressed!)
X **/
X register int ch, cols;
X
X cols = COLUMNS - (strlen(question) + 5 ); /* 5 for "Yes." + 1 */
X
X MoveCursor(LINES-3, cols);
X CleartoEOLN();
X PutLine3(LINES-3, cols,"%s%c%c", question, dflt, BACKSPACE);
X fflush(stdout);
X fflush(stdin);
X
X ch = ReadCh();
X ch = tolower(ch);
X
X while (!( ch == 'y' || ch == 'n' || ch == '\n' || ch == '\r')) {
X ch = ReadCh();
X ch = tolower(ch);
X }
X if(ch == '\n' || ch == '\r')
X ch = dflt;
X
X if(ch == 'y')
X Write_to_screen("Yes.", 0);
X else
X Write_to_screen("No.", 0);
X
X return(ch);
X}
X
Xint
Xread_number(ch)
Xchar ch;
X{
X /** Read a number, where 'ch' is the leading digit! **/
X
X char buff[NLEN];
X int num;
X
X buff[0] = ch;
X buff[1] = '\0';
X
X PutLine0(LINES-3, COLUMNS-40,"Set current message to :");
X if (optionally_enter(buff, LINES-3, COLUMNS-15, TRUE, FALSE) == -1)
X return(current);
X
X sscanf(buff,"%d", &num);
X return(num);
X}
X
Xint
Xoptionally_enter(string, x, y, append_current, passwd)
Xchar *string;
Xint x,y, append_current, passwd;
X{
X /** This will display the string on the screen and allow the user to
X either accept it (by pressing RETURN) or alter it according to
X what the user types. The various flags are:
X string is the buffer to use (with optional initial value)
X x,y is the location we're at on the screen (-1,-1 means
X that we can't use this info and need to find out
X the current location)
X append_current means that we have an initial string and that
X the cursor should be placed at the END of the line,
X not the beginning (the default).
X passwd accept non-printing characters and do not echo
X entered characters.
X
X If we hit an interrupt or EOF we'll return non-zero.
X **/
X
X int ch;
X register int ch_count = 0, iindex = 0, escaped = OFF;
X
X clearerr(stdin);
X
X if(!passwd) {
X if(!(x >=0 && y >= 0))
X GetXYLocation(&x, &y);
X PutLine1(x, y, "%s", string);
X }
X
X CleartoEOLN();
X
X if (! append_current) {
X MoveCursor(x,y);
X }
X else
X iindex = strlen(string);
X
X if (cursor_control)
X transmit_functions(OFF);
X
X /** now we have the screen as we want it and the cursor in the
X right place, we can loop around on the input and return the
X string as soon as the user presses <RETURN>
X **/
X
X do {
X ch = getchar();
X
X if (ch == ctrl('D') || ch == EOF) { /* we've hit EOF */
X if (cursor_control)
X transmit_functions(ON);
X return(1);
X }
X
X if (ch_count++ == 0) {
X if (ch == '\n' || ch == '\r') {
X if (cursor_control)
X transmit_functions(ON);
X return(0);
X }
X else if (! append_current) {
X CleartoEOLN();
X iindex = (append_current? strlen(string) : 0);
X }
X }
X
X /* the following is converted from a case statement to
X allow the variable characters (backspace, kill_line
X and break) to be processed. Case statements in
X C require constants as labels, so it failed ...
X */
X
X if (ch == backspace &&
X (!escaped || (!isprint(ch) && !passwd))) {
X /* This is tricky. Here we are dealing with all situations
X * under which a backspace (really whatever erase char is
X * set to, not necessarily \b) erases the previous character.
X * It will erase unless escaped, because if it's escaped
X * it is taken literally. There is one exception to that --
X * if backspace would be rejected (we don't accept non-printing
X * characters in non-passwd mode), we accept it here as an
X * erasing character, for it if got rejected there would
X * be no way of erasing a preceding backslash. */
X escaped = OFF;
X if (iindex > 0) {
X if(!passwd)
X Writechar(BACKSPACE);
X iindex--;
X }
X if(!passwd) {
X Writechar(' ');
X Writechar(BACKSPACE);
X fflush(stdout);
X }
X }
X else if (ch == EOF || ch == '\n' || ch == '\r') {
X escaped = OFF;
X string[iindex] = '\0';
X if (cursor_control)
X transmit_functions(ON);
X return(0);
X }
X else if (!passwd && ch == ctrl('W')) { /* back up a word! */
X escaped = OFF;
X if (iindex == 0)
X continue; /* no point staying here.. */
X iindex--;
X if (isslash(string[iindex])) {
X erase_a_char();
X }
X else {
X while (iindex >= 0 && isspace(string[iindex])) {
X iindex--;
X erase_a_char();
X }
X
X while (iindex >= 0 && ! isstopchar(string[iindex])) {
X iindex--;
X erase_a_char();
X }
X iindex++; /* and make sure we point at the first AVAILABLE slot */
X }
X }
X else if (!passwd && ch == ctrl('R')) {
X escaped = OFF;
X string[iindex] = '\0';
X PutLine1(x,y, "%s", string);
X CleartoEOLN();
X }
X else if (!escaped && ch == kill_line) {
X /* needed to test if escaped since kill_line character could
X * be a desired valid printing character */
X escaped = OFF;
X if(!passwd) {
X MoveCursor(x,y);
X CleartoEOLN();
X }
X iindex = 0;
X }
X else if (ch == '\0') {
X escaped = OFF;
X if (cursor_control)
X transmit_functions(ON);
X fflush(stdin); /* remove extraneous chars, if any */
X string[0] = '\0'; /* clean up string, and... */
X return(-1);
X }
X else if (!passwd && !isprint(ch)) {
X /* non-printing character - warn with bell*/
X /* don't turn off escaping backslash since current character
X * doesn't "use it up".
X */
X Writechar('\007');
X }
X else { /* default case */
X if(escaped && (ch == backspace || ch == kill_line)) {
X /* if last character was a backslash,
X * and if this character is escapable
X * simply write this character over it even if
X * this character is a backslash.
X */
X if(!passwd)
X Writechar(BACKSPACE);
X iindex--;
X string[iindex++] = ch;
X if(!passwd)
X Writechar(ch);
X escaped = OFF;
X } else {
X string[iindex++] = ch;
X if(!passwd)
X Writechar(ch);
X escaped = ( ch == '\\' ? ON : OFF);
X }
X }
X } while (iindex < SLEN);
X
X string[iindex] = '\0';
X
X if (cursor_control)
X transmit_functions(ON);
X
X return(0);
X}
X
Xint
Xpattern_enter(string, alt_string, x, y, alternate_prompt)
Xchar *string, *alt_string, *alternate_prompt;
Xint x,y;
X{
X /** This function is functionally similar to the routine
X optionally-enter, but if the first character pressed
X is a '/' character, then the alternate prompt and string
X are used rather than the normal one. This routine
X returns 1 if alternate was used, 0 if not
X **/
X
X int ch;
X register iindex = 0, escaped = OFF;
X
X PutLine1(x, y, "%s", string);
X CleartoEOLN();
X MoveCursor(x,y);
X
X if (cursor_control)
X transmit_functions(OFF);
X
X ch = getchar();
X
X if (ch == '\n' || ch == '\r') {
X if (cursor_control)
X transmit_functions(ON);
X return(0); /* we're done. No change needed */
X }
X
X if (ch == '/') {
X PutLine1(x, 0, "%s", alternate_prompt);
X CleartoEOLN();
X (void) optionally_enter(alt_string, x, strlen(alternate_prompt)+1,
X FALSE, FALSE);
X return(1);
X }
X
X CleartoEOLN();
X
X iindex = 0;
X
X if (ch == kill_line) {
X MoveCursor(x,y);
X CleartoEOLN();
X iindex = 0;
X }
X else if (ch != backspace) {
X if(ch == '\\') escaped = ON;
X Writechar(ch);
X string[iindex++] = ch;
X }
X else if (iindex > 0) {
X iindex--;
X erase_a_char();
X }
X else {
X Writechar(' ');
X Writechar(BACKSPACE);
X }
X
X do {
X fflush(stdout);
X ch = getchar();
X
X /* the following is converted from a case statement to
X allow the variable characters (backspace, kill_line
X and break) to be processed. Case statements in
X C require constants as labels, so it failed ...
X */
X
X if (ch == backspace &&
X (!escaped || !isprint(ch)) ) {
X /* This is tricky. Here we are dealing with all situations
X * under which a backspace (really whatever erase char is
X * set to, not necessarily \b) erases the previous character.
X * It will erase unless escaped, because if it's escaped
X * it is taken literally. There is one exception to that --
X * if backspace would be rejected (we don't accept non-printing
X * characters in non-passwd mode), we accept it here as an
X * erasing character, for it if got rejected there would
X * be no way of erasing a preceding backslash. */
X escaped = OFF;
X if (iindex > 0) {
X iindex--;
X erase_a_char();
X }
X else {
X Writechar(' ');
X Writechar(BACKSPACE);
X }
X }
X else if (ch == '\n' || ch == '\r') {
X escaped = OFF;
X string[iindex] = '\0';
X if (cursor_control)
X transmit_functions(ON);
X return(0);
X }
X else if (ch == ctrl('W')) {
X escaped = OFF;
X if (iindex == 0)
X continue; /* no point staying here.. */
X iindex--;
X if (isslash(string[iindex])) {
X erase_a_char();
X }
X else {
X while (iindex >= 0 && isspace(string[iindex])) {
X iindex--;
X erase_a_char();
X }
X
X while (iindex >= 0 && ! isstopchar(string[iindex])) {
X iindex--;
X erase_a_char();
X }
X iindex++;/* and make sure we point at the first AVAILABLE slot */
X }
X }
X else if (ch == ctrl('R')) {
X escaped = OFF;
X string[iindex] = '\0';
X PutLine1(x,y, "%s", string);
X CleartoEOLN();
X }
X else if (!escaped && ch == kill_line) {
X /* needed to test if escaped since kill_line character could
X * be a desired valid printing character */
X escaped = OFF;
X MoveCursor(x,y);
X CleartoEOLN();
X iindex = 0;
X }
X else if (ch == '\0') {
X escaped = OFF;
X if (cursor_control)
X transmit_functions(ON);
X fflush(stdin); /* remove extraneous chars, if any */
X string[0] = '\0'; /* clean up string, and... */
X return(-1);
X }
X else if (!isprint(ch)) {
X /* non-printing character - warn with bell*/
X /* don't turn off escaping backslash since current character
X * doesn't "use it up".
X */
X Writechar('\007');
X }
X else { /* default case */
X if(escaped && (ch == backspace || ch == kill_line)) {
X /* if last character was a backslash,
X * and if this character is escapable
X * simply write this character over it even if
X * this character is a backslash.
X */
X Writechar(BACKSPACE);
X iindex--;
X string[iindex++] = ch;
X Writechar(ch);
X escaped = OFF;
X } else {
X string[iindex++] = ch;
X Writechar(ch);
X escaped = ( ch == '\\' ? ON : OFF);
X }
X }
X } while (iindex < SLEN);
X
X string[iindex] = '\0';
X
X if (cursor_control)
X transmit_functions(ON);
X return(0);
X}
X
Xint
XGetPrompt()
X{
X /** This routine does a read/timeout for a single character.
X The way that this is determined is that the routine to
X read a character is called, then the "errno" is checked
X against EINTR (interrupted call). If they match, this
X returns NO_OP_COMMAND otherwise it returns the normal
X command. On BSD systems, the EINTR will never be returned
X so we instead longjmp from the signal handler.
X **/
X
X int ch;
X
X if (timeout > 0) {
X alarm((unsigned) timeout);
X#ifdef BSD
X if (setjmp(GetPromptBuf)) {
X InGetPrompt = 0;
X ch = NO_OP_COMMAND;
X alarm((unsigned) 0);
X }
X else {
X InGetPrompt = 1;
X ch = ReadCh();
X InGetPrompt = 0;
X alarm((unsigned) 0);
X }
X#else
X errno = 0; /* we actually have to do this. *sigh* */
X ch = ReadCh();
X if (errno == EINTR) ch = NO_OP_COMMAND;
X alarm((unsigned) 0);
X#endif
X }
X else
X ch = ReadCh();
X
X return(ch);
X}
SHAR_EOF
chmod 0444 src/in_utils.c || echo "restore of src/in_utils.c fails"
echo "x - extracting src/init.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/init.c &&
X
Xstatic char rcsid[] = "@(#)$Id: init.c,v 4.1 90/04/28 22:43:15 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: init.c,v $
X * Revision 4.1 90/04/28 22:43:15 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/***** Initialize - read in all the defaults etc etc
X*****/
X
X#include "headers.h"
X#include "patchlevel.h"
X
X#ifdef TERMIOS
X# include <termios.h>
X typedef struct termios term_buff;
X#else
X# ifdef TERMIO
X# include <termio.h>
X# define tcgetattr(fd,buf) ioctl((fd),TCGETA,(buf))
X typedef struct termio term_buff;
X# else
X# include <sgtty.h>
X# define tcgetattr(fd,buf) ioctl((fd),TIOCGETP,(buf))
X typedef struct sgttyb term_buff;
X# endif
X#endif
X
X#ifdef PWDINSYS
X# include <sys/pwd.h>
X#else
X# include <pwd.h>
X#endif
X
X#ifdef I_TIME
X# include <time.h>
X#endif
X#ifdef I_SYSTIME
X# include <sys/time.h>
X#endif
X
X#include <signal.h>
X#include <ctype.h>
X#include <errno.h>
X
X#ifdef BSD
X#undef toupper
X#undef tolower
X#endif
X
Xextern int errno; /* system error number on failure */
Xextern char version_buff[];
X
Xchar *error_name(), *error_description();
X
Xchar *getenv(), *getlogin(), *strcpy(), *strcat(), *index();
Xunsigned short getgid(), getuid();
Xvoid exit();
X#ifndef _POSIX_SOURCE
Xstruct passwd *getpwuid();
X#endif
Xchar *get_full_name();
X
X#ifdef VOIDSIG
X void
X#else
X int
X#endif
X#ifdef SIGTSTP
X sig_user_stop(), sig_return_from_user_stop(),
X#endif
X quit_signal(), term_signal(), ill_signal(),
X fpe_signal(), bus_signal(), segv_signal(),
X alarm_signal(), pipe_signal(), hup_signal();
X
Xinitialize(requestedmfile)
Xchar *requestedmfile; /* first mail file to open, empty if the default */
X{
X /** initialize the whole ball of wax.
X **/
X struct passwd *pass;
X register int i, hostlen, domlen;
X
X#if defined(SIGVEC) & defined(SV_INTERRUPT)
X struct sigvec alarm_vec;
X#endif
X char buffer[SLEN], *cp;
X
X sprintf(version_buff, "%s PL%d", VERSION, PATCHLEVEL);
X Raw(ON);
X
X /* save original user and group ids */
X userid = getuid();
X groupid = getgid();
X
X /* make all newly created files private */
X original_umask = umask(077);
X
X /* Get username (logname), home (login directory), and full_username
X * (part of GCOS) field from the password entry for this user id.
X * Full_username will get overridden by fullname in elmrc, if defined.
X */
X
X if((pass = getpwuid(userid)) == NULL) {
X error("You have no password entry!");
X Raw(OFF);
X exit(1);
X }
X strcpy(username, pass->pw_name);
X strcpy(home, pass->pw_dir);
X
X if((cp = get_full_name(username)) != NULL)
X strcpy(full_username, cp);
X else
X strcpy(full_username, username); /* fall back on logname */
X
X#ifdef DEBUG
X if (debug) { /* setup for dprint() statements! */
X char newfname[SLEN], filename[SLEN];
X
X sprintf(filename, "%s/%s", home, DEBUGFILE);
X if (access(filename, ACCESS_EXISTS) == 0) { /* already one! */
X sprintf(newfname,"%s/%s", home, OLDEBUG);
X (void) rename(filename, newfname);
X }
X
X /* Note what we just did up there: we always save the old
X version of the debug file as OLDEBUG, so users can mail
X copies of bug files without trashing 'em by starting up
X the mailer. Dumb, subtle, but easy enough to do!
X */
X
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 chown(filename, userid, groupid); /* file owned by user */
X
X fprintf(debugfile,
X "Debug output of the ELM program (at debug level %d). Version %s\n\n",
X debug, version_buff);
X }
X#endif
X
X /*
X * If debug level is fairly low, ignore keyboard signals
X * until the screen is set up.
X */
X if (debug < 5) {
X signal(SIGINT, SIG_IGN);
X signal(SIGQUIT, SIG_IGN);
X }
X
X if(!check_only && !batch_only) {
X if ((i = InitScreen()) < 0) {
X if (i == -1) {
X printf(
X"Sorry, but you must specify what type of terminal you're on if you want to\n");
X printf(
X"run the \"elm\" program. (You need your environment variable \"TERM\" set.)\n"
X );
X dprint(1,(debugfile,"No $TERM variable in environment!\n"));
X }
X else if (i == -2) {
X printf(
X"You need a cursor-addressable terminal to run \"elm\" and I can't find any\n");
X printf(
X"kind of termcap entry for \"%s\" - check your \"TERM\" setting...\n",
X getenv("TERM"));
X dprint(1,
X (debugfile,"$TERM variable is an unknown terminal type!\n"));
X } else {
X printf("Failed trying to initialize your terminal entry: unknown return code %d\n", i);
X dprint(1, (debugfile, "Initscreen returned unknown code: %d\n",
X i));
X }
X Raw(OFF);
X exit(1); /* all the errors share this exit statement */
X }
X }
X
X if (debug < 5) { /* otherwise let the system trap 'em! */
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 signal(SIGHUP, hup_signal); /* HangUp (line dropped) */
X }
X else {
X dprint(3,(debugfile,
X "\n*** Elm-Internal Signal Handlers Disabled due to debug level %d ***\n\n",
X debug));
X }
X#if defined(SIGVEC) & defined(SV_INTERRUPT)
X alarm_vec.sv_handler = alarm_signal;
X alarm_vec.sv_flags = SV_INTERRUPT;
X sigvec (SIGALRM, &alarm_vec, (struct sigvec *)0); /* Process Timer Alarm */
X#else
X signal(SIGALRM, alarm_signal); /* Process Timer Alarm */
X#endif
X signal(SIGPIPE, pipe_signal); /* Illegal Pipe Operation */
X#ifdef SIGTSTP
X signal(SIGTSTP, sig_user_stop); /* Suspend signal from tty */
X signal(SIGCONT, sig_return_from_user_stop); /* Continue Process */
X#endif
X
X get_term_chars();
X
X /*
X * Get the host name as per configured behavior.
X */
X#ifdef HOSTCOMPILED
X strncpy(hostname, HOSTNAME, sizeof(hostname) - 1);
X hostname[sizeof(hostname) - 1] = '\0';
X#else
X gethostname(hostname, sizeof(hostname));
X#endif
X
X /*
X * now get the domain name, used to build the full name
X */
X gethostdomain(hostdomain, sizeof(hostdomain));
X
X /*
X * now the tough part:
X * we need to make three variables out of this stuff:
X * hostname = just the hostname, as in bangpaths,
X * this is whatever the user gave us so far,
X * we wont change this one
X * hostdomain = this is the domain considered local to this
X * machine, and should be what we got above.
X * hostfullname = this is the full FQDN of this machine,
X * and is a strange combination of the first two.
X * if tail(hostname) == hostdomain
X * then hostfullname = hostname
X * ie: node.ld.domain.type, ld.domain.type -> node.ld.domain.type
X * else if hostname == hostdomain + 1
X * then hostfullname = hostname
X * ie: domain.type, .domain.type -> domain.type
X *
X * else hostfullname = hostname + hostdomain
X * ie: host, .domain.type -> host.domain.type
X * lost yet?
X */
X hostlen = strlen(hostname);
X domlen = strlen(hostdomain);
X if (hostlen >= domlen) {
X if (strcmp(&hostname[hostlen - domlen], hostdomain) == 0)
X strcpy(hostfullname, hostname);
X else {
X strcpy(hostfullname, hostname);
X strcat(hostfullname, hostdomain);
X }
X } else {
X if (strcmp(hostname, hostdomain + 1) == 0)
X strcpy(hostfullname, hostname);
X else {
X strcpy(hostfullname, hostname);
X strcat(hostfullname, hostdomain);
X }
X }
X
X /* Determine the default mail file name.
X *
X * First look for an environment variable MAIL, then
X * use then mailhome if it is not found
X */
X if ((cp = getenv("MAIL")) == NULL)
X sprintf(defaultfile, "%s%s", mailhome, username);
X else
X strcpy(defaultfile, cp);
X
X /* Determine options that might be set in the .elm/elmrc */
X read_rc_file();
X
X /* Determine the mail file to read */
X if (*requestedmfile == '\0')
X strcpy(requestedmfile, defaultfile);
X else if(!expand_filename(requestedmfile, FALSE)) {
X Raw(OFF);
X exit(0);
X }
X if (check_size)
X if(check_mailfile_size(requestedmfile) != 0) {
X Raw(OFF);
X exit(0);
X }
X
X /* check for permissions only if not send only mode file */
X if (! mail_only) {
X if ((errno = can_access(requestedmfile, READ_ACCESS)) != 0) {
X if (strcmp(requestedmfile, defaultfile) != 0 || errno != ENOENT) {
X dprint(1, (debugfile,
X "Error: given file %s as folder - unreadable (%s)!\n",
X requestedmfile, error_name(errno)));
X fprintf(stderr,"Can't open folder '%s' for reading!\n",
X requestedmfile);
X Raw(OFF);
X exit(1);
X }
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 ScreenSize(&LINES, &COLUMNS);
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 && ! check_only) {
X
X /* get the cursor control keys... */
X
X cursor_control = FALSE;
X
X if ((cp = return_value_of("ku")) != NULL) {
X strcpy(up, cp);
X if ((cp = return_value_of("kd")) != NULL) {
X strcpy(down, cp);
X if ((cp = return_value_of("kl")) != NULL) {
X strcpy(left, cp);
X if ((cp = return_value_of("kr")) != NULL) {
X strcpy(right, cp);
X cursor_control = TRUE;
X transmit_functions(ON);
X }
X }
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 /** clear the screen **/
X if(!check_only && !batch_only)
X ClearScreen();
X
X if (! mail_only && ! check_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(requestedmfile, FALSE); /* read in the folder! */
X }
X
X#ifdef DEBUG
X if (debug >= 2 && debug < 10) {
X fprintf(debugfile,
X"hostname = %-20s \tusername = %-20s \tfullname = %-20s\n",
X hostname, username, full_username);
X
X fprintf(debugfile,
X"home = %-20s \teditor = %-20s \trecvd_mail = %-20s\n",
X home, editor, recvd_mail);
X
X fprintf(debugfile,
X"cur_folder = %-20s \tfolders = %-20s \tprintout = %-20s\n",
X cur_folder, folders, printout);
X
X fprintf(debugfile,
X"sent_mail = %-20s \tprefix = %-20s \tshell = %-20s\n\n",
X sent_mail, prefixchars, shell);
X
X if (local_signature[0])
X fprintf(debugfile, "local_signature = \"%s\"\n",
X local_signature);
X if (remote_signature[0])
X fprintf(debugfile, "remote_signature = \"%s\"\n",
X remote_signature);
X if (local_signature[0] || remote_signature[0])
X fprintf(debugfile, "\n");
X }
X#endif
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 term_buff term_buffer;
X
X if (tcgetattr(STANDARD_INPUT,&term_buffer) == -1) {
X dprint(1, (debugfile,
X "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#if defined(TERMIO) || defined(TERMIOS)
X backspace = term_buffer.c_cc[VERASE];
X kill_line = term_buffer.c_cc[VKILL];
X#else
X backspace = term_buffer.sg_erase;
X kill_line = term_buffer.sg_kill;
X#endif
X }
X}
SHAR_EOF
chmod 0444 src/init.c || echo "restore of src/init.c fails"
echo "x - extracting src/leavembox.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/leavembox.c &&
X
Xstatic char rcsid[] = "@(#)$Id: leavembox.c,v 4.1 90/04/28 22:43:18 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 4.1 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989, 1990 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm@DSI.COM dsinc!elm
X *
X *******************************************************************************
X * $Log: leavembox.c,v $
X * Revision 4.1 90/04/28 22:43:18 syd
X * checkin of Elm 2.3 as of Release PL0
X *
X *
X ******************************************************************************/
X
X/** leave current folder, updating etc. as needed...
X
X**/
X
X#include "headers.h"
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef LOCK_BY_FLOCK
X#include <sys/file.h>
X#endif
X#include <errno.h>
X
X/**********
X Since a number of machines don't seem to bother to define the utimbuf
X structure for some *very* obscure reason....
X
X Suprise, though, BSD has a different utime() entirely...*sigh*
X**********/
X
X#ifndef BSD
X# ifdef NOUTIMBUF
X
Xstruct utimbuf {
X time_t actime; /** access time **/
X time_t modtime; /** modification time **/
X };
X
X
X# endif /* NOUTIMBUF */
X#endif /* BSD */
X
Xextern int errno;
X
Xchar *error_name(), *error_description(), *strcpy(), *rindex();
Xunsigned short getegid();
X#ifndef _POSIX_SOURCE
Xunsigned long sleep();
X#endif
X
Xint
Xleave_mbox(resyncing, quitting, prompt)
Xint resyncing, quitting, prompt;
X{
X /** Close folder, deleting some messages, storing others in mbox,
X and keeping others, as directed by user input and elmrc options.
X
X Return 1 Folder altered
X 0 Folder not altered
X -1 New mail arrived during the process and
X closing was aborted.
X If "resyncing" we are just writing out folder to reopen it. We
X therefore only consider deletes and keeps, not stores to mbox.
X Also we don't remove NEW status so that it can be preserved
X across the resync.
X
X If "quitting" and "prompt" is false, then no prompting is done.
X Otherwise prompting is dependent upon the variable
X question_me, as set by an elmrc option. This behavior makes
X the 'q' command prompt just like 'c' and '$', while
X retaining the 'Q' command for a quick exit that never
X prompts.
X **/
X
X FILE *temp;
X char temp_keep_file[SLEN], buffer[SLEN];
X struct stat buf; /* stat command */
X#ifdef BSD
X time_t utime_buffer[2]; /* utime command */
X#else
X struct utimbuf utime_buffer; /* utime command */
X#endif
X register int to_delete = 0, to_store = 0, to_keep = 0, i,
X marked_deleted, marked_read, marked_unread,
X last_sortby, ask_questions, asked_storage_q,
X num_chgd_status, need_to_copy;
X char answer;
X long bytes();
X
X dprint(1, (debugfile, "\n\n-- leaving folder --\n\n"));
X
X if (message_count == 0)
X return(0); /* nothing changed */
X
X ask_questions = ((quitting && !prompt) ? FALSE : question_me);
X
X /* YES or NO on softkeys */
X if (hp_softkeys && ask_questions) {
X define_softkeys(YESNO);
X softkeys_on();
X }
X
X /* Clear the exit dispositions of all messages, just in case
X * they were left set by a previous call to this function
X * that was interrupted by the receipt of new mail.
X */
X for(i = 0; i < message_count; i++)
X headers[i]->exit_disposition = UNSET;
X
X /* Determine if deleted messages are really to be deleted */
X
X /* we need to know if there are none, or one, or more to delete */
X for (marked_deleted=0, i=0; i<message_count && marked_deleted<2; i++)
X if (ison(headers[i]->status, DELETED))
X marked_deleted++;
X
X if(marked_deleted) {
X answer = (always_del ? 'y' : 'n'); /* default answer */
X if(ask_questions) {
X sprintf(buffer, "Delete message%s? (y/n) ", plural(marked_deleted));
X answer = want_to(buffer, answer);
X }
X
X if(answer == 'y') {
X for (i = 0; i < message_count; i++) {
X if (ison(headers[i]->status, DELETED)) {
X headers[i]->exit_disposition = DELETE;
X to_delete++;
X }
X }
X }
X }
X dprint(3, (debugfile, "Messages to delete: %d\n", to_delete));
X
X /* If this is a non spool file, or if we are merely resyncing,
X * all messages with an unset disposition (i.e. not slated for
X * deletion) are to be kept.
X * Otherwise, we need to determine if read and unread messages
X * are to be stored or kept.
X */
X if(folder_type == NON_SPOOL || resyncing) {
X to_store = 0;
X for (i = 0; i < message_count; i++) {
X if(headers[i]->exit_disposition == UNSET) {
X headers[i]->exit_disposition = KEEP;
X to_keep++;
X }
X }
X } else {
X
X /* Let's first see if user wants to store read messages
X * that aren't slated for deletion */
X
X asked_storage_q = FALSE;
X
X /* we need to know if there are none, or one, or more marked read */
X for (marked_read=0, i=0; i < message_count && marked_read < 2; i++) {
X if((isoff(headers[i]->status, UNREAD))
X && (headers[i]->exit_disposition == UNSET))
X marked_read++;
X }
X if(marked_read) {
X answer = (always_store ? 'y' : 'n'); /* default answer */
X if(ask_questions) {
X sprintf(buffer, "Move read message%s to \"received\" folder? (y/n) ",
X plural(marked_read));
X answer = want_to(buffer, answer);
X asked_storage_q = TRUE;
X }
X
X for (i = 0; i < message_count; i++) {
X if((isoff(headers[i]->status, UNREAD))
X && (headers[i]->exit_disposition == UNSET)) {
X
X if(answer == 'y') {
X headers[i]->exit_disposition = STORE;
X to_store++;
X } else {
X headers[i]->exit_disposition = KEEP;
X to_keep++;
X }
X }
X }
X }
X
X /* If we asked the user if read messages should be stored,
X * and if the user wanted them kept instead, then certainly the
X * user would want the unread messages kept as well.
X */
X if(asked_storage_q && answer == 'n') {
X
X for (i = 0; i < message_count; i++) {
X if((ison(headers[i]->status, UNREAD))
X && (headers[i]->exit_disposition == UNSET)) {
X headers[i]->exit_disposition = KEEP;
X to_keep++;
X }
X }
X
X } else {
X
X /* Determine if unread messages are to be kept */
X
X /* we need to know if there are none, or one, or more unread */
X for (marked_unread=0, i=0; i<message_count && marked_unread<2; i++)
X if((ison(headers[i]->status, UNREAD))
X && (headers[i]->exit_disposition == UNSET))
X marked_unread++;
X
X if(marked_unread) {
X answer = (always_keep ? 'y' : 'n'); /* default answer */
X if(ask_questions) {
X sprintf(buffer,
X "Keep unread message%s in incoming mailbox? (y/n) ",
X plural(marked_unread));
X answer = want_to(buffer, answer);
X }
X
X for (i = 0; i < message_count; i++) {
X if((ison(headers[i]->status, UNREAD))
X && (headers[i]->exit_disposition == UNSET)) {
X
X if(answer == 'n') {
X headers[i]->exit_disposition = STORE;
X to_store++;
X } else {
X headers[i]->exit_disposition = KEEP;
X to_keep++;
X }
X
X }
X }
X }
X }
X }
X
X dprint(3, (debugfile, "Messages to store: %d\n", to_store));
X dprint(3, (debugfile, "Messages to keep: %d\n", to_keep));
X
X if(to_delete + to_store + to_keep != message_count) {
X dprint(1, (debugfile,
X "Error: %d to delete + %d to store + %d to keep != %d message cnt\n",
X to_delete, to_store, to_keep, message_count));
X error("Something wrong in message counts! Folder unchanged.");
X emergency_exit();
X }
X
X
X /* If we are not resyncing, we are leaving the mailfile and
X * the new messages are new no longer. Note that this changes
X * their status.
X */
X if(!resyncing) {
X for (i = 0; i < message_count; i++) {
X if (ison(headers[i]->status, NEW)) {
X clearit(headers[i]->status, NEW);
X headers[i]->status_chgd = TRUE;
X }
X }
X }
X
X /* If all messages are to be kept and none have changed status
X * we don't need to do anything because the current folder won't
X * be changed by our writing it out - unless we are resyncing, in
X * which case we force the writing out of the mailfile.
SHAR_EOF
echo "End of part 16"
echo "File src/leavembox.c is continued in part 17"
echo "17" > s2_seq_.tmp
exit 0
exit 0 # Just in case...