sources-request@mirror.UUCP (03/12/87)
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