home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume9 / elm2 / part16 < prev    next >
Text File  |  1987-03-10  |  38KB  |  1,560 lines

  1. Subject:  v09i016:  ELM Mail System, Part16/19
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: Dave Taylor <hplabs!taylor>
  6. Mod.sources: Volume 9, Issue 16
  7. Archive-name: elm2/Part16
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 16 (of 19)."
  14. # Contents:  src/curses.c src/read_rc.c
  15. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  16. echo shar: Extracting \"src/curses.c\" \(16822 characters\)
  17. if test -f src/curses.c ; then 
  18.   echo shar: Will not over-write existing file \"src/curses.c\"
  19. else
  20. sed "s/^X//" >src/curses.c <<'END_OF_src/curses.c'
  21. X/**             curses.c        **/
  22. X
  23. X/**  This library gives programs the ability to easily access the
  24. X     termcap information and write screen oriented and raw input
  25. X     programs.  The routines can be called as needed, except that
  26. X     to use the cursor / screen routines there must be a call to
  27. X     InitScreen() first.  The 'Raw' input routine can be used
  28. X     independently, however.
  29. X
  30. X     Modified 2/86 to work (hopefully) on Berkeley systems.  If
  31. X     there are any problems with BSD Unix, please report them to
  32. X     the author at taylor@hplabs (fixed, if possible!)
  33. X
  34. X     Modified 5/86 to add memory lock support, thanks to the
  35. X     suggested code by Steve Wolf.
  36. X
  37. X     Modified (as if I'm keeping track) to add 24,80 defaults
  38. X
  39. X     (C) Copyright 1985 Dave Taylor, HP Colorado Networks
  40. X**/
  41. X
  42. X#include "headers.h"
  43. X
  44. X#ifdef RAWMODE
  45. X# ifdef BSD
  46. X#  ifndef BSD4.1
  47. X#    include <sgtty.h>
  48. X#  else
  49. X#    include <termio.h>
  50. X#  endif
  51. X# else
  52. X#  include <termio.h>
  53. X# endif
  54. X#endif
  55. X
  56. X#include <ctype.h>
  57. X
  58. X#ifdef BSD
  59. X#undef tolower
  60. X#endif
  61. X#include "curses.h"
  62. X
  63. X#ifdef RAWMODE
  64. X# define TTYIN    0
  65. X#endif
  66. X
  67. X#ifdef SHORTNAMES
  68. X# define CleartoEOS    ClrtoEOS
  69. X# define _clearinverse    _clrinv
  70. X# define _cleartoeoln    _clrtoeoln
  71. X# define _cleartoeos    _clr2eos
  72. X# define _transmit_off    xmit_off
  73. X# define _transmit_on    xmit_on
  74. X#endif
  75. X
  76. Xextern int debug;
  77. X
  78. X#ifdef RAWMODE
  79. X#  ifndef BSD
  80. Xstruct termio _raw_tty, 
  81. X              _original_tty;
  82. X#  else
  83. X#    define TCGETA    TIOCGETP
  84. X#    define TCSETAW    TIOCSETP
  85. X
  86. Xstruct sgttyb _raw_tty,
  87. X          _original_tty;
  88. X#  endif
  89. X
  90. Xstatic int _inraw = 0;                  /* are we IN rawmode?    */
  91. X
  92. X#endif
  93. X
  94. X#ifdef UTS
  95. Xstatic int _clear_screen = 0;        /* Next i/o clear screen? */
  96. Xstatic char _null_string[SLEN];        /* a string of nulls...   */
  97. X#endif
  98. X
  99. X
  100. X#define DEFAULT_LINES_ON_TERMINAL    24
  101. X#define DEFAULT_COLUMNS_ON_TERMINAL    80
  102. X
  103. Xstatic int _memory_locked = 0;        /* are we IN memlock??   */
  104. Xstatic int _line  = -1,            /* initialize to "trash" */
  105. X           _col   = -1;
  106. X
  107. Xstatic int _intransmit;            /* are we transmitting keys? */
  108. X
  109. Xstatic
  110. Xchar *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
  111. X     *_setbold, *_clearbold, *_setunderline, *_clearunderline, 
  112. X     *_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
  113. X     *_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off,
  114. X     *_set_memlock, *_clear_memlock;
  115. X
  116. Xstatic
  117. Xint _lines, _columns;
  118. X
  119. Xstatic char _terminal[1024];              /* Storage for terminal entry */
  120. Xstatic char _capabilities[1024];           /* String for cursor motion */
  121. X
  122. Xstatic char *ptr = _capabilities;    /* for buffering         */
  123. X
  124. Xint    outchar();            /* char output for tputs */
  125. Xchar  *tgetstr(),                    /* Get termcap capability */
  126. X      *tgoto();                /* and the goto stuff    */
  127. X
  128. XInitScreen()
  129. X{
  130. X    /* Set up all this fun stuff: returns zero if all okay, or;
  131. X        -1 indicating no terminal name associated with this shell,
  132. X        -2..-n  No termcap for this terminal type known
  133. X   */
  134. X
  135. X    int  tgetent(),      /* get termcap entry */
  136. X         error;
  137. X    char termname[40];
  138. X    char *strcpy(), *getenv();
  139. X    
  140. X    dprint0(8,"InitScreen()\n");
  141. X
  142. X    if (getenv("TERM") == NULL) return(-1);
  143. X
  144. X#ifdef UTS
  145. X
  146. X    /* use _line for lack of a better variable, what the heck! */
  147. X
  148. X    for (_line = 0; _line < SLEN; _line++)
  149. X        _null_string[_line] = '\0';
  150. X#endif
  151. X
  152. X    if (strcpy(termname, getenv("TERM")) == NULL)
  153. X        return(-1);
  154. X
  155. X    if ((error = tgetent(_terminal, termname)) != 1)
  156. X        return(error-2);
  157. X
  158. X    _line  =  0;        /* where are we right now?? */
  159. X    _col   =  0;        /* assume zero, zero...     */
  160. X
  161. X    /* load in all those pesky values */
  162. X    _clearscreen       = tgetstr("cl", &ptr);
  163. X    _moveto            = tgetstr("cm", &ptr);
  164. X    _up                = tgetstr("up", &ptr);
  165. X    _down              = tgetstr("do", &ptr);
  166. X    _right             = tgetstr("nd", &ptr);
  167. X    _left              = tgetstr("bs", &ptr);
  168. X    _setbold           = tgetstr("so", &ptr);
  169. X    _clearbold         = tgetstr("se", &ptr);
  170. X    _setunderline      = tgetstr("us", &ptr);
  171. X    _clearunderline    = tgetstr("ue", &ptr);
  172. X    _setinverse        = tgetstr("so", &ptr);
  173. X    _clearinverse      = tgetstr("se", &ptr);
  174. X    _sethalfbright     = tgetstr("hs", &ptr);
  175. X    _clearhalfbright   = tgetstr("he", &ptr);
  176. X    _cleartoeoln       = tgetstr("ce", &ptr);
  177. X    _cleartoeos        = tgetstr("cd", &ptr);
  178. X    _lines                 = tgetnum("li");
  179. X    _columns       = tgetnum("co");
  180. X    _transmit_on       = tgetstr("ks", &ptr);
  181. X    _transmit_off      = tgetstr("ke", &ptr);
  182. X    _set_memlock       = tgetstr("ml", &ptr);
  183. X    _clear_memlock       = tgetstr("mu", &ptr);
  184. X
  185. X
  186. X    if (!_left) {
  187. X        _left = ptr;
  188. X        *ptr++ = '\b';
  189. X        *ptr++ = '\0';
  190. X    }
  191. X
  192. X    return(0);
  193. X}
  194. X
  195. Xchar *return_value_of(termcap_label)
  196. Xchar *termcap_label;
  197. X{
  198. X    /** This will return the string kept by termcap for the 
  199. X        specified capability. Modified to ensure that if 
  200. X        tgetstr returns a pointer to a transient address    
  201. X        that we won't bomb out with a later segmentation
  202. X        fault (thanks to Dave@Infopro for this one!)
  203. X
  204. X        Tweaked to remove padding sequences.
  205. X     **/
  206. X
  207. X    static char escape_sequence[20];
  208. X    register int i=0,j=0;
  209. X    char buffer[20];
  210. X    char *myptr, *tgetstr();             /* Get termcap capability */
  211. X
  212. X    dprint1(9,"return_value_of(%s)\n", termcap_label);
  213. X
  214. X    if (strlen(termcap_label) < 2)
  215. X      return(NULL);
  216. X
  217. X    if (termcap_label[0] == 's' && termcap_label[1] == 'o')
  218. X      strcpy(escape_sequence, _setinverse);
  219. X    else if (termcap_label[0] == 's' && termcap_label[1] == 'e')
  220. X      strcpy(escape_sequence, _clearinverse);
  221. X    else if ((myptr = tgetstr(termcap_label, &ptr)) == NULL)
  222. X      return( (char *) NULL );
  223. X    else
  224. X      strcpy(escape_sequence, myptr);
  225. X
  226. X    if (chloc(escape_sequence, '$') != -1) {
  227. X      while (escape_sequence[i] != '\0') {
  228. X        while (escape_sequence[i] != '$' && escape_sequence[i] != '\0')
  229. X          buffer[j++] = escape_sequence[i++];
  230. X        if (escape_sequence[i] == '$') {
  231. X          while (escape_sequence[i] != '>') i++;
  232. X          i++;
  233. X        }
  234. X      }
  235. X      buffer[j] = '\0';
  236. X      strcpy(escape_sequence, buffer);
  237. X    }
  238. X
  239. X    return( (char *) escape_sequence);
  240. X}
  241. X
  242. Xtransmit_functions(newstate)
  243. Xint newstate;
  244. X{
  245. X    /** turn function key transmission to ON | OFF **/
  246. X
  247. X    dprint1(9,"transmit_functions(%s)\n", onoff(newstate));
  248. X
  249. X    if (newstate != _intransmit) {
  250. X        _intransmit = ! _intransmit;
  251. X        if (newstate == ON)
  252. X          tputs(_transmit_on, 1, outchar);
  253. X        else 
  254. X          tputs(_transmit_off, 1, outchar);
  255. X        fflush(stdout);      /* clear the output buffer */
  256. X    }
  257. X}
  258. X
  259. X/****** now into the 'meat' of the routines...the cursor stuff ******/
  260. X
  261. XScreenSize(lines, columns)
  262. Xint *lines, *columns;
  263. X{
  264. X    /** returns the number of lines and columns on the display. **/
  265. X
  266. X    if (_lines == 0) _lines = DEFAULT_LINES_ON_TERMINAL;
  267. X    if (_columns == 0) _columns = DEFAULT_COLUMNS_ON_TERMINAL;
  268. X
  269. X    dprint2(9,"ScreenSize(_,_) returning %d, %d\n", _lines-1, _columns);
  270. X
  271. X    *lines = _lines - 1;        /* assume index from zero */
  272. X    *columns = _columns;
  273. X}
  274. X
  275. XGetXYLocation(x,y)
  276. Xint *x,*y;
  277. X{
  278. X    /* return the current cursor location on the screen */
  279. X
  280. X    *x = _line;
  281. X    *y = _col;
  282. X}
  283. X
  284. XClearScreen()
  285. X{
  286. X    /* clear the screen: returns -1 if not capable */
  287. X
  288. X    _line = 0;    /* clear leaves us at top... */
  289. X    _col  = 0;
  290. X
  291. X#ifdef UTS
  292. X    if (isatube) {
  293. X        _clear_screen++;    /* queue up for clearing... */
  294. X        return(0);
  295. X    }
  296. X#endif
  297. X
  298. X    if (!_clearscreen)
  299. X        return(-1);
  300. X
  301. X    tputs(_clearscreen, 1, outchar);
  302. X    fflush(stdout);      /* clear the output buffer */
  303. X    return(0);
  304. X}
  305. X
  306. XMoveCursor(row, col)
  307. Xint row, col;
  308. X{
  309. X    /** move cursor to the specified row column on the screen.
  310. X            0,0 is the top left! **/
  311. X
  312. X    char *stuff, *tgoto();
  313. X
  314. X    /* we don't want to change "rows" or we'll mangle scrolling... */
  315. X
  316. X    if (col > COLUMNS) col = COLUMNS;
  317. X    if (col < 0)       col = 0;
  318. X
  319. X#ifdef UTS
  320. X    if (isatube) {
  321. X        at row+1, col+1;
  322. X        _line = row;
  323. X        _col  = col;
  324. X        return(0);
  325. X    }
  326. X#endif
  327. X    if (!_moveto)
  328. X        return(-1);
  329. X
  330. X    if (row == _line) {
  331. X      if (col == _col)
  332. X        return(0);                /* already there! */
  333. X
  334. X      else if (abs(col - _col) < 5) {    /* within 5 spaces... */
  335. X        if (col > _col)
  336. X          CursorRight(col - _col);
  337. X        else 
  338. X          CursorLeft(_col - col);
  339. X          }
  340. X      else {        /* move along to the new x,y loc */
  341. X        stuff = tgoto(_moveto, col, row);
  342. X        tputs(stuff, 1, outchar);
  343. X        fflush(stdout);
  344. X      }
  345. X    }
  346. X    else if (col == _col && abs(row - _line) < 5) {
  347. X      if (row < _line)
  348. X        CursorUp(_line - row);
  349. X      else
  350. X        CursorDown(row - _line);
  351. X    }
  352. X    else if (_line == row-1 && col == 0) {
  353. X      putchar('\n');    /* that's */
  354. X      putchar('\r');    /*  easy! */
  355. X      fflush(stdout);
  356. X    }
  357. X    else {
  358. X      stuff = tgoto(_moveto, col, row);
  359. X      tputs(stuff, 1, outchar);
  360. X      fflush(stdout);
  361. X    }
  362. X
  363. X    _line = row;    /* to ensure we're really there... */
  364. X    _col  = col;
  365. X
  366. X    return(0);
  367. X}
  368. X
  369. XCursorUp(n)
  370. Xint n;
  371. X{
  372. X    /** move the cursor up 'n' lines **/
  373. X
  374. X    _line = (_line-n > 0? _line - n: 0);    /* up 'n' lines... */
  375. X
  376. X#ifdef UTS
  377. X    if (isatube) {
  378. X        at _line+1, _col+1;
  379. X        return(0);
  380. X    }
  381. X#endif
  382. X    if (!_up)
  383. X        return(-1);
  384. X
  385. X    while (n-- > 0)
  386. X        tputs(_up, 1, outchar);
  387. X
  388. X    fflush(stdout);
  389. X    return(0);
  390. X}
  391. X
  392. X
  393. XCursorDown(n)
  394. Xint n;
  395. X{
  396. X    /** move the cursor down 'n' lines **/
  397. X
  398. X    _line = (_line+n < LINES? _line + n: LINES);    /* down 'n' lines... */
  399. X
  400. X#ifdef UTS
  401. X    if (isatube) {
  402. X        at _line+1, _col+1 ;
  403. X        return(0);
  404. X    }
  405. X#endif
  406. X
  407. X    if (!_down)
  408. X        return(-1);
  409. X
  410. X    while (n-- > 0)
  411. X        tputs(_down, 1, outchar);
  412. X
  413. X    fflush(stdout);
  414. X    return(0);
  415. X}
  416. X
  417. X
  418. XCursorLeft(n)
  419. Xint n;
  420. X{
  421. X    /** move the cursor 'n' characters to the left **/
  422. X
  423. X    _col = (_col - n> 0? _col - n: 0);    /* left 'n' chars... */
  424. X
  425. X#ifdef UTS
  426. X    if (isatube) {
  427. X        at _line+1, _col+1;
  428. X        return(0);
  429. X    }
  430. X#endif
  431. X
  432. X    if (!_left)
  433. X        return(-1);
  434. X
  435. X    while (n-- > 0)
  436. X        tputs(_left, 1, outchar);
  437. X
  438. X    fflush(stdout);
  439. X    return(0);
  440. X}
  441. X
  442. X
  443. XCursorRight(n)
  444. Xint n;
  445. X{
  446. X    /** move the cursor 'n' characters to the right (nondestructive) **/
  447. X
  448. X    _col = (_col+n < COLUMNS? _col + n: COLUMNS);    /* right 'n' chars... */
  449. X
  450. X#ifdef UTS
  451. X    if (isatube) {
  452. X        at _line+1, _col+1;
  453. X        return(0);
  454. X    }
  455. X#endif
  456. X
  457. X    if (!_right)
  458. X        return(-1);
  459. X
  460. X    while (n-- > 0)
  461. X        tputs(_right, 1, outchar);
  462. X
  463. X    fflush(stdout);
  464. X    return(0);
  465. X}
  466. X
  467. X
  468. XStartBold()
  469. X{
  470. X    /** start boldface/standout mode **/
  471. X
  472. X    if (!_setbold)
  473. X        return(-1);
  474. X
  475. X    tputs(_setbold, 1, outchar);
  476. X    fflush(stdout);
  477. X    return(0);
  478. X}
  479. X
  480. X
  481. XEndBold()
  482. X{
  483. X    /** compliment of startbold **/
  484. X
  485. X    if (!_clearbold)
  486. X        return(-1);
  487. X
  488. X    tputs(_clearbold, 1, outchar);
  489. X    fflush(stdout);
  490. X    return(0);
  491. X}
  492. X
  493. X
  494. XStartUnderline()
  495. X{
  496. X    /** start underline mode **/
  497. X
  498. X    if (!_setunderline)
  499. X        return(-1);
  500. X
  501. X    tputs(_setunderline, 1, outchar);
  502. X    fflush(stdout);
  503. X    return(0);
  504. X}
  505. X
  506. X
  507. XEndUnderline()
  508. X{
  509. X    /** the compliment of start underline mode **/
  510. X
  511. X    if (!_clearunderline)
  512. X        return(-1);
  513. X
  514. X    tputs(_clearunderline, 1, outchar);
  515. X    fflush(stdout);
  516. X    return(0);
  517. X}
  518. X
  519. X
  520. XStartHalfbright()
  521. X{
  522. X    /** start half intensity mode **/
  523. X
  524. X    if (!_sethalfbright)
  525. X        return(-1);
  526. X
  527. X    tputs(_sethalfbright, 1, outchar);
  528. X    fflush(stdout);
  529. X    return(0);
  530. X}
  531. X
  532. XEndHalfbright()
  533. X{
  534. X    /** compliment of starthalfbright **/
  535. X
  536. X    if (!_clearhalfbright)
  537. X        return(-1);
  538. X
  539. X    tputs(_clearhalfbright, 1, outchar);
  540. X    fflush(stdout);
  541. X    return(0);
  542. X}
  543. X
  544. XStartInverse()
  545. X{
  546. X    /** set inverse video mode **/
  547. X
  548. X    if (!_setinverse)
  549. X        return(-1);
  550. X
  551. X    tputs(_setinverse, 1, outchar);
  552. X    fflush(stdout);
  553. X    return(0);
  554. X}
  555. X
  556. X
  557. XEndInverse()
  558. X{
  559. X    /** compliment of startinverse **/
  560. X
  561. X    if (!_clearinverse)
  562. X        return(-1);
  563. X
  564. X    tputs(_clearinverse, 1, outchar);
  565. X    fflush(stdout);
  566. X    return(0);
  567. X}
  568. X
  569. Xint
  570. XHasMemlock()
  571. X{
  572. X    /** returns TRUE iff memory locking is available (a terminal
  573. X        feature that allows a specified portion of the screen to
  574. X        be "locked" & not cleared/scrolled... **/
  575. X
  576. X    return ( _set_memlock && _clear_memlock );
  577. X}
  578. X
  579. Xstatic int _old_LINES;
  580. X
  581. Xint
  582. XStartMemlock()
  583. X{
  584. X    /** mark the current line as the "last" line of the portion to 
  585. X        be memory locked (always relative to the top line of the
  586. X        screen) Note that this will alter LINES so that it knows
  587. X        the top is locked.  This means that (plus) the program 
  588. X        will scroll nicely but (minus) End memlock MUST be called
  589. X        whenever we leave the locked-memory part of the program! **/
  590. X
  591. X    if (! _set_memlock)
  592. X      return(-1);
  593. X
  594. X    if (! _memory_locked) {
  595. X
  596. X      _old_LINES = LINES;
  597. X      LINES -= _line;        /* we can't use this for scrolling */
  598. X
  599. X      tputs(_set_memlock, 1, outchar);
  600. X      fflush(stdout);
  601. X      _memory_locked = TRUE;
  602. X    }
  603. X
  604. X    return(0);
  605. X}
  606. X
  607. Xint
  608. XEndMemlock()
  609. X{
  610. X    /** Clear the locked memory condition...  **/
  611. X
  612. X    if (! _set_memlock)
  613. X      return(-1);
  614. X
  615. X    if (_memory_locked) {
  616. X      LINES = _old_LINES;        /* back to old setting */
  617. X  
  618. X      tputs(_clear_memlock, 1, outchar);
  619. X      fflush(stdout);
  620. X      _memory_locked = FALSE;
  621. X    }
  622. X    return(0);
  623. X}
  624. X
  625. X
  626. XWritechar(ch)
  627. Xchar ch;
  628. X{
  629. X    /** write a character to the current screen location. **/
  630. X
  631. X#ifdef UTS
  632. X    char buffer[2];    /* can't output characters! */
  633. X
  634. X    if (isatube) {
  635. X      buffer[0] = ch;
  636. X      buffer[1] = '\0';
  637. X
  638. X      at _line+1, _col+1;
  639. X      panel (noerase, noinit, noread) {
  640. X        #ON, buffer, 1#
  641. X      }
  642. X     }
  643. X    else
  644. X#endif
  645. X      putchar(ch);
  646. X
  647. X    if (ch == BACKSPACE)    /* moved BACK one! */
  648. X        _col--;
  649. X    else if (ch >= ' ')    /* moved FORWARD one! */
  650. X        _col++;
  651. X}
  652. X
  653. X/*VARARGS2*/
  654. X
  655. XWrite_to_screen(line, argcount, arg1, arg2, arg3)
  656. Xchar *line;
  657. Xint   argcount, arg1, arg2, arg3;
  658. X{
  659. X    /** This routine writes to the screen at the current location.
  660. X          when done, it increments lines & columns accordingly by
  661. X        looking for "\n" sequences... **/
  662. X
  663. X    switch (argcount) {
  664. X    case 0 :
  665. X        PutLine0(_line, _col, line);
  666. X        break;
  667. X    case 1 :
  668. X        PutLine1(_line, _col, line, arg1);
  669. X        break;
  670. X    case 2 :
  671. X        PutLine2(_line, _col, line, arg1, arg2);
  672. X        break;
  673. X    case 3 :
  674. X        PutLine3(_line, _col, line, arg1, arg2, arg3);
  675. X        break;
  676. X    }
  677. X}
  678. X
  679. XPutLine0(x, y, line)
  680. Xint x,y;
  681. Xchar *line;
  682. X{
  683. X    /** Write a zero argument line at location x,y **/
  684. X
  685. X    register int i;
  686. X
  687. X#ifdef UTS
  688. X    if (isatube) {
  689. X        at x+1, y+1;
  690. X        panel (init=_clear_screen, noread, erase=_clear_screen) {
  691. X          #ON, line, strlen(line)-1#
  692. X        }
  693. X        _clear_screen = 0;
  694. X        _col += printable_chars(line);
  695. X
  696. X        /* line wrapped around?? */
  697. X        while (_col > COLUMNS) {
  698. X          _col  -= COLUMNS;
  699. X          _line += 1;
  700. X        }
  701. X
  702. X        /* now let's figure out if we're supposed to do a "<return>" */
  703. X
  704. X        for (i=0; i < strlen(line); i++)
  705. X            if (line[i] == '\n') {
  706. X                _line++;
  707. X                _col = 0;        /* on new line! */
  708. X            }
  709. X        return(0);
  710. X    }
  711. X#endif
  712. X    MoveCursor(x,y);
  713. X    printf("%s", line);    /* to avoid '%' problems */
  714. X    fflush(stdout);
  715. X    _col += printable_chars(line);
  716. X
  717. X    while (_col > COLUMNS) {     /* line wrapped around?? */
  718. X        _col -= COLUMNS;
  719. X        _line += 1;
  720. X    }
  721. X
  722. X    /** now let's figure out if we're supposed to do a "<return>" **/
  723. X
  724. X    for (i=0; i < strlen(line); i++)
  725. X        if (line[i] == '\n') {
  726. X            _line++;
  727. X            _col = 0;        /* on new line! */
  728. X        }
  729. X}
  730. X
  731. X/*VARARGS2*/
  732. XPutLine1(x,y, line, arg1)
  733. Xint x,y;
  734. Xchar *line;
  735. Xchar *arg1;
  736. X{
  737. X    /** write line at location x,y - one argument... **/
  738. X
  739. X    char buffer[VERY_LONG_STRING];
  740. X
  741. X    sprintf(buffer, line, arg1);
  742. X
  743. X    PutLine0(x, y, buffer);
  744. X}
  745. X
  746. X/*VARARGS2*/
  747. XPutLine2(x,y, line, arg1, arg2)
  748. Xint x,y;
  749. Xchar *line;
  750. Xchar *arg1, *arg2;
  751. X{
  752. X    /** write line at location x,y - one argument... **/
  753. X
  754. X    char buffer[VERY_LONG_STRING];
  755. X
  756. X    sprintf(buffer, line, arg1, arg2);
  757. X
  758. X    PutLine0(x, y, buffer);
  759. X}
  760. X
  761. X/*VARARGS2*/
  762. XPutLine3(x,y, line, arg1, arg2, arg3)
  763. Xint x,y;
  764. Xchar *line;
  765. Xchar *arg1, *arg2, *arg3;
  766. X{
  767. X    /** write line at location x,y - one argument... **/
  768. X
  769. X    char buffer[VERY_LONG_STRING];
  770. X
  771. X    sprintf(buffer, line, arg1, arg2, arg3);
  772. X
  773. X    PutLine0(x, y, buffer);
  774. X}
  775. X
  776. XCleartoEOLN()
  777. X{
  778. X    /** clear to end of line **/
  779. X#ifdef UTS
  780. X    char buffer[SLEN];
  781. X    register int cols, i = 0;
  782. X
  783. X    if (isatube) {
  784. X
  785. X        for (cols = _col; cols < COLUMNS; cols++)
  786. X            buffer[i++] = ' ';
  787. X
  788. X        buffer[i] = '\0';
  789. X
  790. X        at _line+1, _col+1;
  791. X        panel (noerase, noinit, noread) {
  792. X          #ON, buffer, strlen(buffer)-1#
  793. X        }
  794. X
  795. X        return(0);
  796. X    }
  797. X#endif
  798. X
  799. X    if (!_cleartoeoln)
  800. X        return(-1);
  801. X
  802. X    tputs(_cleartoeoln, 1, outchar);
  803. X    fflush(stdout);  /* clear the output buffer */
  804. X    return(0);
  805. X}
  806. X
  807. XCleartoEOS()
  808. X{
  809. X    /** clear to end of screen **/
  810. X
  811. X#ifdef UTS
  812. X    register int line_at;
  813. X
  814. X    if (isatube) {
  815. X      for (line_at = _line; line_at < LINES-1; line_at++) {
  816. X        panel (noread, noinit, noread) {
  817. X                #@ line_at, 1# #ON, _null_string, COLUMNS# 
  818. X        }
  819. X      }
  820. X    
  821. X        return(0);
  822. X    }
  823. X
  824. X#endif
  825. X    if (!_cleartoeos)
  826. X        return(-1);
  827. X
  828. X    tputs(_cleartoeos, 1, outchar);
  829. X    fflush(stdout);  /* clear the output buffer */
  830. X    return(0);
  831. X}
  832. X
  833. X#ifdef RAWMODE
  834. X
  835. XRaw(state)
  836. Xint state;
  837. X{
  838. X    /** state is either ON or OFF, as indicated by call **/
  839. X
  840. X    if (state == OFF && _inraw) {
  841. X      (void) ioctl(TTYIN, TCSETAW, &_original_tty);
  842. X      _inraw = 0;
  843. X    }
  844. X    else if (state == ON && ! _inraw) {
  845. X
  846. X      (void) ioctl(TTYIN, TCGETA, &_original_tty);    /** current setting **/
  847. X
  848. X      (void) ioctl(TTYIN, TCGETA, &_raw_tty);    /** again! **/
  849. X#ifdef BSD
  850. X      _raw_tty.sg_flags &= ~(ECHO | CRMOD);    /* echo off */
  851. X      _raw_tty.sg_flags |= CBREAK;    /* raw on    */
  852. X#else
  853. X      _raw_tty.c_lflag &= ~(ICANON | ECHO);    /* noecho raw mode        */
  854. X
  855. X      _raw_tty.c_cc[VMIN] = '\01';    /* minimum # of chars to queue    */
  856. X      _raw_tty.c_cc[VTIME] = '\0';    /* minimum time to wait for input */
  857. X
  858. X#endif
  859. X      (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
  860. X
  861. X      _inraw = 1;
  862. X    }
  863. X}
  864. X
  865. Xint
  866. XReadCh()
  867. X{
  868. X    /** read a character with Raw mode set! **/
  869. X
  870. X    register int result;
  871. X    char ch;
  872. X
  873. X    result = read(0, &ch, 1);
  874. X
  875. X    return(result == 0? EOF : ch);
  876. X}
  877. X
  878. X#endif
  879. X
  880. Xoutchar(c)
  881. Xchar c;
  882. X{
  883. X    /** output the given character.  From tputs... **/
  884. X    /** Note: this CANNOT be a macro!              **/
  885. X
  886. X    putc(c, stdout);
  887. X}
  888. END_OF_src/curses.c
  889. if test 16822 -ne `wc -c <src/curses.c`; then
  890.     echo shar: \"src/curses.c\" unpacked with wrong size!?
  891. fi
  892. # end of overwriting check
  893. fi
  894. echo shar: Extracting \"src/read_rc.c\" \(18128 characters\)
  895. if test -f src/read_rc.c ; then 
  896.   echo shar: Will not over-write existing file \"src/read_rc.c\"
  897. else
  898. sed "s/^X//" >src/read_rc.c <<'END_OF_src/read_rc.c'
  899. X/**            read_rc.c            **/
  900. X
  901. X/** (C) Copyright 1985, Dave Taylor            **/
  902. X
  903. X/** This file contains programs to allow the user to have a .elmrc file
  904. X    in their home directory containing any of the following: 
  905. X
  906. X    fullname= <username string>
  907. X    maildir = <directory>
  908. X    mailbox = <file>
  909. X    editor  = <editor>
  910. X    savemail= <savefile>
  911. X    calendar= <calendar file name>
  912. X    shell   = <shell>
  913. X    print   = <print command>
  914. X    weedout = <list of headers to weed out>
  915. X    prefix  = <copied message prefix string>
  916. X    pager   = <command to use for displaying messages>
  917. X
  918. X--
  919. X    signature = <.signature file for all outbound mail>
  920. XOR:
  921. X    localsignature = <.signature file for local mail>
  922. X    remotesignature = <.signature file for non-local mail>
  923. X--
  924. X
  925. X    bounceback= <hop count threshold, or zero to disable>
  926. X    timeout = <seconds for main menu timeout or zero to disable>
  927. X    userlevel = <0=amateur, 1=okay, 2 or greater = expert!>
  928. X
  929. X    sortby  = <sent, received, from, size, subject>
  930. X
  931. X    alternatives = <list of addresses that forward to us>
  932. X
  933. X    and/or the logical arguments:
  934. X    
  935. X    autocopy    [on|off]
  936. X    copy        [on|off]    
  937. X    resolve     [on|off]
  938. X    weed        [on|off]
  939. X    noheader    [on|off]
  940. X    titles      [on|off]
  941. X    editout     [on|off]
  942. X    savebyname  [on|off]
  943. X    movepage    [on|off]
  944. X    pointnew    [on|off]
  945. X    hpkeypad    [on|off]
  946. X    hpsoftkeys  [on|off]
  947. X    alwaysleave [on|off]
  948. X    alwaysdel   [on|off]
  949. X    arrow        [on|off]
  950. X    menus        [on|off]
  951. X    forms        [on|off]
  952. X    warnings    [on|off]
  953. X    names        [on|off]
  954. X    ask        [on|off]
  955. X    keepempty   [on|off]
  956. X
  957. X
  958. X    Lines starting with '#' are considered comments and are not checked
  959. X    any further!
  960. X
  961. X    Modified 10/85 to know about "Environment" variables..
  962. X    Modified 12/85 for the 'prefix' option
  963. X    Modified  2/86 for the new 3.3 flags
  964. X    Modified  8/86 (was I supposed to be keeping this up to date?)
  965. X**/
  966. X
  967. X#include <stdio.h>
  968. X#include <ctype.h>
  969. X
  970. X#ifdef BSD
  971. X#undef tolower
  972. X#endif
  973. X
  974. X#include "headers.h"
  975. X
  976. Xchar *shift_lower(), *strtok(), *getenv(), *strcpy();
  977. Xvoid   exit();
  978. X
  979. X#define NOTWEEDOUT    0
  980. X#define WEEDOUT        1
  981. X#define ALTERNATIVES    2
  982. X
  983. Xread_rc_file()
  984. X{
  985. X    /** this routine does all the actual work of reading in the
  986. X        .rc file... **/
  987. X
  988. X    FILE *file;
  989. X    char buffer[SLEN], filename[SLEN];
  990. X    char word1[SLEN], word2[SLEN];
  991. X    register int  i, errors = 0, last = NOTWEEDOUT, lineno = 0;
  992. X
  993. X    sprintf(filename,"%s/%s", home, elmrcfile);
  994. X
  995. X    default_weedlist();
  996. X
  997. X    alternative_addresses = NULL;     /* none yet! */
  998. X
  999. X    if ((file = fopen(filename, "r")) == NULL) {
  1000. X      dprint0(2,"Warning: User has no \".elmrc\" file (read_rc_file)\n");
  1001. X      return;    /* we're done! */
  1002. X    }
  1003. X
  1004. X    while (fgets(buffer, SLEN, file) != NULL) {
  1005. X      lineno++;
  1006. X      no_ret(buffer);         /* remove return */
  1007. X      if (buffer[0] == '#') {     /* comment       */
  1008. X        last = NOTWEEDOUT;
  1009. X        continue;
  1010. X      }
  1011. X      if (strlen(buffer) < 2) {    /* empty line    */
  1012. X        last = NOTWEEDOUT;
  1013. X        continue;
  1014. X      }
  1015. X
  1016. X      breakup(buffer, word1, word2);
  1017. X
  1018. X      strcpy(word1, shift_lower(word1));    /* to lower case */
  1019. X
  1020. X      if (word2[0] == 0 && (last != WEEDOUT || last != ALTERNATIVES)) {
  1021. X        dprint1(2,"Error: Bad .elmrc entry in users file;\n-> \"%s\"\n",
  1022. X             buffer);
  1023. X        fprintf(stderr, 
  1024. X            "Line %d of your \".elmrc\" is badly formed:\n> %s\n",
  1025. X            lineno, buffer);
  1026. X        errors++;
  1027. X        continue;
  1028. X      }
  1029. X    
  1030. X      if (equal(word1,"maildir") || equal(word1,"folders")) {
  1031. X        expand_env(folders, word2);
  1032. X        last = NOTWEEDOUT;
  1033. X      }
  1034. X      else if (equal(word1, "fullname") || equal(word1,"username") ||
  1035. X           equal(word1, "name")) {
  1036. X        strcpy(full_username, word2);
  1037. X        last = NOTWEEDOUT;
  1038. X      }
  1039. X      else if (equal(word1, "prefix")) {
  1040. X        for (i=0; i < strlen(word2); i++)
  1041. X          prefixchars[i] = (word2[i] == '_' ? ' ' : word2[i]);
  1042. X        prefixchars[i] = '\0';
  1043. X       
  1044. X        last = NOTWEEDOUT;
  1045. X      }
  1046. X      else if (equal(word1, "shell")) {
  1047. X        expand_env(shell, word2);
  1048. X        last = NOTWEEDOUT;
  1049. X      }
  1050. X      else if (equal(word1, "sort") || equal(word1, "sortby")) {
  1051. X        strcpy(word2, shift_lower(word2));
  1052. X        if (equal(word2, "sent"))
  1053. X           sortby = SENT_DATE;
  1054. X        else if (equal(word2, "received") || equal(word2,"recieved"))
  1055. X           sortby = RECEIVED_DATE;
  1056. X        else if (equal(word2, "from") || equal(word2, "sender"))
  1057. X           sortby = SENDER;
  1058. X        else if (equal(word2, "size") || equal(word2, "lines"))
  1059. X          sortby = SIZE;
  1060. X        else if (equal(word2, "subject"))
  1061. X          sortby = SUBJECT;
  1062. X        else if (equal(word2, "reverse-sent") || equal(word2,"rev-sent"))
  1063. X           sortby = - SENT_DATE;
  1064. X        else if (strncmp(word2, "reverse-rec",11) == 0 || 
  1065. X             strncmp(word2,"rev-rec",7) == 0)
  1066. X           sortby = - RECEIVED_DATE;
  1067. X        else if (equal(word2, "reverse-from") || equal(word2, "rev-from")
  1068. X              || equal(word2,"reverse-sender")|| equal(word2,"rev-sender"))
  1069. X           sortby = - SENDER;
  1070. X        else if (equal(word2, "reverse-size") || equal(word2, "rev-size")
  1071. X              || equal(word2, "reverse-lines")|| equal(word2,"rev-lines"))
  1072. X          sortby = - SIZE;
  1073. X        else if (equal(word2, "reverse-subject") || 
  1074. X             equal(word2, "rev-subject"))
  1075. X          sortby = - SUBJECT;
  1076. X        else {
  1077. X         if (! errors)
  1078. X           printf("Error reading '.elmrc' file;\n");
  1079. X         printf("Line %d: Don't know what sort key '%s' specifies!\n", 
  1080. X            lineno, word2);
  1081. X         errors++;
  1082. X         continue;
  1083. X       }
  1084. X      }
  1085. X      else if (equal(word1, "mailbox")) {
  1086. X        expand_env(mailbox, word2);
  1087. X        last = NOTWEEDOUT;
  1088. X      }
  1089. X      else if (equal(word1, "editor") || equal(word1,"mailedit")) {
  1090. X        expand_env(editor, word2);
  1091. X        last = NOTWEEDOUT;
  1092. X      }
  1093. X      else if (equal(word1, "savemail") || equal(word1, "saveto")) {
  1094. X        expand_env(savefile, word2);
  1095. X        last = NOTWEEDOUT;
  1096. X      }
  1097. X      else if (equal(word1, "calendar")) {
  1098. X        expand_env(calendar_file, word2);
  1099. X        last = NOTWEEDOUT;
  1100. X      }
  1101. X      else if (equal(word1, "print") || equal(word1, "printmail")) {
  1102. X        expand_env(printout, word2);
  1103. X        last = NOTWEEDOUT;
  1104. X      }
  1105. X      else if (equal(word1, "pager") || equal(word1, "page")) {
  1106. X        expand_env(pager, word2);
  1107. X        last = NOTWEEDOUT;
  1108. X      }
  1109. X      else if (equal(word1, "signature")) {
  1110. X        if (equal(shift_lower(word2), "on") ||
  1111. X        equal(shift_lower(word2), "off")) {
  1112. X          fprintf(stderr, 
  1113. X      "\"signature\" used in obsolete way in .elmrc file - ignored!\n\r");
  1114. X          fprintf(stderr,
  1115. X   "\t(signature should specify the filename to use rather than on/off)\n\r");
  1116. X        }
  1117. X        else {
  1118. X          expand_env(local_signature, word2);
  1119. X          strcpy(remote_signature, local_signature);
  1120. X          signature = TRUE;
  1121. X        }
  1122. X        last = NOTWEEDOUT;
  1123. X      }
  1124. X      else if (equal(word1, "localsignature")) {
  1125. X        expand_env(local_signature, word2);
  1126. X        signature = TRUE;
  1127. X        last = NOTWEEDOUT;
  1128. X      }
  1129. X      else if (equal(word1, "remotesignature")) {
  1130. X        expand_env(remote_signature, word2);
  1131. X        signature = TRUE;
  1132. X        last = NOTWEEDOUT;
  1133. X      }
  1134. X      else if (equal(word1, "autocopy")) {
  1135. X        auto_copy = is_it_on(word2);
  1136. X        last = NOTWEEDOUT;
  1137. X      }
  1138. X      else if (equal(word1, "copy") || equal(word1, "auto_cc")) {
  1139. X        auto_cc = is_it_on(word2);
  1140. X        last = NOTWEEDOUT;
  1141. X      }
  1142. X      else if (equal(word1, "names")) {
  1143. X        names_only = is_it_on(word2);
  1144. X        last = NOTWEEDOUT;
  1145. X      }
  1146. X      else if (equal(word1, "resolve")) {
  1147. X        resolve_mode = is_it_on(word2);
  1148. X        last = NOTWEEDOUT;
  1149. X      }
  1150. X      else if (equal(word1, "weed")) {
  1151. X        filter = is_it_on(word2);
  1152. X        last = NOTWEEDOUT;
  1153. X      }
  1154. X      else if (equal(word1, "noheader")) {
  1155. X        noheader = is_it_on(word2);
  1156. X        last = NOTWEEDOUT;
  1157. X      }
  1158. X      else if (equal(word1, "titles")) {
  1159. X        title_messages = is_it_on(word2);
  1160. X        last = NOTWEEDOUT;
  1161. X      }
  1162. X      else if (equal(word1, "editout")) {
  1163. X        edit_outbound = is_it_on(word2);
  1164. X        last = NOTWEEDOUT;
  1165. X      }
  1166. X      else if (equal(word1, "savebyname") || equal(word1, "savename")) {
  1167. X        save_by_name = is_it_on(word2);
  1168. X        last = NOTWEEDOUT;
  1169. X      }
  1170. X      else if (equal(word1, "movepage") || equal(word1, "page") ||
  1171. X           equal(word1, "movewhenpaged")) {
  1172. X        move_when_paged = is_it_on(word2);
  1173. X        last = NOTWEEDOUT;
  1174. X      }
  1175. X      else if (equal(word1, "pointnew") || equal(word1, "pointtonew")) {
  1176. X        point_to_new = is_it_on(word2);
  1177. X        last = NOTWEEDOUT;
  1178. X      }
  1179. X      else if (equal(word1, "keypad") || equal(word1, "hpkeypad")) {
  1180. X        hp_terminal = is_it_on(word2);
  1181. X        last = NOTWEEDOUT;
  1182. X      }
  1183. X      else if (equal(word1, "softkeys") || equal(word1, "hpsoftkeys")) {
  1184. X        if (hp_softkeys = is_it_on(word2))
  1185. X          hp_terminal = TRUE;    /* must be set also! */
  1186. X        last = NOTWEEDOUT;
  1187. X      }
  1188. X      else if (equal(word1, "arrow")) {
  1189. X        arrow_cursor = is_it_on(word2);
  1190. X        last = NOTWEEDOUT;
  1191. X      }
  1192. X      else if (strncmp(word1, "form", 4) == 0) {
  1193. X        allow_forms = (is_it_on(word2)? MAYBE : NO);
  1194. X        last = NOTWEEDOUT;
  1195. X      }
  1196. X      else if (strncmp(word1, "menu", 4) == 0) {
  1197. X        mini_menu = is_it_on(word2);
  1198. X        last = NOTWEEDOUT;
  1199. X      }
  1200. X      else if (strncmp(word1, "warning", 7) == 0) {
  1201. X        warnings = is_it_on(word2);
  1202. X        last = NOTWEEDOUT;
  1203. X      }
  1204. X      else if (equal(word1, "alwaysleave") || equal(word1, "leave")) {
  1205. X        always_leave = is_it_on(word2);
  1206. X        last = NOTWEEDOUT;
  1207. X      }
  1208. X      else if (equal(word1, "alwaysdelete") || equal(word1, "delete")) {
  1209. X        always_del = is_it_on(word2);
  1210. X        last = NOTWEEDOUT;
  1211. X      }
  1212. X      else if (equal(word1, "ask") || equal(word1, "question")) {
  1213. X        question_me = is_it_on(word2);
  1214. X        last = NOTWEEDOUT;
  1215. X      }
  1216. X      else if (equal(word1, "keep") || equal(word1, "keepempty")) {
  1217. X        keep_empty_files = is_it_on(word2);
  1218. X        last = NOTWEEDOUT;
  1219. X      }
  1220. X      else if (equal(word1, "bounce") || equal(word1, "bounceback")) {
  1221. X        bounceback = atoi(word2);
  1222. X        if (bounceback > MAX_HOPS) {
  1223. X          fprintf(stderr,
  1224. X    "Warning: bounceback is set to greater than %d (max-hops) - Ignored.\n",
  1225. X               MAX_HOPS);
  1226. X          bounceback = 0;
  1227. X        }
  1228. X        last = NOTWEEDOUT;
  1229. X      }
  1230. X      else if (equal(word1, "userlevel")) {
  1231. X        user_level = atoi(word2);
  1232. X        last = NOTWEEDOUT;
  1233. X      }
  1234. X      else if (equal(word1, "timeout")) {
  1235. X        timeout = atoi(word2);
  1236. X        if (timeout < 10) {
  1237. X          fprintf(stderr,
  1238. X       "Warning: timeout is set to less than 10 seconds - Ignored.\n");
  1239. X          timeout = 0;
  1240. X        }
  1241. X        last = NOTWEEDOUT;
  1242. X      }
  1243. X      else if (equal(word1, "weedout")) {
  1244. X        weedout(word2);
  1245. X        last = WEEDOUT;
  1246. X      }
  1247. X      else if (equal(word1, "alternatives")) {
  1248. X        alternatives(word2);
  1249. X        last = ALTERNATIVES;
  1250. X      }
  1251. X      else if (last == WEEDOUT)    /* could be multiple line weedout */
  1252. X        weedout(buffer);
  1253. X      else if (last == ALTERNATIVES)    /* multi-line addresses   */
  1254. X        alternatives(buffer);
  1255. X      else {
  1256. X        fprintf(stderr, 
  1257. X           "Line %d is undefined in your \".elmrc\" file:\n> %s\n", 
  1258. X           lineno, buffer);
  1259. X        errors++;
  1260. X      }
  1261. X    }
  1262. X
  1263. X    if (debug > 10)     /** only do this if we REALLY want debug! **/
  1264. X      dump_rc_results();
  1265. X
  1266. X    if (errors) 
  1267. X      exit(errors);
  1268. X}
  1269. X    
  1270. Xweedout(string)
  1271. Xchar *string;
  1272. X{
  1273. X    /** This routine is called with a list of headers to weed out.   **/
  1274. X
  1275. X    char *strptr, *header;
  1276. X    register int i;
  1277. X
  1278. X    strptr = string;
  1279. X
  1280. X    while ((header = strtok(strptr, "\t ,\"'")) != NULL) {
  1281. X      if (strlen(header) > 0) {
  1282. X        if (weedcount > MAX_IN_WEEDLIST) {
  1283. X          fprintf(stderr, "Too many weed headers!  Leaving...\n");
  1284. X          exit(1);
  1285. X        }
  1286. X        if ((weedlist[weedcount] = (char *) pmalloc(strlen(header) + 1)) 
  1287. X        == NULL) {
  1288. X          fprintf(stderr,
  1289. X              "Too many weed headers - out of memory!  Leaving...\n");
  1290. X          exit(1);
  1291. X        }
  1292. X
  1293. X        for (i=0; i< strlen(header); i++)
  1294. X          if (header[i] == '_') header[i] = ' ';
  1295. X
  1296. X        strcpy(weedlist[weedcount], header);
  1297. X        weedcount++;
  1298. X      }
  1299. X      strptr = NULL;
  1300. X    }
  1301. X}
  1302. X
  1303. Xalternatives(string)
  1304. Xchar *string;
  1305. X{
  1306. X    /** This routine is called with a list of alternative addresses
  1307. X        that you may receive mail from (forwarded) **/
  1308. X
  1309. X    char *strptr, *address;
  1310. X    struct addr_rec *current_record, *previous_record;
  1311. X
  1312. X    previous_record = alternative_addresses;    /* start 'er up! */
  1313. X    /* move to the END of the alternative addresses list */
  1314. X
  1315. X    if (previous_record != NULL)
  1316. X      while (previous_record->next != NULL)
  1317. X        previous_record = previous_record->next;
  1318. X
  1319. X    strptr = (char *) string;
  1320. X
  1321. X    while ((address = strtok(strptr, "\t ,\"'")) != NULL) {
  1322. X      if (previous_record == NULL) {
  1323. X        previous_record = (struct addr_rec *) pmalloc(sizeof 
  1324. X        *alternative_addresses);
  1325. X
  1326. X        strcpy(previous_record->address, address);
  1327. X        previous_record->next = NULL;
  1328. X        alternative_addresses = previous_record;
  1329. X      }
  1330. X      else {
  1331. X        current_record = (struct addr_rec *) pmalloc(sizeof 
  1332. X        *alternative_addresses);
  1333. X      
  1334. X        strcpy(current_record->address, address);
  1335. X        current_record->next = NULL;
  1336. X        previous_record->next = current_record;
  1337. X        previous_record = current_record;
  1338. X      }
  1339. X      strptr = (char *) NULL;
  1340. X    }
  1341. X}
  1342. X
  1343. Xdefault_weedlist()
  1344. X{
  1345. X    /** Install the default headers to weed out!  Many gracious 
  1346. X        thanks to John Lebovitz for this dynamic method of 
  1347. X        allocation!
  1348. X    **/
  1349. X
  1350. X    static char *default_list[] = { ">From", "In-Reply-To:",
  1351. X               "References:", "Newsgroups:", "Received:",
  1352. X               "Apparently-To:", "Message-Id:", "Content-Type:",
  1353. X               "From", "X-Mailer:", "*end-of-defaults*", NULL
  1354. X             };
  1355. X
  1356. X    for (weedcount = 0; default_list[weedcount] != NULL; weedcount++) {
  1357. X      if ((weedlist[weedcount] = (char *)
  1358. X          pmalloc(strlen(default_list[weedcount]) + 1)) == NULL) {
  1359. X        fprintf(stderr, 
  1360. X           "\n\rNot enough memory for default weedlist.  Leaving.\n\r");
  1361. X        leave(1);
  1362. X      }
  1363. X      strcpy(weedlist[weedcount], default_list[weedcount]);
  1364. X    }
  1365. X}
  1366. X
  1367. Xint
  1368. Xmatches_weedlist(buffer)
  1369. Xchar *buffer;
  1370. X{
  1371. X    /** returns true iff the first 'n' characters of 'buffer' 
  1372. X        match an entry of the weedlist **/
  1373. X    
  1374. X    register int i;
  1375. X
  1376. X    for (i=0;i < weedcount; i++)
  1377. X      if (strncmp(buffer, weedlist[i], strlen(weedlist[i])) == 0) 
  1378. X        return(1);
  1379. X
  1380. X    return(0);
  1381. X}
  1382. X
  1383. Xbreakup(buffer, word1, word2)
  1384. Xchar *buffer, *word1, *word2;
  1385. X{
  1386. X    /** This routine breaks buffer down into word1, word2 where 
  1387. X        word1 is alpha characters only, and there is an equal
  1388. X        sign delimiting the two...
  1389. X        alpha = beta
  1390. X        For lines with more than one 'rhs', word2 is set to the
  1391. X        entire string...
  1392. X    **/
  1393. X
  1394. X    register int i;
  1395. X    
  1396. X    for (i=0;i<strlen(buffer) && isalpha(buffer[i]); i++)
  1397. X      word1[i] = buffer[i];
  1398. X
  1399. X    word1[i++] = '\0';    /* that's the first word! */
  1400. X
  1401. X    /** spaces before equal sign? **/
  1402. X
  1403. X    while (buffer[i] == ' ' || buffer[i] == '\t') i++;
  1404. X
  1405. X    if (buffer[i] == '=') i++;
  1406. X
  1407. X    /** spaces after equal sign? **/
  1408. X
  1409. X    while (buffer[i] == ' ' || buffer[i] == '\t') i++;
  1410. X
  1411. X    if (i < strlen(buffer))
  1412. X      strcpy(word2, (char *) (buffer + i));
  1413. X    else
  1414. X      word2[0] = '\0';
  1415. X}
  1416. X
  1417. Xexpand_env(dest, buffer)
  1418. Xchar *dest, *buffer;
  1419. X{
  1420. X    /** expand possible metacharacters in buffer and then copy
  1421. X        to dest... 
  1422. X        This routine knows about "~" being the home directory,
  1423. X        and "$xxx" being an environment variable.
  1424. X    **/
  1425. X
  1426. X    char  *word, *string, next_word[SLEN];
  1427. X    
  1428. X    if (buffer[0] == '/') {
  1429. X      dest[0] = '/';
  1430. X      dest[1] = '\0';
  1431. X    }
  1432. X    else
  1433. X      dest[0] = '\0';
  1434. X
  1435. X    string = (char *) buffer;
  1436. X
  1437. X    while ((word = strtok(string, "/")) != NULL) {
  1438. X      if (word[0] == '$') {
  1439. X        next_word[0] = '\0';
  1440. X        if (getenv((char *) (word + 1)) != NULL)
  1441. X        strcpy(next_word, getenv((char *) (word + 1)));
  1442. X        if (strlen(next_word) == 0)
  1443. X          leave(fprintf(stderr, 
  1444. X            "\n\rCan't expand environment variable '%s'\n\r",
  1445. X            word));
  1446. X      }
  1447. X      else if (word[0] == '~' && word[1] == '\0')
  1448. X        strcpy(next_word, home);
  1449. X      else
  1450. X        strcpy(next_word, word);
  1451. X
  1452. X      sprintf(dest, "%s%s%s", dest, 
  1453. X         (strlen(dest) > 0 && lastch(dest) != '/' ? "/":""),
  1454. X         next_word);
  1455. X
  1456. X      string = (char *) NULL;
  1457. X    }
  1458. X}
  1459. X
  1460. X#define on_off(s)    (s == 1? "ON" : "OFF")
  1461. Xdump_rc_results()
  1462. X{
  1463. X
  1464. X    register int i;
  1465. X
  1466. X    fprintf(debugfile, "\n\n\n\n");
  1467. X    fprintf(debugfile, "folders = %s\n", folders);
  1468. X    fprintf(debugfile, "mailbox = %s\n", mailbox);
  1469. X    fprintf(debugfile, "editor = %s\n", editor);
  1470. X    fprintf(debugfile, "printout = %s\n", printout);
  1471. X    fprintf(debugfile, "savefile = %s\n", savefile);
  1472. X    fprintf(debugfile, "calendar_file = %s\n", calendar_file);
  1473. X    fprintf(debugfile, "prefixchars = %s\n", prefixchars);
  1474. X    fprintf(debugfile, "shell = %s\n", shell);
  1475. X    fprintf(debugfile, "pager = %s\n", pager);
  1476. X    fprintf(debugfile, "\n");
  1477. X    fprintf(debugfile, "mini_menu = %s\n", on_off(mini_menu));
  1478. X    fprintf(debugfile, "mbox_specified = %s\n", on_off(mbox_specified));
  1479. X    fprintf(debugfile, "check_first = %s\n", on_off(check_first));
  1480. X    fprintf(debugfile, "auto_copy = %s\n", on_off(auto_copy));
  1481. X    fprintf(debugfile, "filter = %s\n", on_off(filter));
  1482. X    fprintf(debugfile, "resolve_mode = %s\n", on_off(resolve_mode));
  1483. X    fprintf(debugfile, "auto_cc = %s\n", on_off(auto_cc));
  1484. X    fprintf(debugfile, "noheader = %s\n", on_off(noheader));
  1485. X    fprintf(debugfile, "title_messages = %s\n", on_off(title_messages));
  1486. X    fprintf(debugfile, "hp_terminal = %s\n", on_off(hp_terminal));
  1487. X    fprintf(debugfile, "hp_softkeys = %s\n", on_off(hp_softkeys));
  1488. X    fprintf(debugfile, "save_by_name = %s\n", on_off(save_by_name));
  1489. X    fprintf(debugfile, "move_when_paged = %s\n", on_off(move_when_paged));
  1490. X    fprintf(debugfile, "point_to_new = %s\n", on_off(point_to_new));
  1491. X    fprintf(debugfile, "bounceback = %s\n", on_off(bounceback));
  1492. X    fprintf(debugfile, "signature = %s\n", on_off(signature));
  1493. X    fprintf(debugfile, "always_leave = %s\n", on_off(always_leave));
  1494. X    fprintf(debugfile, "always_del = %s\n", on_off(always_del));
  1495. X    fprintf(debugfile, "arrow_cursor = %s\n", on_off(arrow_cursor));
  1496. X    fprintf(debugfile, "names = %s\n", on_off(names_only));
  1497. X    fprintf(debugfile, "warnings = %s\n", on_off(warnings));
  1498. X    fprintf(debugfile, "question_me = %s\n", on_off(question_me));
  1499. X    fprintf(debugfile, "keep_empty_files = %s\n", 
  1500. X               on_off(keep_empty_files));
  1501. X
  1502. X    fprintf(debugfile, "\n** userlevel = %s **\n\n", user_level);
  1503. X
  1504. X    fprintf(debugfile, "Weeding out the following headers;\n");
  1505. X    for (i=0; i < weedcount; i++) 
  1506. X      fprintf(debugfile, "\t\"%s\"\n", weedlist[i]);
  1507. X    
  1508. X    fprintf(debugfile, "\n\n");
  1509. X}
  1510. X
  1511. Xis_it_on(word)
  1512. Xchar *word;
  1513. X{
  1514. X    /** Returns TRUE if the specified word is either 'ON', 'YES'
  1515. X        or 'TRUE', and FALSE otherwise.   We explicitly translate
  1516. X        to lowercase here to ensure that we have the fastest
  1517. X        routine possible - we really DON'T want to have this take
  1518. X        a long time or our startup will be major pain each time.
  1519. X    **/
  1520. X
  1521. X    static char mybuffer[NLEN];
  1522. X    register int i, j;
  1523. X
  1524. X    for (i=0, j=0; word[i] != '\0'; i++)
  1525. X      mybuffer[j++] = isupper(word[i]) ? tolower(word[i]) : word[i];
  1526. X    mybuffer[j] = '\0';
  1527. X
  1528. X    return(  (strncmp(mybuffer, "on",   2) == 0) ||
  1529. X         (strncmp(mybuffer, "yes",  3) == 0) ||
  1530. X         (strncmp(mybuffer, "true", 4) == 0)
  1531. X          );
  1532. X}
  1533. X    
  1534. X
  1535. X    
  1536. X
  1537. X
  1538. END_OF_src/read_rc.c
  1539. if test 18128 -ne `wc -c <src/read_rc.c`; then
  1540.     echo shar: \"src/read_rc.c\" unpacked with wrong size!?
  1541. fi
  1542. # end of overwriting check
  1543. fi
  1544. echo shar: End of archive 16 \(of 19\).
  1545. cp /dev/null ark16isdone
  1546. DONE=true
  1547. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  1548.     if test ! -f ark${I}isdone ; then
  1549.     echo shar: You still need to run archive ${I}.
  1550.     DONE=false
  1551.     fi
  1552. done
  1553. if test "$DONE" = "true" ; then
  1554.     echo You have unpacked all 19 archives.
  1555.     echo "See the Instructions file"
  1556.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1557. fi
  1558. ##  End of shell archive.
  1559. exit 0
  1560.