v18i094: Elm mail system, release 2.2, Part15/24
Rich Salz
rsalz at uunet.uu.net
Thu Apr 13 07:19:14 AEST 1989
Submitted-by: dsinc!syd at uunet.UU.NET (Syd Weinstein)
Posting-number: Volume 18, Issue 94
Archive-name: elm2.2/part15
#!/bin/sh
# this is part 15 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file src/forms.c continued
#
CurArch=15
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/forms.c"
sed 's/^X//' << 'SHAR_EOF' >> src/forms.c
X}
X
Xint
Xmail_filled_in_form(address, subject)
Xchar *address, *subject;
X{
X /** This is the interesting routine. This one will read the
X message and prompt the user, line by line, for each of
X the fields...returns non-zero if it succeeds
X **/
X
X FILE *fd;
X register int lines = 0, count;
X char buffer[SLEN], *ptr;
X
X dprint(4, (debugfile,
X "replying to form with;\n\taddress=%s and\n\t subject=%s\n",
X address, subject));
X
X if (fseek(mailfile, headers[current-1]->offset, 0) == -1) {
X dprint(1, (debugfile,
X "Error: seek %ld resulted in errno %s (%s)\n",
X headers[current-1]->offset, error_name(errno),
X "mail_filled_in_form"));
X error2("ELM [seek] couldn't read %d bytes into file (%s).",
X headers[current-1]->offset, error_name(errno));
X return(0);
X }
X
X /* now we can fly along and get to the message body... */
X
X while ((ptr = fgets(buffer, SLEN, mailfile)) != NULL) {
X if (strlen(buffer) == 1) /* <return> only */
X break;
X else if (strncmp(buffer,"From ", 5) == 0 && lines++ > 0) {
X error("No form in this message!?");
X return(0);
X }
X }
X
X if (ptr == NULL) {
X error("No form in this message!?");
X return(0);
X }
X
X dprint(6, (debugfile, "- past header of form message -\n"));
X
X /* at this point we're at the beginning of the body of the message */
X
X /* now we can skip to the FORM-IMAGE section by reading through a
X line with a triple asterisk... */
X
X while ((ptr = fgets(buffer, SLEN, mailfile)) != NULL) {
X if (strcmp(buffer, "***\n") == 0)
X break; /* we GOT it! It's a miracle! */
X else if (strncmp(buffer, "From ",5) == 0) {
X error("Badly constructed form. Can't reply!");
X return(0);
X }
X }
X
X if (ptr == NULL) {
X error("Badly constructed form. Can't reply!");
X return(0);
X }
X
X dprint(6, (debugfile, "- skipped the non-forms-image stuff -\n"));
X
X /* one last thing - let's open the tempfile for output... */
X
X sprintf(buffer, "%s%d", temp_form_file, getpid());
X
X dprint(2, (debugfile,"-- forms sending using file %s --\n", buffer));
X
X if ((fd = fopen(buffer,"w")) == NULL) {
X error2("Can't open \"%s\" as output file! (%s).", buffer,
X error_name(errno));
X dprint(1, (debugfile,
X "** Error %s encountered trying to open temp file %s;\n",
X error_name(errno), buffer));
X return(0);
X }
X
X /* NOW we're ready to read the form image in and start prompting... */
X
X Raw(OFF);
X ClearScreen();
X
X while ((ptr = fgets(buffer, SLEN, mailfile)) != NULL) {
X dprint(9, (debugfile, "- read %s", buffer));
X if (strcmp(buffer, "***\n") == 0) /* end of form! */
X break;
X
X switch ((count = occurances_of(COLON, buffer))) {
X case 0 : printf("%s", buffer); /* output line */
X fprintf(fd, "%s", buffer);
X break;
X case 1 : if (buffer[0] == COLON) {
X printf(
X"(Enter as many lines as needed, ending with a '.' by itself on a line)\n");
X while (fgets(buffer, SLEN, stdin) != NULL)
X no_ret(buffer);
X if (strcmp(buffer, ".") == 0)
X break;
X else
X fprintf(fd,"%s\n", buffer);
X }
X else
X prompt_for_entry(buffer, fd);
X break;
X default: prompt_for_multiple_entries(buffer, fd, count);
X }
X }
X
X Raw(ON);
X fclose(fd);
X
X /** let's just mail this off now... **/
X
X mail_form(address, subject);
X
X return(1);
X}
X
Xprompt_for_entry(buffer, fd)
Xchar *buffer;
XFILE *fd;
X{
X /** This is called with an entry of the form "prompt:" and will
X display the prompt and save the prompt and the user reply
X in the file "fd"
X **/
X
X char mybuffer[SLEN];
X
X no_ret(buffer);
X
X dprint(7, (debugfile, "prompt-for-entry \"%s\"\n", buffer));
X
X printf("%s ", buffer); fflush(stdout);
X
X fgets(mybuffer, SLEN, stdin);
X
X fprintf(fd, "%s: %s", buffer, mybuffer);
X}
X
Xprompt_for_multiple_entries(buffer, fd, entries)
Xchar *buffer;
XFILE *fd;
Xint entries;
X{
X /** Almost the same as the above routine, this one deals with lines
X that have multiple colons on them. It must first figure out how
X many spaces to allocate for each field then prompts the user,
X line by line, for the entries...
X **/
X
X char mybuffer[SLEN], prompt[SLEN], spaces[SLEN];
X register int field_size, i, j, offset = 0, extra_tabs = 0;
X
X dprint(7, (debugfile,
X "prompt-for-multiple [%d] -entries \"%s\"\n", entries,
X buffer));
X
X strcpy(prompt, "No Prompt Available:");
X
X while (entries--) {
X j=0;
X i = chloc((char *) buffer + offset, COLON) + 1;
X while (j < i - 1) {
X prompt[j] = buffer[j+offset];
X j++;
X }
X prompt[j] = '\0';
X
X field_size = 0;
X
X while (whitespace(buffer[i+offset])) {
X if (buffer[i+offset] == TAB) {
X field_size += 8 - (i % 8);
X extra_tabs += (8 - (i % 8)) - 1;
X }
X else
X field_size += 1;
X i++;
X }
X
X offset += i;
X
X if (field_size == 0) /* probably last prompt in line... */
X field_size = 80 - (offset + extra_tabs);
X
X prompt_for_sized_entry(prompt, mybuffer, field_size);
X
X spaces[0] = ' '; /* always at least ONE trailing space... */
X spaces[1] = '\0';
X
X for (j = strlen(mybuffer); j < field_size; j++)
X strcat(spaces, " ");
X
X fprintf(fd, "%s: %s%s", prompt, mybuffer, spaces);
X fflush(fd);
X }
X
X fprintf(fd, "\n");
X}
X
Xprompt_for_sized_entry(prompt, buffer, field_size)
Xchar *prompt, *buffer;
Xint field_size;
X{
X /* This routine prompts for an entry of the size specified. */
X
X register int i;
X
X dprint(7, (debugfile, "prompt-for-sized-entry \"%s\" %d chars\n",
X prompt, field_size));
X
X printf("%s : ", prompt);
X
X for (i=0;i<field_size; i++)
X putchar('_');
X for (i=0;i<field_size; i++)
X putchar(BACKSPACE);
X fflush(stdout);
X
X fgets(buffer, SLEN, stdin);
X no_ret(buffer);
X
X if (strlen(buffer) > field_size) buffer[field_size-1] = '\0';
X}
SHAR_EOF
echo "File src/forms.c is complete"
chmod 0444 src/forms.c || echo "restore of src/forms.c fails"
echo "x - extracting src/hdrconfg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > src/hdrconfg.c &&
X
Xstatic char rcsid[] = "@(#)$Id: hdrconfg.c,v 2.12 89/03/25 21:46:24 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.12 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: hdrconfg.c,v $
X * Revision 2.12 89/03/25 21:46:24 syd
X * Initial 2.2 Release checkin
X *
X *
X ******************************************************************************/
X
X/** This file contains the routines necessary to be able to modify
X the mail headers of messages on the way off the machine. The
X headers currently supported for modification are:
X
X Subject:
X To:
X Cc:
X Bcc:
X Reply-To:
X Expires:
X Priority:
X In-Reply-To:
X Action:
X
X <user defined>
X**/
X
X#include "headers.h"
X
X#include <ctype.h>
X
X#ifdef BSD
X#undef toupper
X#endif
X
X/* allow two lines for address-type headers, subject, and in-reply-to */
X/* allow one line for all others - unlikely to exceed one line */
X#define TO_LINE 2
X#define CC_LINE 4
X#define BCC_LINE 6
X#define SUBJECT_LINE 8
X#define REPLY_TO_LINE 10
X#define ACTION_LINE 11
X#define EXPIRES_LINE 12
X#define PRIORITY_LINE 13
X#define IN_REPLY_TO_LINE 14
X#define USER_DEFINED_HDR_LINE 16
X#define INSTRUCT_LINE LINES-5
X#define EXTRA_PROMPT_LINE LINES-3
X#define INPUT_LINE LINES-2
X#define ERROR_LINE LINES-1
X
X#define put_to() {ClearLine(TO_LINE+1);\
X PutLine1(TO_LINE,0,"To: %s",expanded_to);CleartoEOLN();}
X
X#define put_cc() {ClearLine(CC_LINE+1);\
X PutLine1(CC_LINE,0,"Cc: %s", expanded_cc);CleartoEOLN();}
X
X#define put_bcc() {ClearLine(BCC_LINE+1);\
X PutLine1(BCC_LINE,0,"Bcc: %s",expanded_bcc);CleartoEOLN();}
X
X#define put_replyto() {PutLine1(REPLY_TO_LINE,0,"Reply-to: %s",reply_to);\
X CleartoEOLN();}
X
X#define put_subject() {ClearLine(SUBJECT_LINE+1);\
X PutLine1(SUBJECT_LINE,0,"Subject: %s",subject);CleartoEOLN();}
X
X#define put_action() {PutLine1(ACTION_LINE,0,"Action: %s",action);\
X CleartoEOLN();}
X
X#define put_expires() {PutLine1(EXPIRES_LINE,0,"Expires: %s",expires);\
X CleartoEOLN();}
X
X#define put_priority() {PutLine1(PRIORITY_LINE,0,"Priority: %s",priority);\
X CleartoEOLN();}
X
X#define put_inreplyto() {ClearLine(IN_REPLY_TO_LINE+1);\
X PutLine1(IN_REPLY_TO_LINE,0,"In-reply-to: %s",in_reply_to);CleartoEOLN();}
X
X#define put_userdefined() {PutLine1(USER_DEFINED_HDR_LINE,0,"%s",\
X user_defined_header);CleartoEOLN();}
X
X/* these are all defined in the mailmsg file! */
Xextern char subject[SLEN], in_reply_to[SLEN], expires[SLEN],
X action[SLEN], priority[SLEN], reply_to[SLEN], to[VERY_LONG_STRING],
X cc[VERY_LONG_STRING], expanded_to[VERY_LONG_STRING],
X expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN],
X bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
X
Xchar *strip_commas(), *strcpy();
X
Xedit_headers()
X{
X /** Edit headers. **/
X int c;
X
X /* Expand address-type headers for main part of display */
X /* (Unexpanded ones are used on the 'edit-line') */
X (void) build_address(strip_commas(to), expanded_to);
X (void) build_address(strip_commas(cc), expanded_cc);
X (void) build_address(strip_commas(bcc), expanded_bcc);
X
X display_headers();
X
X clearerr(stdin);
X
X clearerr(stdin);
X
X while (TRUE) { /* forever */
X PutLine0(INPUT_LINE,0,"Choice: ");
X CleartoEOS();
X c = getchar();
X c = toupper(c);
X clear_error();
X if (c == EOF)
X return(0);
X switch (c) {
X case RETURN:
X case LINE_FEED:
X case 'Q' : return(0);
X case ctrl('L') : display_headers();
X break;
X case 'T' : PutLine0(INPUT_LINE, 0, "To: "); CleartoEOLN();
X if (optionally_enter(to, INPUT_LINE, 4, TRUE, FALSE) == -1)
X return(0);
X (void) build_address(strip_commas(to), expanded_to);
X put_to();
X break;
X case 'S' : PutLine0(INPUT_LINE, 0, "Subject: "); CleartoEOLN();
X if (optionally_enter(subject,
X INPUT_LINE, 9, FALSE, FALSE) == -1)
X return(0);
X put_subject();
X break;
X case 'B' : PutLine0(INPUT_LINE, 0, "Bcc: "); CleartoEOLN();
X if (optionally_enter(bcc,
X INPUT_LINE, 5, TRUE, FALSE) == -1)
X return(0);
X (void) build_address(strip_commas(bcc), expanded_bcc);
X put_bcc();
X break;
X case 'C' : PutLine0(INPUT_LINE, 0, "Cc: "); CleartoEOLN();
X if (optionally_enter(cc, INPUT_LINE, 4, TRUE, FALSE) == -1)
X return(0);
X (void) build_address(strip_commas(cc), expanded_cc);
X put_cc();
X break;
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(INPUT_LINE, 9, 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 /** else fall through as an error **/
X default : Centerline(ERROR_LINE, "Unknown header being specified!");
X }
X }
X}
X
Xdisplay_headers()
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 (strlen(in_reply_to) > 0) put_inreplyto();
X if (strlen(user_defined_header) > 0) put_userdefined();
X
X Centerline(INSTRUCT_LINE,
X"Choose first letter of existing header, u)ser defined header, or <return>.");
X}
X
Xenter_date(x, y, datebuf)
Xint x, y;
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
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 2.13 89/03/25 21:46:26 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.13 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: help.c,v $
X * Revision 2.13 89/03/25 21:46:26 syd
X * Initial 2.2 Release checkin
X *
X *
X ******************************************************************************/
X
X/*** help routine for ELM program
X
X***/
X
X#include <ctype.h>
X#include "headers.h"
X
Xhelp(pager)
Xint pager;
X{
X /** Process the request for help [section] from the user.
X If pager is TRUE, then act a little differently from
X if pager 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
X MoveCursor(LINES-4,0);
X CleartoEOS();
X
X if(pager) {
X put_border();
X Centerline(LINES,
X "Press keys you want help for, '?' for a list, or '.' to end.");
X prompt_line = LINES-3;
X } else {
X Centerline(LINES-4, "ELM Help System");
X Centerline(LINES-3,
X "Press keys you want help for, '?' for a list, or '.' to end.");
X prompt_line = LINES-2;
X }
X info_line = prompt_line + 1;
X
X PutLine0(prompt_line, 0, "Help on key: ");
X
X do {
X MoveCursor(prompt_line, strlen("Help on key: "));
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? PAGER_HELP : MAIN_HELP);
X return(1);
X
X case '$': if(!pager) 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) 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) 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)
X s = "* = Go to the last message in the current folder.";
X break;
X
X case '-': if(!pager) s =
X"- = Go to the previous page of messages. This is the same as the LEFT arrow.";
X break;
X
X case '=': if(!pager) s =
X "'=' = Go to the first message in the current folder.";
X break;
X
X case ' ': if(pager) 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)
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)
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) s =
X "^ = Toggle the Delete/Undelete status of the current message.";
X break;
X
X case 'a': if(!pager) 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) 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) s =
X "^D = Mark for deletion all messages with the specified pattern.";
X break;
X
X case 'e': if(!pager) 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) 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) 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)
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) 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) 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) 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) s =
X "Q = Quick quit the mailer, save read, leave unread, delete deleted.";
X break;
X
X case '\n':
X case '\r': if(pager)
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) s = "^L = Rewrite the screen.";
X break;
X
X case ctrl('?'): /* DEL */
X case ctrl('Q'): if(!pager) s = "Exit the mail system quickly.";
X break;
X
X default : if (isdigit(ch) && !pager)
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.",buffer);
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 2.13 89/03/25 21:46:28 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.13 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: in_utils.c,v $
X * Revision 2.13 89/03/25 21:46:28 syd
X * Initial 2.2 Release checkin
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 explicitly
X use backspace-space-backspace sequences)
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,
X use_cursor_control, escaped = OFF;
X
X clearerr(stdin);
X
X if(!passwd) {
X if(use_cursor_control = (x >=0 && y >= 0))
X PutLine1(x, y, "%s", string);
X else
X printf("%s", string);
X }
X
X CleartoEOLN();
X
X if (! append_current) {
X if (use_cursor_control)
X MoveCursor(x,y);
X else if(!passwd)
X non_destructive_back_up(strlen(string));
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 || (ch < ' ' || 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 if (use_cursor_control) {
X PutLine1(x,y, "%s", string);
X CleartoEOLN();
X }
X else
X printf("\n\r%s", string);
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 if (use_cursor_control)
X MoveCursor(x,y);
X else
X back_up(iindex);
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 && (ch < ' ' || 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 || (ch < ' ' || 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 (ch < ' ' || 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
Xback_up(spaces)
Xint spaces;
X{
X /** this routine is to replace the goto x,y call for when sending
X mail without starting the entire "elm" system up... **/
X
X while (spaces--) {
X erase_a_char();
X }
X}
X
Xnon_destructive_back_up(spaces)
Xint spaces;
X{
X /** same as back_up() but doesn't ERASE the characters on the screen **/
X
X while (spaces--)
X Writechar(BACKSPACE);
X fflush(stdout);
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.
X **/
X
X int ch;
X
X if (timeout > 0) {
X alarm((unsigned) timeout);
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 }
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 2.24 89/03/25 21:46:31 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.24 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
X *******************************************************************************
X * $Log: init.c,v $
X * Revision 2.24 89/03/25 21:46:31 syd
X * Initial 2.2 Release checkin
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 BSD
X# include <sgtty.h>
X#else
X# include <termio.h>
X#endif
X
X#include <pwd.h>
X
X#ifdef BSD
X# include <sys/time.h>
X#else
X# include <time.h>
X#endif
X
X#include <signal.h>
X#include <ctype.h>
X#include <errno.h>
X
X#ifdef BSD
X#undef 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();
Xunsigned short getgid(), getuid();
Xvoid exit();
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, *getpwuid();
X char *getenv(), *get_full_name();
X
X register int i, j;
X#ifdef VOIDSIG
X void quit_signal(), term_signal(), ill_signal(),
X fpe_signal(), bus_signal(), segv_signal(),
X alarm_signal(), pipe_signal(), hup_signal();
X#else
X int quit_signal(), term_signal(), ill_signal(),
X fpe_signal(), bus_signal(), segv_signal(),
X alarm_signal(), pipe_signal(), hup_signal();
X#endif
X#ifdef SIGTSTP
X#ifdef VOIDSIG
X int sig_user_stop(), sig_return_from_user_stop();
X#else
X int sig_user_stop(), sig_return_from_user_stop();
X#endif
X#endif
X char buffer[SLEN], *cp;
X
X sprintf(version_buff, "%s PL%d", VERSION, PATCHLEVEL);
X Raw(ON);
X
X userid = getuid();
X groupid = getgid();
X
X (void)umask(077); /* make all newly created files private */
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 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(SIGINT, SIG_IGN);
X signal(SIGQUIT, quit_signal); /* Quit signal */
X signal(SIGTERM, term_signal); /* Terminate signal */
X signal(SIGILL, ill_signal); /* Illegal instruction */
X signal(SIGFPE, fpe_signal); /* Floating point exception */
X signal(SIGBUS, bus_signal); /* Bus error */
X signal(SIGSEGV, segv_signal); /* Segmentation Violation */
X 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
X signal(SIGALRM, alarm_signal); /* Process Timer Alarm */
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#ifdef HOSTCOMPILED
X strncpy(hostname, HOSTNAME, sizeof(hostname));
X#else
X gethostname(hostname, sizeof(hostname));
X#endif
X gethostdomain(hostdomain, sizeof(hostdomain));
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 default mail file */
X if(strcmp(requestedmfile, defaultfile) != 0) {
X if ((errno = can_access(requestedmfile, READ_ACCESS))) {
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 /** 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#ifdef BSD
X struct sgttyb term_buffer;
X
X# define TCGETA TIOCGETP
X
X#else
X struct termio term_buffer;
X#endif
X
X if (ioctl(STANDARD_INPUT, TCGETA, &term_buffer) == -1) {
X 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#ifdef BSD
X backspace = term_buffer.sg_erase;
X kill_line = term_buffer.sg_kill;
X#else
X backspace = term_buffer.c_cc[VERASE];
X kill_line = term_buffer.c_cc[VKILL];
X#endif
X }
X}
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 2.26 89/03/25 21:46:33 syd Exp $";
X
X/*******************************************************************************
X * The Elm Mail System - $Revision: 2.26 $ $State: Exp $
X *
X * Copyright (c) 1986, 1987 Dave Taylor
X * Copyright (c) 1988, 1989 USENET Community Trust
X *******************************************************************************
X * Bug reports, patches, comments, suggestions should be sent to:
X *
X * Syd Weinstein, Elm Coordinator
X * elm at dsinc.UUCP dsinc!elm
X *
SHAR_EOF
echo "End of part 15"
echo "File src/leavembox.c is continued in part 16"
echo "16" > s2_seq_.tmp
exit 0
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
More information about the Comp.sources.unix
mailing list