home *** CD-ROM | disk | FTP | other *** search
- 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...
-