home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume9
/
elm2
/
part16
< prev
next >
Wrap
Text File
|
1987-03-10
|
38KB
|
1,560 lines
Subject: v09i016: ELM Mail System, Part16/19
Newsgroups: mod.sources
Approved: rs@mirror.TMC.COM
Submitted by: Dave Taylor <hplabs!taylor>
Mod.sources: Volume 9, Issue 16
Archive-name: elm2/Part16
#! /bin/sh
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# If this archive is complete, you will see the message:
# "End of archive 16 (of 19)."
# Contents: src/curses.c src/read_rc.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo shar: Extracting \"src/curses.c\" \(16822 characters\)
if test -f src/curses.c ; then
echo shar: Will not over-write existing file \"src/curses.c\"
else
sed "s/^X//" >src/curses.c <<'END_OF_src/curses.c'
X/** curses.c **/
X
X/** This library gives programs the ability to easily access the
X termcap information and write screen oriented and raw input
X programs. The routines can be called as needed, except that
X to use the cursor / screen routines there must be a call to
X InitScreen() first. The 'Raw' input routine can be used
X independently, however.
X
X Modified 2/86 to work (hopefully) on Berkeley systems. If
X there are any problems with BSD Unix, please report them to
X the author at taylor@hplabs (fixed, if possible!)
X
X Modified 5/86 to add memory lock support, thanks to the
X suggested code by Steve Wolf.
X
X Modified (as if I'm keeping track) to add 24,80 defaults
X
X (C) Copyright 1985 Dave Taylor, HP Colorado Networks
X**/
X
X#include "headers.h"
X
X#ifdef RAWMODE
X# ifdef BSD
X# ifndef BSD4.1
X# include <sgtty.h>
X# else
X# include <termio.h>
X# endif
X# else
X# include <termio.h>
X# endif
X#endif
X
X#include <ctype.h>
X
X#ifdef BSD
X#undef tolower
X#endif
X#include "curses.h"
X
X#ifdef RAWMODE
X# define TTYIN 0
X#endif
X
X#ifdef SHORTNAMES
X# define CleartoEOS ClrtoEOS
X# define _clearinverse _clrinv
X# define _cleartoeoln _clrtoeoln
X# define _cleartoeos _clr2eos
X# define _transmit_off xmit_off
X# define _transmit_on xmit_on
X#endif
X
Xextern int debug;
X
X#ifdef RAWMODE
X# ifndef BSD
Xstruct termio _raw_tty,
X _original_tty;
X# else
X# define TCGETA TIOCGETP
X# define TCSETAW TIOCSETP
X
Xstruct sgttyb _raw_tty,
X _original_tty;
X# endif
X
Xstatic int _inraw = 0; /* are we IN rawmode? */
X
X#endif
X
X#ifdef UTS
Xstatic int _clear_screen = 0; /* Next i/o clear screen? */
Xstatic char _null_string[SLEN]; /* a string of nulls... */
X#endif
X
X
X#define DEFAULT_LINES_ON_TERMINAL 24
X#define DEFAULT_COLUMNS_ON_TERMINAL 80
X
Xstatic int _memory_locked = 0; /* are we IN memlock?? */
Xstatic int _line = -1, /* initialize to "trash" */
X _col = -1;
X
Xstatic int _intransmit; /* are we transmitting keys? */
X
Xstatic
Xchar *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
X *_setbold, *_clearbold, *_setunderline, *_clearunderline,
X *_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
X *_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off,
X *_set_memlock, *_clear_memlock;
X
Xstatic
Xint _lines, _columns;
X
Xstatic char _terminal[1024]; /* Storage for terminal entry */
Xstatic char _capabilities[1024]; /* String for cursor motion */
X
Xstatic char *ptr = _capabilities; /* for buffering */
X
Xint outchar(); /* char output for tputs */
Xchar *tgetstr(), /* Get termcap capability */
X *tgoto(); /* and the goto stuff */
X
XInitScreen()
X{
X /* Set up all this fun stuff: returns zero if all okay, or;
X -1 indicating no terminal name associated with this shell,
X -2..-n No termcap for this terminal type known
X */
X
X int tgetent(), /* get termcap entry */
X error;
X char termname[40];
X char *strcpy(), *getenv();
X
X dprint0(8,"InitScreen()\n");
X
X if (getenv("TERM") == NULL) return(-1);
X
X#ifdef UTS
X
X /* use _line for lack of a better variable, what the heck! */
X
X for (_line = 0; _line < SLEN; _line++)
X _null_string[_line] = '\0';
X#endif
X
X if (strcpy(termname, getenv("TERM")) == NULL)
X return(-1);
X
X if ((error = tgetent(_terminal, termname)) != 1)
X return(error-2);
X
X _line = 0; /* where are we right now?? */
X _col = 0; /* assume zero, zero... */
X
X /* load in all those pesky values */
X _clearscreen = tgetstr("cl", &ptr);
X _moveto = tgetstr("cm", &ptr);
X _up = tgetstr("up", &ptr);
X _down = tgetstr("do", &ptr);
X _right = tgetstr("nd", &ptr);
X _left = tgetstr("bs", &ptr);
X _setbold = tgetstr("so", &ptr);
X _clearbold = tgetstr("se", &ptr);
X _setunderline = tgetstr("us", &ptr);
X _clearunderline = tgetstr("ue", &ptr);
X _setinverse = tgetstr("so", &ptr);
X _clearinverse = tgetstr("se", &ptr);
X _sethalfbright = tgetstr("hs", &ptr);
X _clearhalfbright = tgetstr("he", &ptr);
X _cleartoeoln = tgetstr("ce", &ptr);
X _cleartoeos = tgetstr("cd", &ptr);
X _lines = tgetnum("li");
X _columns = tgetnum("co");
X _transmit_on = tgetstr("ks", &ptr);
X _transmit_off = tgetstr("ke", &ptr);
X _set_memlock = tgetstr("ml", &ptr);
X _clear_memlock = tgetstr("mu", &ptr);
X
X
X if (!_left) {
X _left = ptr;
X *ptr++ = '\b';
X *ptr++ = '\0';
X }
X
X return(0);
X}
X
Xchar *return_value_of(termcap_label)
Xchar *termcap_label;
X{
X /** This will return the string kept by termcap for the
X specified capability. Modified to ensure that if
X tgetstr returns a pointer to a transient address
X that we won't bomb out with a later segmentation
X fault (thanks to Dave@Infopro for this one!)
X
X Tweaked to remove padding sequences.
X **/
X
X static char escape_sequence[20];
X register int i=0,j=0;
X char buffer[20];
X char *myptr, *tgetstr(); /* Get termcap capability */
X
X dprint1(9,"return_value_of(%s)\n", termcap_label);
X
X if (strlen(termcap_label) < 2)
X return(NULL);
X
X if (termcap_label[0] == 's' && termcap_label[1] == 'o')
X strcpy(escape_sequence, _setinverse);
X else if (termcap_label[0] == 's' && termcap_label[1] == 'e')
X strcpy(escape_sequence, _clearinverse);
X else if ((myptr = tgetstr(termcap_label, &ptr)) == NULL)
X return( (char *) NULL );
X else
X strcpy(escape_sequence, myptr);
X
X if (chloc(escape_sequence, '$') != -1) {
X while (escape_sequence[i] != '\0') {
X while (escape_sequence[i] != '$' && escape_sequence[i] != '\0')
X buffer[j++] = escape_sequence[i++];
X if (escape_sequence[i] == '$') {
X while (escape_sequence[i] != '>') i++;
X i++;
X }
X }
X buffer[j] = '\0';
X strcpy(escape_sequence, buffer);
X }
X
X return( (char *) escape_sequence);
X}
X
Xtransmit_functions(newstate)
Xint newstate;
X{
X /** turn function key transmission to ON | OFF **/
X
X dprint1(9,"transmit_functions(%s)\n", onoff(newstate));
X
X if (newstate != _intransmit) {
X _intransmit = ! _intransmit;
X if (newstate == ON)
X tputs(_transmit_on, 1, outchar);
X else
X tputs(_transmit_off, 1, outchar);
X fflush(stdout); /* clear the output buffer */
X }
X}
X
X/****** now into the 'meat' of the routines...the cursor stuff ******/
X
XScreenSize(lines, columns)
Xint *lines, *columns;
X{
X /** returns the number of lines and columns on the display. **/
X
X if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
X if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
X
X dprint2(9,"ScreenSize(_,_) returning %d, %d\n", _lines-1, _columns);
X
X *lines = _lines - 1; /* assume index from zero */
X *columns = _columns;
X}
X
XGetXYLocation(x,y)
Xint *x,*y;
X{
X /* return the current cursor location on the screen */
X
X *x = _line;
X *y = _col;
X}
X
XClearScreen()
X{
X /* clear the screen: returns -1 if not capable */
X
X _line = 0; /* clear leaves us at top... */
X _col = 0;
X
X#ifdef UTS
X if (isatube) {
X _clear_screen++; /* queue up for clearing... */
X return(0);
X }
X#endif
X
X if (!_clearscreen)
X return(-1);
X
X tputs(_clearscreen, 1, outchar);
X fflush(stdout); /* clear the output buffer */
X return(0);
X}
X
XMoveCursor(row, col)
Xint row, col;
X{
X /** move cursor to the specified row column on the screen.
X 0,0 is the top left! **/
X
X char *stuff, *tgoto();
X
X /* we don't want to change "rows" or we'll mangle scrolling... */
X
X if (col > COLUMNS) col = COLUMNS;
X if (col < 0) col = 0;
X
X#ifdef UTS
X if (isatube) {
X at row+1, col+1;
X _line = row;
X _col = col;
X return(0);
X }
X#endif
X if (!_moveto)
X return(-1);
X
X if (row == _line) {
X if (col == _col)
X return(0); /* already there! */
X
X else if (abs(col - _col) < 5) { /* within 5 spaces... */
X if (col > _col)
X CursorRight(col - _col);
X else
X CursorLeft(_col - col);
X }
X else { /* move along to the new x,y loc */
X stuff = tgoto(_moveto, col, row);
X tputs(stuff, 1, outchar);
X fflush(stdout);
X }
X }
X else if (col == _col && abs(row - _line) < 5) {
X if (row < _line)
X CursorUp(_line - row);
X else
X CursorDown(row - _line);
X }
X else if (_line == row-1 && col == 0) {
X putchar('\n'); /* that's */
X putchar('\r'); /* easy! */
X fflush(stdout);
X }
X else {
X stuff = tgoto(_moveto, col, row);
X tputs(stuff, 1, outchar);
X fflush(stdout);
X }
X
X _line = row; /* to ensure we're really there... */
X _col = col;
X
X return(0);
X}
X
XCursorUp(n)
Xint n;
X{
X /** move the cursor up 'n' lines **/
X
X _line = (_line-n > 0? _line - n: 0); /* up 'n' lines... */
X
X#ifdef UTS
X if (isatube) {
X at _line+1, _col+1;
X return(0);
X }
X#endif
X if (!_up)
X return(-1);
X
X while (n-- > 0)
X tputs(_up, 1, outchar);
X
X fflush(stdout);
X return(0);
X}
X
X
XCursorDown(n)
Xint n;
X{
X /** move the cursor down 'n' lines **/
X
X _line = (_line+n < LINES? _line + n: LINES); /* down 'n' lines... */
X
X#ifdef UTS
X if (isatube) {
X at _line+1, _col+1 ;
X return(0);
X }
X#endif
X
X if (!_down)
X return(-1);
X
X while (n-- > 0)
X tputs(_down, 1, outchar);
X
X fflush(stdout);
X return(0);
X}
X
X
XCursorLeft(n)
Xint n;
X{
X /** move the cursor 'n' characters to the left **/
X
X _col = (_col - n> 0? _col - n: 0); /* left 'n' chars... */
X
X#ifdef UTS
X if (isatube) {
X at _line+1, _col+1;
X return(0);
X }
X#endif
X
X if (!_left)
X return(-1);
X
X while (n-- > 0)
X tputs(_left, 1, outchar);
X
X fflush(stdout);
X return(0);
X}
X
X
XCursorRight(n)
Xint n;
X{
X /** move the cursor 'n' characters to the right (nondestructive) **/
X
X _col = (_col+n < COLUMNS? _col + n: COLUMNS); /* right 'n' chars... */
X
X#ifdef UTS
X if (isatube) {
X at _line+1, _col+1;
X return(0);
X }
X#endif
X
X if (!_right)
X return(-1);
X
X while (n-- > 0)
X tputs(_right, 1, outchar);
X
X fflush(stdout);
X return(0);
X}
X
X
XStartBold()
X{
X /** start boldface/standout mode **/
X
X if (!_setbold)
X return(-1);
X
X tputs(_setbold, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
X
XEndBold()
X{
X /** compliment of startbold **/
X
X if (!_clearbold)
X return(-1);
X
X tputs(_clearbold, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
X
XStartUnderline()
X{
X /** start underline mode **/
X
X if (!_setunderline)
X return(-1);
X
X tputs(_setunderline, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
X
XEndUnderline()
X{
X /** the compliment of start underline mode **/
X
X if (!_clearunderline)
X return(-1);
X
X tputs(_clearunderline, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
X
XStartHalfbright()
X{
X /** start half intensity mode **/
X
X if (!_sethalfbright)
X return(-1);
X
X tputs(_sethalfbright, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
XEndHalfbright()
X{
X /** compliment of starthalfbright **/
X
X if (!_clearhalfbright)
X return(-1);
X
X tputs(_clearhalfbright, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
XStartInverse()
X{
X /** set inverse video mode **/
X
X if (!_setinverse)
X return(-1);
X
X tputs(_setinverse, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
X
XEndInverse()
X{
X /** compliment of startinverse **/
X
X if (!_clearinverse)
X return(-1);
X
X tputs(_clearinverse, 1, outchar);
X fflush(stdout);
X return(0);
X}
X
Xint
XHasMemlock()
X{
X /** returns TRUE iff memory locking is available (a terminal
X feature that allows a specified portion of the screen to
X be "locked" & not cleared/scrolled... **/
X
X return ( _set_memlock && _clear_memlock );
X}
X
Xstatic int _old_LINES;
X
Xint
XStartMemlock()
X{
X /** mark the current line as the "last" line of the portion to
X be memory locked (always relative to the top line of the
X screen) Note that this will alter LINES so that it knows
X the top is locked. This means that (plus) the program
X will scroll nicely but (minus) End memlock MUST be called
X whenever we leave the locked-memory part of the program! **/
X
X if (! _set_memlock)
X return(-1);
X
X if (! _memory_locked) {
X
X _old_LINES = LINES;
X LINES -= _line; /* we can't use this for scrolling */
X
X tputs(_set_memlock, 1, outchar);
X fflush(stdout);
X _memory_locked = TRUE;
X }
X
X return(0);
X}
X
Xint
XEndMemlock()
X{
X /** Clear the locked memory condition... **/
X
X if (! _set_memlock)
X return(-1);
X
X if (_memory_locked) {
X LINES = _old_LINES; /* back to old setting */
X
X tputs(_clear_memlock, 1, outchar);
X fflush(stdout);
X _memory_locked = FALSE;
X }
X return(0);
X}
X
X
XWritechar(ch)
Xchar ch;
X{
X /** write a character to the current screen location. **/
X
X#ifdef UTS
X char buffer[2]; /* can't output characters! */
X
X if (isatube) {
X buffer[0] = ch;
X buffer[1] = '\0';
X
X at _line+1, _col+1;
X panel (noerase, noinit, noread) {
X #ON, buffer, 1#
X }
X }
X else
X#endif
X putchar(ch);
X
X if (ch == BACKSPACE) /* moved BACK one! */
X _col--;
X else if (ch >= ' ') /* moved FORWARD one! */
X _col++;
X}
X
X/*VARARGS2*/
X
XWrite_to_screen(line, argcount, arg1, arg2, arg3)
Xchar *line;
Xint argcount, arg1, arg2, arg3;
X{
X /** This routine writes to the screen at the current location.
X when done, it increments lines & columns accordingly by
X looking for "\n" sequences... **/
X
X switch (argcount) {
X case 0 :
X PutLine0(_line, _col, line);
X break;
X case 1 :
X PutLine1(_line, _col, line, arg1);
X break;
X case 2 :
X PutLine2(_line, _col, line, arg1, arg2);
X break;
X case 3 :
X PutLine3(_line, _col, line, arg1, arg2, arg3);
X break;
X }
X}
X
XPutLine0(x, y, line)
Xint x,y;
Xchar *line;
X{
X /** Write a zero argument line at location x,y **/
X
X register int i;
X
X#ifdef UTS
X if (isatube) {
X at x+1, y+1;
X panel (init=_clear_screen, noread, erase=_clear_screen) {
X #ON, line, strlen(line)-1#
X }
X _clear_screen = 0;
X _col += printable_chars(line);
X
X /* line wrapped around?? */
X while (_col > COLUMNS) {
X _col -= COLUMNS;
X _line += 1;
X }
X
X /* now let's figure out if we're supposed to do a "<return>" */
X
X for (i=0; i < strlen(line); i++)
X if (line[i] == '\n') {
X _line++;
X _col = 0; /* on new line! */
X }
X return(0);
X }
X#endif
X MoveCursor(x,y);
X printf("%s", line); /* to avoid '%' problems */
X fflush(stdout);
X _col += printable_chars(line);
X
X while (_col > COLUMNS) { /* line wrapped around?? */
X _col -= COLUMNS;
X _line += 1;
X }
X
X /** now let's figure out if we're supposed to do a "<return>" **/
X
X for (i=0; i < strlen(line); i++)
X if (line[i] == '\n') {
X _line++;
X _col = 0; /* on new line! */
X }
X}
X
X/*VARARGS2*/
XPutLine1(x,y, line, arg1)
Xint x,y;
Xchar *line;
Xchar *arg1;
X{
X /** write line at location x,y - one argument... **/
X
X char buffer[VERY_LONG_STRING];
X
X sprintf(buffer, line, arg1);
X
X PutLine0(x, y, buffer);
X}
X
X/*VARARGS2*/
XPutLine2(x,y, line, arg1, arg2)
Xint x,y;
Xchar *line;
Xchar *arg1, *arg2;
X{
X /** write line at location x,y - one argument... **/
X
X char buffer[VERY_LONG_STRING];
X
X sprintf(buffer, line, arg1, arg2);
X
X PutLine0(x, y, buffer);
X}
X
X/*VARARGS2*/
XPutLine3(x,y, line, arg1, arg2, arg3)
Xint x,y;
Xchar *line;
Xchar *arg1, *arg2, *arg3;
X{
X /** write line at location x,y - one argument... **/
X
X char buffer[VERY_LONG_STRING];
X
X sprintf(buffer, line, arg1, arg2, arg3);
X
X PutLine0(x, y, buffer);
X}
X
XCleartoEOLN()
X{
X /** clear to end of line **/
X#ifdef UTS
X char buffer[SLEN];
X register int cols, i = 0;
X
X if (isatube) {
X
X for (cols = _col; cols < COLUMNS; cols++)
X buffer[i++] = ' ';
X
X buffer[i] = '\0';
X
X at _line+1, _col+1;
X panel (noerase, noinit, noread) {
X #ON, buffer, strlen(buffer)-1#
X }
X
X return(0);
X }
X#endif
X
X if (!_cleartoeoln)
X return(-1);
X
X tputs(_cleartoeoln, 1, outchar);
X fflush(stdout); /* clear the output buffer */
X return(0);
X}
X
XCleartoEOS()
X{
X /** clear to end of screen **/
X
X#ifdef UTS
X register int line_at;
X
X if (isatube) {
X for (line_at = _line; line_at < LINES-1; line_at++) {
X panel (noread, noinit, noread) {
X #@ line_at, 1# #ON, _null_string, COLUMNS#
X }
X }
X
X return(0);
X }
X
X#endif
X if (!_cleartoeos)
X return(-1);
X
X tputs(_cleartoeos, 1, outchar);
X fflush(stdout); /* clear the output buffer */
X return(0);
X}
X
X#ifdef RAWMODE
X
XRaw(state)
Xint state;
X{
X /** state is either ON or OFF, as indicated by call **/
X
X if (state == OFF && _inraw) {
X (void) ioctl(TTYIN, TCSETAW, &_original_tty);
X _inraw = 0;
X }
X else if (state == ON && ! _inraw) {
X
X (void) ioctl(TTYIN, TCGETA, &_original_tty); /** current setting **/
X
X (void) ioctl(TTYIN, TCGETA, &_raw_tty); /** again! **/
X#ifdef BSD
X _raw_tty.sg_flags &= ~(ECHO | CRMOD); /* echo off */
X _raw_tty.sg_flags |= CBREAK; /* raw on */
X#else
X _raw_tty.c_lflag &= ~(ICANON | ECHO); /* noecho raw mode */
X
X _raw_tty.c_cc[VMIN] = '\01'; /* minimum # of chars to queue */
X _raw_tty.c_cc[VTIME] = '\0'; /* minimum time to wait for input */
X
X#endif
X (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
X
X _inraw = 1;
X }
X}
X
Xint
XReadCh()
X{
X /** read a character with Raw mode set! **/
X
X register int result;
X char ch;
X
X result = read(0, &ch, 1);
X
X return(result == 0? EOF : ch);
X}
X
X#endif
X
Xoutchar(c)
Xchar c;
X{
X /** output the given character. From tputs... **/
X /** Note: this CANNOT be a macro! **/
X
X putc(c, stdout);
X}
END_OF_src/curses.c
if test 16822 -ne `wc -c <src/curses.c`; then
echo shar: \"src/curses.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: Extracting \"src/read_rc.c\" \(18128 characters\)
if test -f src/read_rc.c ; then
echo shar: Will not over-write existing file \"src/read_rc.c\"
else
sed "s/^X//" >src/read_rc.c <<'END_OF_src/read_rc.c'
X/** read_rc.c **/
X
X/** (C) Copyright 1985, Dave Taylor **/
X
X/** This file contains programs to allow the user to have a .elmrc file
X in their home directory containing any of the following:
X
X fullname= <username string>
X maildir = <directory>
X mailbox = <file>
X editor = <editor>
X savemail= <savefile>
X calendar= <calendar file name>
X shell = <shell>
X print = <print command>
X weedout = <list of headers to weed out>
X prefix = <copied message prefix string>
X pager = <command to use for displaying messages>
X
X--
X signature = <.signature file for all outbound mail>
XOR:
X localsignature = <.signature file for local mail>
X remotesignature = <.signature file for non-local mail>
X--
X
X bounceback= <hop count threshold, or zero to disable>
X timeout = <seconds for main menu timeout or zero to disable>
X userlevel = <0=amateur, 1=okay, 2 or greater = expert!>
X
X sortby = <sent, received, from, size, subject>
X
X alternatives = <list of addresses that forward to us>
X
X and/or the logical arguments:
X
X autocopy [on|off]
X copy [on|off]
X resolve [on|off]
X weed [on|off]
X noheader [on|off]
X titles [on|off]
X editout [on|off]
X savebyname [on|off]
X movepage [on|off]
X pointnew [on|off]
X hpkeypad [on|off]
X hpsoftkeys [on|off]
X alwaysleave [on|off]
X alwaysdel [on|off]
X arrow [on|off]
X menus [on|off]
X forms [on|off]
X warnings [on|off]
X names [on|off]
X ask [on|off]
X keepempty [on|off]
X
X
X Lines starting with '#' are considered comments and are not checked
X any further!
X
X Modified 10/85 to know about "Environment" variables..
X Modified 12/85 for the 'prefix' option
X Modified 2/86 for the new 3.3 flags
X Modified 8/86 (was I supposed to be keeping this up to date?)
X**/
X
X#include <stdio.h>
X#include <ctype.h>
X
X#ifdef BSD
X#undef tolower
X#endif
X
X#include "headers.h"
X
Xchar *shift_lower(), *strtok(), *getenv(), *strcpy();
Xvoid exit();
X
X#define NOTWEEDOUT 0
X#define WEEDOUT 1
X#define ALTERNATIVES 2
X
Xread_rc_file()
X{
X /** this routine does all the actual work of reading in the
X .rc file... **/
X
X FILE *file;
X char buffer[SLEN], filename[SLEN];
X char word1[SLEN], word2[SLEN];
X register int i, errors = 0, last = NOTWEEDOUT, lineno = 0;
X
X sprintf(filename,"%s/%s", home, elmrcfile);
X
X default_weedlist();
X
X alternative_addresses = NULL; /* none yet! */
X
X if ((file = fopen(filename, "r")) == NULL) {
X dprint0(2,"Warning: User has no \".elmrc\" file (read_rc_file)\n");
X return; /* we're done! */
X }
X
X while (fgets(buffer, SLEN, file) != NULL) {
X lineno++;
X no_ret(buffer); /* remove return */
X if (buffer[0] == '#') { /* comment */
X last = NOTWEEDOUT;
X continue;
X }
X if (strlen(buffer) < 2) { /* empty line */
X last = NOTWEEDOUT;
X continue;
X }
X
X breakup(buffer, word1, word2);
X
X strcpy(word1, shift_lower(word1)); /* to lower case */
X
X if (word2[0] == 0 && (last != WEEDOUT || last != ALTERNATIVES)) {
X dprint1(2,"Error: Bad .elmrc entry in users file;\n-> \"%s\"\n",
X buffer);
X fprintf(stderr,
X "Line %d of your \".elmrc\" is badly formed:\n> %s\n",
X lineno, buffer);
X errors++;
X continue;
X }
X
X if (equal(word1,"maildir") || equal(word1,"folders")) {
X expand_env(folders, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "fullname") || equal(word1,"username") ||
X equal(word1, "name")) {
X strcpy(full_username, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "prefix")) {
X for (i=0; i < strlen(word2); i++)
X prefixchars[i] = (word2[i] == '_' ? ' ' : word2[i]);
X prefixchars[i] = '\0';
X
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "shell")) {
X expand_env(shell, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "sort") || equal(word1, "sortby")) {
X strcpy(word2, shift_lower(word2));
X if (equal(word2, "sent"))
X sortby = SENT_DATE;
X else if (equal(word2, "received") || equal(word2,"recieved"))
X sortby = RECEIVED_DATE;
X else if (equal(word2, "from") || equal(word2, "sender"))
X sortby = SENDER;
X else if (equal(word2, "size") || equal(word2, "lines"))
X sortby = SIZE;
X else if (equal(word2, "subject"))
X sortby = SUBJECT;
X else if (equal(word2, "reverse-sent") || equal(word2,"rev-sent"))
X sortby = - SENT_DATE;
X else if (strncmp(word2, "reverse-rec",11) == 0 ||
X strncmp(word2,"rev-rec",7) == 0)
X sortby = - RECEIVED_DATE;
X else if (equal(word2, "reverse-from") || equal(word2, "rev-from")
X || equal(word2,"reverse-sender")|| equal(word2,"rev-sender"))
X sortby = - SENDER;
X else if (equal(word2, "reverse-size") || equal(word2, "rev-size")
X || equal(word2, "reverse-lines")|| equal(word2,"rev-lines"))
X sortby = - SIZE;
X else if (equal(word2, "reverse-subject") ||
X equal(word2, "rev-subject"))
X sortby = - SUBJECT;
X else {
X if (! errors)
X printf("Error reading '.elmrc' file;\n");
X printf("Line %d: Don't know what sort key '%s' specifies!\n",
X lineno, word2);
X errors++;
X continue;
X }
X }
X else if (equal(word1, "mailbox")) {
X expand_env(mailbox, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "editor") || equal(word1,"mailedit")) {
X expand_env(editor, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "savemail") || equal(word1, "saveto")) {
X expand_env(savefile, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "calendar")) {
X expand_env(calendar_file, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "print") || equal(word1, "printmail")) {
X expand_env(printout, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "pager") || equal(word1, "page")) {
X expand_env(pager, word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "signature")) {
X if (equal(shift_lower(word2), "on") ||
X equal(shift_lower(word2), "off")) {
X fprintf(stderr,
X "\"signature\" used in obsolete way in .elmrc file - ignored!\n\r");
X fprintf(stderr,
X "\t(signature should specify the filename to use rather than on/off)\n\r");
X }
X else {
X expand_env(local_signature, word2);
X strcpy(remote_signature, local_signature);
X signature = TRUE;
X }
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "localsignature")) {
X expand_env(local_signature, word2);
X signature = TRUE;
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "remotesignature")) {
X expand_env(remote_signature, word2);
X signature = TRUE;
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "autocopy")) {
X auto_copy = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "copy") || equal(word1, "auto_cc")) {
X auto_cc = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "names")) {
X names_only = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "resolve")) {
X resolve_mode = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "weed")) {
X filter = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "noheader")) {
X noheader = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "titles")) {
X title_messages = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "editout")) {
X edit_outbound = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "savebyname") || equal(word1, "savename")) {
X save_by_name = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "movepage") || equal(word1, "page") ||
X equal(word1, "movewhenpaged")) {
X move_when_paged = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "pointnew") || equal(word1, "pointtonew")) {
X point_to_new = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "keypad") || equal(word1, "hpkeypad")) {
X hp_terminal = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "softkeys") || equal(word1, "hpsoftkeys")) {
X if (hp_softkeys = is_it_on(word2))
X hp_terminal = TRUE; /* must be set also! */
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "arrow")) {
X arrow_cursor = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (strncmp(word1, "form", 4) == 0) {
X allow_forms = (is_it_on(word2)? MAYBE : NO);
X last = NOTWEEDOUT;
X }
X else if (strncmp(word1, "menu", 4) == 0) {
X mini_menu = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (strncmp(word1, "warning", 7) == 0) {
X warnings = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "alwaysleave") || equal(word1, "leave")) {
X always_leave = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "alwaysdelete") || equal(word1, "delete")) {
X always_del = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "ask") || equal(word1, "question")) {
X question_me = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "keep") || equal(word1, "keepempty")) {
X keep_empty_files = is_it_on(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "bounce") || equal(word1, "bounceback")) {
X bounceback = atoi(word2);
X if (bounceback > MAX_HOPS) {
X fprintf(stderr,
X "Warning: bounceback is set to greater than %d (max-hops) - Ignored.\n",
X MAX_HOPS);
X bounceback = 0;
X }
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "userlevel")) {
X user_level = atoi(word2);
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "timeout")) {
X timeout = atoi(word2);
X if (timeout < 10) {
X fprintf(stderr,
X "Warning: timeout is set to less than 10 seconds - Ignored.\n");
X timeout = 0;
X }
X last = NOTWEEDOUT;
X }
X else if (equal(word1, "weedout")) {
X weedout(word2);
X last = WEEDOUT;
X }
X else if (equal(word1, "alternatives")) {
X alternatives(word2);
X last = ALTERNATIVES;
X }
X else if (last == WEEDOUT) /* could be multiple line weedout */
X weedout(buffer);
X else if (last == ALTERNATIVES) /* multi-line addresses */
X alternatives(buffer);
X else {
X fprintf(stderr,
X "Line %d is undefined in your \".elmrc\" file:\n> %s\n",
X lineno, buffer);
X errors++;
X }
X }
X
X if (debug > 10) /** only do this if we REALLY want debug! **/
X dump_rc_results();
X
X if (errors)
X exit(errors);
X}
X
Xweedout(string)
Xchar *string;
X{
X /** This routine is called with a list of headers to weed out. **/
X
X char *strptr, *header;
X register int i;
X
X strptr = string;
X
X while ((header = strtok(strptr, "\t ,\"'")) != NULL) {
X if (strlen(header) > 0) {
X if (weedcount > MAX_IN_WEEDLIST) {
X fprintf(stderr, "Too many weed headers! Leaving...\n");
X exit(1);
X }
X if ((weedlist[weedcount] = (char *) pmalloc(strlen(header) + 1))
X == NULL) {
X fprintf(stderr,
X "Too many weed headers - out of memory! Leaving...\n");
X exit(1);
X }
X
X for (i=0; i< strlen(header); i++)
X if (header[i] == '_') header[i] = ' ';
X
X strcpy(weedlist[weedcount], header);
X weedcount++;
X }
X strptr = NULL;
X }
X}
X
Xalternatives(string)
Xchar *string;
X{
X /** This routine is called with a list of alternative addresses
X that you may receive mail from (forwarded) **/
X
X char *strptr, *address;
X struct addr_rec *current_record, *previous_record;
X
X previous_record = alternative_addresses; /* start 'er up! */
X /* move to the END of the alternative addresses list */
X
X if (previous_record != NULL)
X while (previous_record->next != NULL)
X previous_record = previous_record->next;
X
X strptr = (char *) string;
X
X while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
X if (previous_record == NULL) {
X previous_record = (struct addr_rec *) pmalloc(sizeof
X *alternative_addresses);
X
X strcpy(previous_record->address, address);
X previous_record->next = NULL;
X alternative_addresses = previous_record;
X }
X else {
X current_record = (struct addr_rec *) pmalloc(sizeof
X *alternative_addresses);
X
X strcpy(current_record->address, address);
X current_record->next = NULL;
X previous_record->next = current_record;
X previous_record = current_record;
X }
X strptr = (char *) NULL;
X }
X}
X
Xdefault_weedlist()
X{
X /** Install the default headers to weed out! Many gracious
X thanks to John Lebovitz for this dynamic method of
X allocation!
X **/
X
X static char *default_list[] = { ">From", "In-Reply-To:",
X "References:", "Newsgroups:", "Received:",
X "Apparently-To:", "Message-Id:", "Content-Type:",
X "From", "X-Mailer:", "*end-of-defaults*", NULL
X };
X
X for (weedcount = 0; default_list[weedcount] != NULL; weedcount++) {
X if ((weedlist[weedcount] = (char *)
X pmalloc(strlen(default_list[weedcount]) + 1)) == NULL) {
X fprintf(stderr,
X "\n\rNot enough memory for default weedlist. Leaving.\n\r");
X leave(1);
X }
X strcpy(weedlist[weedcount], default_list[weedcount]);
X }
X}
X
Xint
Xmatches_weedlist(buffer)
Xchar *buffer;
X{
X /** returns true iff the first 'n' characters of 'buffer'
X match an entry of the weedlist **/
X
X register int i;
X
X for (i=0;i < weedcount; i++)
X if (strncmp(buffer, weedlist[i], strlen(weedlist[i])) == 0)
X return(1);
X
X return(0);
X}
X
Xbreakup(buffer, word1, word2)
Xchar *buffer, *word1, *word2;
X{
X /** This routine breaks buffer down into word1, word2 where
X word1 is alpha characters only, and there is an equal
X sign delimiting the two...
X alpha = beta
X For lines with more than one 'rhs', word2 is set to the
X entire string...
X **/
X
X register int i;
X
X for (i=0;i<strlen(buffer) && isalpha(buffer[i]); i++)
X word1[i] = buffer[i];
X
X word1[i++] = '\0'; /* that's the first word! */
X
X /** spaces before equal sign? **/
X
X while (buffer[i] == ' ' || buffer[i] == '\t') i++;
X
X if (buffer[i] == '=') i++;
X
X /** spaces after equal sign? **/
X
X while (buffer[i] == ' ' || buffer[i] == '\t') i++;
X
X if (i < strlen(buffer))
X strcpy(word2, (char *) (buffer + i));
X else
X word2[0] = '\0';
X}
X
Xexpand_env(dest, buffer)
Xchar *dest, *buffer;
X{
X /** expand possible metacharacters in buffer and then copy
X to dest...
X This routine knows about "~" being the home directory,
X and "$xxx" being an environment variable.
X **/
X
X char *word, *string, next_word[SLEN];
X
X if (buffer[0] == '/') {
X dest[0] = '/';
X dest[1] = '\0';
X }
X else
X dest[0] = '\0';
X
X string = (char *) buffer;
X
X while ((word = strtok(string, "/")) != NULL) {
X if (word[0] == '$') {
X next_word[0] = '\0';
X if (getenv((char *) (word + 1)) != NULL)
X strcpy(next_word, getenv((char *) (word + 1)));
X if (strlen(next_word) == 0)
X leave(fprintf(stderr,
X "\n\rCan't expand environment variable '%s'\n\r",
X word));
X }
X else if (word[0] == '~' && word[1] == '\0')
X strcpy(next_word, home);
X else
X strcpy(next_word, word);
X
X sprintf(dest, "%s%s%s", dest,
X (strlen(dest) > 0 && lastch(dest) != '/' ? "/":""),
X next_word);
X
X string = (char *) NULL;
X }
X}
X
X#define on_off(s) (s == 1? "ON" : "OFF")
Xdump_rc_results()
X{
X
X register int i;
X
X fprintf(debugfile, "\n\n\n\n");
X fprintf(debugfile, "folders = %s\n", folders);
X fprintf(debugfile, "mailbox = %s\n", mailbox);
X fprintf(debugfile, "editor = %s\n", editor);
X fprintf(debugfile, "printout = %s\n", printout);
X fprintf(debugfile, "savefile = %s\n", savefile);
X fprintf(debugfile, "calendar_file = %s\n", calendar_file);
X fprintf(debugfile, "prefixchars = %s\n", prefixchars);
X fprintf(debugfile, "shell = %s\n", shell);
X fprintf(debugfile, "pager = %s\n", pager);
X fprintf(debugfile, "\n");
X fprintf(debugfile, "mini_menu = %s\n", on_off(mini_menu));
X fprintf(debugfile, "mbox_specified = %s\n", on_off(mbox_specified));
X fprintf(debugfile, "check_first = %s\n", on_off(check_first));
X fprintf(debugfile, "auto_copy = %s\n", on_off(auto_copy));
X fprintf(debugfile, "filter = %s\n", on_off(filter));
X fprintf(debugfile, "resolve_mode = %s\n", on_off(resolve_mode));
X fprintf(debugfile, "auto_cc = %s\n", on_off(auto_cc));
X fprintf(debugfile, "noheader = %s\n", on_off(noheader));
X fprintf(debugfile, "title_messages = %s\n", on_off(title_messages));
X fprintf(debugfile, "hp_terminal = %s\n", on_off(hp_terminal));
X fprintf(debugfile, "hp_softkeys = %s\n", on_off(hp_softkeys));
X fprintf(debugfile, "save_by_name = %s\n", on_off(save_by_name));
X fprintf(debugfile, "move_when_paged = %s\n", on_off(move_when_paged));
X fprintf(debugfile, "point_to_new = %s\n", on_off(point_to_new));
X fprintf(debugfile, "bounceback = %s\n", on_off(bounceback));
X fprintf(debugfile, "signature = %s\n", on_off(signature));
X fprintf(debugfile, "always_leave = %s\n", on_off(always_leave));
X fprintf(debugfile, "always_del = %s\n", on_off(always_del));
X fprintf(debugfile, "arrow_cursor = %s\n", on_off(arrow_cursor));
X fprintf(debugfile, "names = %s\n", on_off(names_only));
X fprintf(debugfile, "warnings = %s\n", on_off(warnings));
X fprintf(debugfile, "question_me = %s\n", on_off(question_me));
X fprintf(debugfile, "keep_empty_files = %s\n",
X on_off(keep_empty_files));
X
X fprintf(debugfile, "\n** userlevel = %s **\n\n", user_level);
X
X fprintf(debugfile, "Weeding out the following headers;\n");
X for (i=0; i < weedcount; i++)
X fprintf(debugfile, "\t\"%s\"\n", weedlist[i]);
X
X fprintf(debugfile, "\n\n");
X}
X
Xis_it_on(word)
Xchar *word;
X{
X /** Returns TRUE if the specified word is either 'ON', 'YES'
X or 'TRUE', and FALSE otherwise. We explicitly translate
X to lowercase here to ensure that we have the fastest
X routine possible - we really DON'T want to have this take
X a long time or our startup will be major pain each time.
X **/
X
X static char mybuffer[NLEN];
X register int i, j;
X
X for (i=0, j=0; word[i] != '\0'; i++)
X mybuffer[j++] = isupper(word[i]) ? tolower(word[i]) : word[i];
X mybuffer[j] = '\0';
X
X return( (strncmp(mybuffer, "on", 2) == 0) ||
X (strncmp(mybuffer, "yes", 3) == 0) ||
X (strncmp(mybuffer, "true", 4) == 0)
X );
X}
X
X
X
X
X
END_OF_src/read_rc.c
if test 18128 -ne `wc -c <src/read_rc.c`; then
echo shar: \"src/read_rc.c\" unpacked with wrong size!?
fi
# end of overwriting check
fi
echo shar: End of archive 16 \(of 19\).
cp /dev/null ark16isdone
DONE=true
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
if test ! -f ark${I}isdone ; then
echo shar: You still need to run archive ${I}.
DONE=false
fi
done
if test "$DONE" = "true" ; then
echo You have unpacked all 19 archives.
echo "See the Instructions file"
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
fi
## End of shell archive.
exit 0