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