home *** CD-ROM | disk | FTP | other *** search
/ ftp.freefriends.org / ftp.freefriends.org.tar / ftp.freefriends.org / arnold / Source / mush.rstevens.tar.gz / mush.tar / mush.h < prev    next >
C/C++ Source or Header  |  1992-10-30  |  24KB  |  673 lines

  1. /* @(#)mush.h    (c) copyright 1986 (Dan Heller) */
  2.  
  3. #include "config.h"
  4.  
  5. #ifdef CURSES
  6.  
  7. #ifdef USG
  8. #    define _USG
  9. #    undef USG
  10. #endif /* USG */
  11. #ifdef SYSV
  12. #    define _SYSV
  13. #    undef SYSV
  14. #endif /* SYSV */
  15. #include <curses.h>
  16.  
  17. #ifdef timeout
  18. #undef timeout
  19. #endif
  20. #ifdef overwrite
  21. #undef overwrite
  22. #endif
  23.  
  24. #if !defined(USG) && defined(_USG)
  25. #    define USG
  26. #endif /* USG */
  27. #if !defined(SYSV) && defined(_SYSV)
  28. #    define SYSV
  29. #endif /* SYSV */
  30.  
  31. #else /* CURSES */
  32. #include <stdio.h>
  33. #if defined(SYSV) && defined(USG) || defined(AIX)
  34. #include <termio.h>
  35. #endif /* SYSV && USG */
  36. #endif /* CURSES */
  37.  
  38. #if defined(SVR4)
  39. #include <sys/ttold.h>
  40. #endif /* SVR4 */
  41.  
  42. #include <ctype.h>
  43. #include <errno.h>
  44. #include <setjmp.h>
  45. #include "strings.h"
  46.  
  47. extern char
  48.     *malloc(),        /* allocate memory */
  49.     *calloc(),        /* allocate and clear memory */
  50.     *realloc();        /* re-allocate memory */
  51.  
  52. extern void
  53.     free_vec(),        /* free a malloc'ed argv */
  54.     xfree();        /* free malloc'ed pointers */
  55.  
  56. #ifdef BSD
  57. #define fputs Fputs    /* See comments in print.c */
  58. #endif /* BSD */
  59.  
  60. #if defined(BSD) || defined(GETWD)
  61. extern char *getwd();
  62. #define GetCwd(buf,len)    getwd(buf)
  63. #else
  64. extern char *getcwd();
  65. #define GetCwd(buf,len) getcwd(buf,len)
  66. #endif /* BSD || GETWD */
  67.  
  68. #ifdef SUNTOOL
  69. #    include <suntool/sunview.h>
  70. #ifdef SUN_4_0
  71. #    include <suntool/alert.h>
  72. #endif /* SUN_4_0 */
  73. #    include <suntool/textsw.h>
  74. #    include <sys/ioctl.h>   /* for ltchars */
  75. #else
  76. #    include <sys/types.h>
  77. #    include <signal.h>
  78. #    ifndef SYSV
  79. #    include <sys/time.h>
  80. #    include <sys/ioctl.h>   /* for ltchars */
  81. #    else
  82. #    include <time.h>
  83. #    ifdef M_UNIX
  84. #        ifndef SELECT
  85. #        define SELECT
  86. #        endif
  87. #        include <sys/select.h>
  88. #    endif /* M_UNIX */
  89. #    include <fcntl.h>
  90. #    endif /* SYSV */
  91. #endif /* SUNTOOL */
  92.  
  93. #ifdef POSIX_UTIME
  94. #include <sys/utime.h>
  95. #endif /* POSIX_UTIME */
  96. #include <sys/stat.h>
  97. #include <sys/file.h>
  98.  
  99. #ifdef SUNTOOL
  100. #    include <suntool/panel.h>
  101. #    include <suntool/canvas.h>
  102. #    include <suntool/tty.h>
  103. #    include <suntool/menu.h>
  104. #    include <suntool/icon.h>
  105. #    include <suntool/scrollbar.h>
  106. #    include <suntool/icon_load.h>
  107. #endif /* SUNTOOL */
  108.  
  109. /* if no maximum number of files can be found, we'll use getdtablesize() */
  110. #ifdef _NFILE
  111. #    define MAXFILES _NFILE
  112. #else
  113. #ifdef NOFILE
  114. #    define MAXFILES NOFILE
  115. #endif /* NOFILE */
  116. #endif /* _NFILE */
  117.  
  118. #ifndef MAXPATHLEN
  119. #define MAXPATHLEN BUFSIZ
  120. #endif /* MAXPATHLEN */
  121.  
  122. #ifdef CTRL
  123. #undef CTRL
  124. #endif /* CTRL */
  125. #define CTRL(c)        ((c) & 037)
  126.  
  127. #define ESC         '\033'
  128.  
  129. #define NO_STRING    ""
  130. #ifdef  NULL
  131. #undef  NULL
  132. #endif /* NULL */
  133. #define NULL        (char *)0
  134. #define NULL_FILE    (FILE *)0
  135. #define DUBL_NULL    (char **)0
  136. #define TRPL_NULL    (char ***)0
  137. #ifdef putchar
  138. #undef putchar
  139. #endif /* putchar */
  140. #define putchar(c)    (void) (fputc(c, stdout), fflush(stdout))
  141. #ifdef SUNTOOL
  142. extern int bell();
  143. #else /* SUNTOOL */
  144. #define bell()        (void) (fputc('\007', stderr), fflush(stderr))
  145. #endif /* SUNTOOL */
  146.  
  147. /* For error recovery purposes, send keyboard generated signals to a special
  148.  * routine (interrupt) to set a global flag (WAS_INTR) and return to the
  149.  * calling routine which is responsible for checking the flag.  For both
  150.  * on_intr() and off_intr() macros, initialize WAS_INTR to false.
  151.  */
  152. #define on_intr() \
  153.     turnoff(glob_flags, WAS_INTR), oldint = signal(SIGINT, intrpt), \
  154.     oldquit = signal(SIGQUIT, intrpt)
  155.  
  156. #define off_intr() \
  157.     (void) (turnoff(glob_flags, WAS_INTR), signal(SIGINT, oldint), \
  158.         signal(SIGQUIT, oldquit))
  159.  
  160. /* Don't flush input when setting echo or cbreak modes (allow typeahead) */
  161. #ifdef TIOCSETN
  162. #ifdef stty
  163. #undef stty
  164. #endif /* stty */
  165. #define stty(fd, sgttybuf)    ioctl(fd, TIOCSETN, sgttybuf)
  166. #endif /* TIOCSETN */
  167.  
  168. /* for system-V machines that run termio */
  169. #if defined(SYSV) && defined(USG) || defined(AIX)
  170. #ifdef crmode
  171. #undef crmode
  172. #undef nocrmode
  173. #endif /* nocrmode */
  174.  
  175. unsigned char vmin, vtime;
  176. #define sg_erase  c_cc[2]
  177. #define sg_flags  c_lflag
  178. #define sg_kill   c_cc[3]
  179. #define sg_ospeed c_cflag
  180. #define gtty(fd, SGTTYbuf)    ioctl(fd, TCGETA, SGTTYbuf)
  181. #undef stty
  182. #define stty(fd, SGTTYbuf)    ioctl(fd, TCSETAW, SGTTYbuf)
  183. #define echon()    (_tty.sg_flags |= (ECHO|ECHOE),    stty(0, &_tty))
  184. #define echoff()   (_tty.sg_flags &= ~ECHO,   stty(0, &_tty))
  185. #define cbrkon()   \
  186.     (_tty.sg_flags &= ~ICANON, _tty.c_cc[VMIN] = 1, stty(0, &_tty))
  187. #define cbrkoff()  \
  188.     (_tty.sg_flags |= ICANON,_tty.c_cc[VMIN] = vmin,_tty.c_iflag |= ICRNL, \
  189.         _tty.c_cc[VTIME] = vtime, stty(0, &_tty))
  190. #define savetty()  \
  191.     (void) gtty(0, &_tty), vtime = _tty.c_cc[VTIME], vmin = _tty.c_cc[VMIN]
  192. #define cbreak()   cbrkon()
  193. #define nocbreak() cbrkoff()
  194.  
  195. /* If curses isn't defined, declare our 'tty' and macros for echo/cbreak */
  196. #ifndef CURSES
  197. typedef struct termio SGTTY;
  198. #define echom()    echon()
  199. #define noechom()  echoff()
  200. #define crmode()   cbrkon()
  201. #define nocrmode() cbrkoff()
  202.  
  203. #else /* CURSES */
  204. /* If curses is defined, use the echo/cbreak commands in library only
  205.  * if curses is running.  If curses isn't running, use macros above.
  206.  */
  207. #define echom()    ((iscurses) ? echo(): echon())
  208. #define noechom()  ((iscurses) ? noecho(): echoff())
  209. #define crmode()   ((iscurses) ? cbreak() : cbrkon())
  210. #define nocrmode() ((iscurses) ? nocbreak() : cbrkoff())
  211. #endif /* CURSES */
  212. #endif /* SYSV && USG || AIX */
  213.  
  214. #if !defined(USG) && !defined(AIX)
  215. #ifndef CURSES
  216. /* if curses is not defined, simulate the same tty based macros */
  217. typedef struct sgttyb SGTTY;
  218. /* Do real ioctl calls to set the tty modes */
  219. #define crmode()   (_tty.sg_flags |= CBREAK,  stty(0, &_tty))
  220. #define nocrmode() (_tty.sg_flags &= ~CBREAK, stty(0, &_tty))
  221. #define echom()    (_tty.sg_flags |= ECHO,    stty(0, &_tty))
  222. #define noechom()  (_tty.sg_flags &= ~ECHO,   stty(0, &_tty))
  223. #define savetty()  (void) gtty(0, &_tty)
  224. #else /* CURSES */
  225. #define echom()    echo()
  226. #define noechom()  noecho()
  227. #endif /* ~CURSES */
  228. #endif /* ~USG */
  229.  
  230. /* With all that out of the way, we can now declare our tty type */
  231. SGTTY _tty;
  232.  
  233. extern char
  234.     del_line,        /* tty delete line character */
  235.     del_word,        /* tty delete word character */
  236.     del_char,        /* backspace */
  237.     reprint_line,    /* usually ^R */
  238.     eofc,        /* usually ^D */
  239.     lit_next,        /* usually ^V */
  240.     complete,        /* word completion, usually ESC */
  241.     complist;        /* completion listing, usually tab */
  242.  
  243. /* These macros now turn on/off echo/cbreak independent of the UNIX running */
  244. #define echo_on()    \
  245.     if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) nocrmode(), echom()
  246. #define echo_off()    \
  247.     if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) crmode(), noechom()
  248.  
  249. #define strdup(dst, src) (xfree (dst), dst = savestr(src))
  250. #define Debug        if (debug == 0) {;} else (void) wprint
  251.  
  252. #ifdef SYSV
  253. #ifndef L_SET
  254. #define L_SET    0
  255. #endif /* L_SET */
  256. #ifndef F_OK
  257. #define F_OK    000
  258. #define R_OK    004
  259. #define W_OK    002
  260. #define E_OK    001
  261. #endif /* F_OK */
  262. #ifdef u_long
  263. #undef u_long
  264. #endif /* u_long */
  265. #define u_long    unsigned long
  266. #ifndef HPUX
  267. #define vfork   fork
  268. #endif /* HPUX */
  269. #ifndef SIGCHLD
  270. #define SIGCHLD SIGCLD
  271. #endif /* SIGCHLD */
  272. #endif /* SYSV */
  273.  
  274. #if !defined(SUNTOOL) && !defined(CURSES)
  275.  
  276. #define TRUE          1
  277. #define FALSE          0
  278. #define print          (void) printf
  279. #define wprint          (void) printf
  280. #define print_more      (void) printf
  281.  
  282. #endif /* !SUNTOOL && !CURSES */
  283.  
  284. #ifndef max
  285. #define max(a,b) (((a) > (b)) ? (a) : (b))
  286. #define min(a,b) (((a) < (b)) ? (a) : (b))
  287. #endif /* max */
  288.  
  289. #if defined(CURSES) && (!defined(SUNTOOL))
  290. #define wprint    (void) printf
  291. #endif /* CURSES && (!SUNTOOL) */
  292.  
  293. #ifdef SUNTOOL
  294. /* stdout may be closed */
  295. #define printf wprint
  296. #else /* !SUNTOOL */
  297. #define ok_box print
  298. #endif /* SUNTOOL */
  299.  
  300. #if defined(CURSES) || defined(SUNTOOL)
  301. #define print_more      turnon(glob_flags, CONT_PRNT), print
  302. void print();    /* printf to window or curses or tty accordingly */
  303. #endif /* CURSES || SUNTOOL */
  304.  
  305. #define ArraySize(o)      (sizeof(o) / sizeof(*o))
  306.  
  307. #ifdef SUNTOOL
  308.  
  309. #define NO_ITEM        (Panel_item)0
  310. #define NO_EVENT    (struct inputevent *)0
  311. #define TIME_OUT    60    /* sleep 60 secs between mailchecks */
  312. #define PIX_XOR        PIX_SRC ^ PIX_DST
  313. #define ID        event_id(event)
  314. #define l_width()    mush_font->pf_defaultsize.x /* width of letter */
  315. #define l_height()    mush_font->pf_defaultsize.y /* height of letter */
  316. #define Clrtoeol(w,x,y)    ((void) pw_text(w, x, y, PIX_SRC, mush_font, blank))
  317.  
  318. /* Miscellaneous old-SunView cleanup */
  319. #ifndef TTY_ARGV_DO_NOT_FORK
  320. #define TTY_ARGV_DO_NOT_FORK (-1)
  321. #endif
  322.  
  323. #endif /* SUNTOOL */
  324.  
  325. /* bits and pieces */
  326. #define turnon(flg,val)   ((flg) |= (u_long)(val))
  327. #define turnoff(flg,val)  ((flg) &= ~(u_long)(val))
  328. #define ison(flg,val)     ((u_long)(flg) & (u_long)(val))
  329. #define isoff(flg,val)    (!ison((flg), (val)))
  330. #define set_replied(n)      \
  331.     if (isoff(msg[n].m_flags, REPLIED)) \
  332.         turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED)
  333. #define set_isread(n)      \
  334.     if (turnon(msg[n].m_flags, DO_UPDATE) && ison(msg[n].m_flags, UNREAD)) \
  335.         turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
  336.  
  337. #define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE))
  338. #define in_macro() (ison(glob_flags, LINE_MACRO|IN_MACRO))
  339. #define line_macro(s) (void) (turnon(glob_flags, LINE_MACRO), mac_push(s))
  340. #define curs_macro(s) (void) (turnon(glob_flags, IN_MACRO), mac_push(s))
  341. #define Ungetstr(s) (void) (turnon(glob_flags, QUOTE_MACRO), mac_push(s))
  342.  
  343. /* global conditions */
  344. #define is_shell (mailfile && *mailfile)
  345.  
  346. /* msg lists represented by bits (8 should be replaced by sizeof(char) */
  347. #define clear_msg_list(list)      ((void) bzero(list, (msg_cnt+7)/8))
  348. #define msg_bit(list, n)    ((list[(n) / 8] >> ((n) % 8)) & 1)
  349. #define set_msg_bit(list, n)    (list[(n) / 8] |= (1 << ((n) % 8)))
  350. #define unset_msg_bit(list, n)  (list[(n) / 8] &= ~(1 << ((n) % 8)))
  351. #define bput(S1, S2, Len, op)                   \
  352.         do {                         \
  353.             register char *s1 = S1, *s2 = S2;         \
  354.             register int len = Len;             \
  355.             while(len--)                 \
  356.             *s2++ op *s1++;             \
  357.         } while (0)
  358. #define bitput(m1,m2,len,op)    bput(m1, m2, (((len)+7)/8), op)
  359.  
  360. /* convenience and/or readability */
  361. #define when          break;case
  362. #define otherwise      break;default
  363. #define lower(c)      (isupper(c)? tolower(c): c)
  364. #define Lower(c)      (c = lower(c))
  365. #define upper(c)      (islower(c)? toupper(c): c)
  366. #define Upper(c)      (c = upper(c))
  367. #define skipspaces(n)     for(p += (n); *p == ' ' || *p == '\t'; ++p)
  368. #define skipdigits(n)     for(p += (n); isdigit(*p); ++p)
  369. #define ismsgnum(c)       (isdigit(c)||c=='.'||c=='^'||c=='$'||c=='*')
  370. #define skipmsglist(n)\
  371.     for(p += (n); *p && (ismsgnum(*p) || index(" \t,-{`}", *p)); p += !!*p)\
  372.     if (*p != '`' || !p[1]) {;} else do ++p; while (*p && *p != '`')
  373.  
  374. /* define a macro to declare unsigned-long bits */
  375. #define ULBIT(bit)        ((u_long)1 << (u_long)(bit))
  376.  
  377. /* various flags */
  378. u_long   glob_flags;    /* global boolean flags thruout the whole program */
  379. #define DO_UPDATE   ULBIT(0) /* folder has been modified -- update it */
  380. #define REV_VIDEO   ULBIT(1) /* reverse video for curses or toolmode */
  381. #define CONT_PRNT   ULBIT(2) /* continue to print without a '\n' */
  382. #define DO_SHELL    ULBIT(3) /* run a shell even if no mail? (true if tool) */
  383. #define DO_PIPE     ULBIT(4) /* if commands are piping to other commands */
  384. #define IS_PIPE     ULBIT(5) /* true if commands' "input" comes from a pipe */
  385. #define IGN_SIGS    ULBIT(6) /* true if catch() should not longjmp */
  386. #define IGN_BANG    ULBIT(7) /* ignore ! as a history reference */
  387. #define ECHO_FLAG   ULBIT(8) /* if true, echo|cbreak is ON, echo typing (-e) */
  388. #define IS_GETTING  ULBIT(9) /* true if we're getting input for a letter */
  389. #define PRE_CURSES  ULBIT(10) /* true if curses will run, but hasn't started */
  390. #define READ_ONLY   ULBIT(11) /* -r passed to folder() for read only */
  391. #define REDIRECT    ULBIT(12) /* true if stdin is being redirected */
  392. #define WAS_INTR    ULBIT(13) /* catch interrupts, set this flag (signals.c) */
  393. #define WARNING     ULBIT(14) /* if set, various warning messages are printed */
  394. #define NEW_MAIL    ULBIT(15) /* new mail has arrived; mush is busy or closed */
  395. #define CNTD_CMD    ULBIT(16) /* curses.c -- promotes "...continue..." prompt */
  396. #define IS_SENDING  ULBIT(17) /* was run to send mail, not run as a shell */
  397. #define MIL_TIME    ULBIT(19) /* if $mil_time is set, use 24hr time fmt */
  398. #define DATE_RECV   ULBIT(20) /* $date_received: show date received on msgs */
  399. #define IN_MACRO    ULBIT(21) /* input is currently being read from a macro */
  400. #define LINE_MACRO  ULBIT(22) /* escape to line mode from curses in progress */
  401. #define QUOTE_MACRO ULBIT(23) /* protect current macro from recursive expan.. */
  402. #define NEW_FRAME   ULBIT(24) /* toolmode should build a new frame for pager */
  403. #define HELP_TEXT   ULBIT(25) /* create textsw frame for paging help messages */
  404. #define CORRUPTED   ULBIT(26) /* error loading new mail has occurred */
  405.  
  406. /* flags to control composition */
  407. #define VERBOSE        ULBIT(0)  /* verbose flag for sendmail */
  408. #define INCLUDE        ULBIT(1)  /* include msg in response */
  409. #define INCLUDE_H    ULBIT(2)  /* include msg with header */
  410. #define EDIT        ULBIT(3)  /* enter editor by default on mailing */
  411. #define SIGN        ULBIT(4)  /* auto-include ~/.signature in mail */
  412. #define DO_FORTUNE    ULBIT(5)  /* add a fortune at end of msgs */
  413. #define EDIT_HDRS    ULBIT(6)  /* user edits headers using editor */
  414. #define SEND_NOW    ULBIT(7)  /* send without further changes */
  415. #define NO_SIGN        ULBIT(8)  /* override SIGN and DO_FORTUNE */
  416.  
  417. /* msg flags */
  418. #define PRINTED        ULBIT(4)  /* sent through lpr command */
  419. #define NO_HEADER    ULBIT(6)  /* don't print header of message */
  420. #define DELETE        ULBIT(7)
  421. #define OLD        ULBIT(8)
  422. #define UNREAD        ULBIT(9)
  423. #define UPDATE_STATUS    ULBIT(10) /* change status of msg when copyback */
  424. #define NO_PAGE        ULBIT(11) /* don't page this message */
  425. #define INDENT        ULBIT(12) /* indent included msg with string */
  426. #define NO_IGNORE    ULBIT(13) /* don't ignore headers */
  427. #define PRESERVE    ULBIT(14) /* preserve in mailbox unless deleted */
  428. #define M_TOP        ULBIT(15) /* just print the top of msg (same as pre) */
  429. #define FORWARD        ULBIT(16) /* Forward messages into the message buffer */
  430. #define REPLIED        ULBIT(17) /* Messages that have been replied to */
  431. #define NEW_SUBJECT    ULBIT(18) /* new subject regardless of $ask (mail -s) */
  432. #define SAVED        ULBIT(19) /* when message has been saved */
  433. #define NO_SEPARATOR    ULBIT(20) /* don't include message separator lines */
  434. #define METAMAIL    ULBIT(21) /* message can display with "metamail" */
  435.  
  436. #define M_PRIORITY(n)    ULBIT(22+(n))
  437. /* It is possible to reset MAX_PRIORITY to as high as 9 */
  438. #define MAX_PRIORITY    5
  439.  
  440. #define    MAXMSGS_BITS    MAXMSGS/sizeof(char)    /* number of bits for bitmap */
  441.  
  442. struct msg {
  443.     u_long m_flags;
  444.     long   m_offset;    /* offset in tempfile of msg */
  445.     long   m_size;    /* number of bytes in msg */
  446.     int    m_lines;    /* number of lines in msg */
  447.     char   *m_date_recv;/* Date user received msg (see dates.c for fmt) */
  448.     char   *m_date_sent;/* Date author sent msg (see dates.c for fmt) */
  449. } msg[MAXMSGS];
  450.  
  451. struct options {
  452.     char *option;
  453.     char *value;
  454.     struct options *next;
  455. } *set_options, *aliases, *ignore_hdr, *functions, *fkeys, *own_hdrs;
  456.  
  457. #define chk_option(v,f)    chk_two_lists(do_set(set_options,(v)), (f), "\t ,")
  458.  
  459. struct cmd {
  460.     char *command;
  461.     int (*func)();
  462. };
  463. extern struct cmd ucb_cmds[];
  464. extern struct cmd cmds[], hidden_cmds[];
  465.  
  466. struct expand {
  467.     char *orig;        /* string beginning with substring to be expanded */
  468.     char *exp;        /* result of expansion of substring */
  469.     char *rest;        /* rest of the original string beyond substring */
  470. };
  471.  
  472. FILE
  473.     *tmpf,        /* temporary holding place for all mail */
  474.     *mask_fopen(),    /* open a file with umask 077 (permissions 600) */
  475.     *open_file(),    /* open a file or program for write/append */
  476.     *lock_fopen(),    /* open and lock a file as an atomic operation */
  477.     *popen();        /* this should be in stdio.h */
  478.  
  479. extern char
  480.     *sys_errlist[],    /* system's list of global error messages */
  481.     **environ;        /* user's environment variables */
  482.  
  483. extern int errno;    /* global system error number */
  484. jmp_buf jmpbuf;        /* longjmp to jmpbuf on sigs (not in tool) */
  485.  
  486. char
  487.     debug,        /* debug causes various print statements in code */
  488.     tempfile[MAXPATHLEN],    /* path to filename of temporary file */
  489.     msg_list[MAXMSGS_BITS],    /* MAXMSGS bits of boolean storage */
  490.     **alternates,    /* alternates list --see alts() */
  491.     *cmd_help,        /* filename of location for "command -?" commands. */
  492.     *login,        /* login name of user */
  493.     *mailfile,        /* path to filename of current mailfile */
  494.     **ourname,        /* the name and aliases of the current host */
  495.     **known_hosts,    /* the names of all hosts connected via uucp */
  496.     *prompt,        /* the prompt string -- may have %d */
  497.     *format_prompt(),    /* function to format prompts from the prompt string */
  498.     *escape,        /* the "tilde escape" when inputting text to letter */
  499.     *hdrs_only,        /* true if -H flag was given --set to args */
  500.     *hdr_format,    /* set to the header format string; referenced a lot */
  501.     *spoolfile,        /* MAILDIR/$USER in a string -- this is used a lot */
  502.     *msg_get(),        /* find start of message and return From_ line */
  503.     *do_range(),    /* parse a string converting to a "range" of numbers */
  504.     *getpath(),        /* static char returning path (expanding ~, +, %, #) */
  505.     *getdir(),        /* uses getpath() to expand and test directory names */
  506.     *do_set(),        /* set/unset an option, alias, ignored-hdr */
  507.     *reverse(),        /* reverse a string */
  508.     *trim_filename(),    /* remove or condense leading file name path */
  509.     *prog_name,
  510.  
  511.     /* from loop.c */
  512.     **make_command(),    /* build a command vector (argv) */
  513.     **mk_argv(),    /* given a string, make a vector */
  514.     *variable_stuff(),    /* return information about variables */
  515.     *check_internal(),    /* test or evaluate internal variables */
  516.  
  517.     /* from dates.c */
  518.     *Time(),        /* returns string expression of time (takes args) */
  519.     *date_to_ctime(),    /* convert a date into ctime() format */
  520.     *date_to_string(),    /* returns a string described by parse_date() */
  521.     *msg_date(),    /* return a string of the date of a message */
  522.     *parse_date(),    /* parse an ascii date, and return message-id str */
  523.     *rfc_date(),    /* create a date string compliant to RFC822 */
  524.  
  525.     /* from hdrs.c */
  526.     *cc_to(),         /* when responding, return str which is the cc-list */
  527.     *compose_hdr(),    /* passes hdr_format to format_hdr() for displays */
  528.     *format_hdr(),    /* returns a formatted line describing passed msg # */
  529.     *header_field(),    /* the line in msg described by arg (message header) */
  530.     *reply_to(),    /* who do we reply to when responding */
  531.     *subject_to(),      /* when responding, return str which is the subject */
  532.  
  533.     /* addrs.c */
  534.     *alias_to_address(),/* convert a name[list] to "real" names */
  535.     *bang_form(),    /* construct a !-style form of an address */
  536.     *get_name_n_addr(), /* get name and addr from a well-formed address */
  537.     *set_header(),     /* [interactive] proc to set/display to/subject/cc */
  538.     *wrap_addrs();    /* insert newlines in between headers */
  539.  
  540. int
  541.     last_msg_cnt,    /* when checking for new mail, save the last msg_cnt */
  542.     msg_cnt,        /* total number of messages */
  543.     crt,        /* min number of lines msg contains to invoke pager */
  544.     current_msg,    /* the current message we're dealing with */
  545.     exec_pid,        /* pid of a command that has been "exec"ed */
  546.     hist_no,        /* command's history number */
  547.     iscurses,        /* if we're running curses */
  548. #if defined(SUNTOOL) || defined(lint)
  549.     istool,        /* argv[0] == "xxxxtool", ranges from 0 to 2 */
  550. #else /* !SUNTOOL */
  551. #define istool 0
  552. #endif /* SUNTOOL */
  553.     n_array[128],    /* array of message numbers in the header window */
  554.     screen,        /* number of headers window can handle */
  555.     wrapcolumn,        /* compose mode line wrap, measured from left */
  556.  
  557.     close_lock(),     /* unlock and close a file opened by lock_fopen() */
  558.  
  559.     mush_quit(), do_alias(), respond(), cd(), sh(), stop(),
  560.     folder(), folders(), merge_folders(), do_undigest(), mark_msg(),
  561.     save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
  562.     save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(),
  563.     do_pick(), print_help(), question_mark(), do_from(), my_stty(),
  564.     do_version(), disp_hist(), source(), do_echo(), ls(), pipe_msg(),
  565.     await(), nopenfiles(), file_to_fp(),
  566.     check_new_mail(), get_new_mail(), show_new_mail(),
  567.     Setenv(), Unsetenv(), Printenv(), msg_flags(), toggle_debug();
  568.  
  569. #ifndef SIGRET
  570. #define SIGRET int
  571. #endif /* SIGRET */
  572. SIGRET
  573.     rm_edfile(),    /* remove letter-compose file on interrupts */
  574.     stop_start(),    /* handle job control signals */
  575.     bus_n_seg(),    /* handle runtime segfaults -- exit gracefully */
  576.     sigchldcatcher(),    /* account for terminated child processes */
  577.     catch(),        /* catch user (keyboard) generated signals */
  578.     intrpt();        /* handle interrupts when we don't want to */
  579.  
  580. long
  581.     spool_size,        /* size of spool mail regardless of current folder */
  582.     last_size,        /* the last size of the mailfile since last check */
  583.     time();        /* satisfy lint */
  584.  
  585. void
  586.     error(), getmail(), mail_status(), sign_letter(),
  587.     init(), display_msg(), cleanup(), fs_error();
  588.     /* printf(), fclose(), fflush(), fputs(), fputc() */
  589. #ifdef TIOCGLTC
  590. struct ltchars ltchars;            /* tty character settings */
  591. #endif /* TIOCGLTC */
  592. #if defined(BSD) && !defined(AIX) /* (TIOCGETC) */
  593. struct tchars  tchars;            /* more tty character settings */
  594. #endif /* BSD && !AIX (TIOCGETC) */
  595.  
  596. #ifdef CURSES
  597.  
  598. #define STANDOUT(y,x,s) standout(), mvaddstr(y,x,s), standend()
  599. #define redraw()    clearok(curscr, TRUE), wrefresh(curscr)
  600.  
  601. int
  602.     curses_init();    /* interpret commands via the curses interface */
  603. #endif /* CURSES */
  604.  
  605. int
  606.     mac_push(),        /* set up a string as a macro */
  607.     bind_it();        /* bind strings to functions or macros */
  608.  
  609. void
  610.     mac_flush();    /* Abandon macro processing (on error) */
  611.  
  612. #if defined(SUNTOOL) || defined(POP3_SUPPORT)
  613. #ifdef POP3_SUPPORT
  614. #define MIN_TIME_OUT    (15 * 60)    /* 15 min. checks */
  615. extern void popchkmail();
  616. extern void popgetmail();
  617. #else
  618. #define MIN_TIME_OUT    30        /* 30 sec. checks */
  619. #endif /* POP3_SUPPORT */
  620.  
  621. int
  622.     time_out;        /* time out interval to wait for new mail */
  623. #endif /* SUNTOOL || POP3_SUPPORT */
  624.  
  625. #ifdef SUNTOOL
  626. void
  627.     timeout_cursors(), do_file_dir(), toggle_mail_items(), ok_box(),
  628.     read_mail(), opts_panel_item(), view_options(), toolquit(), wprint(),
  629.     update_list_textsw(), check_icons();
  630.  
  631. char
  632.     *find_key(),    /* pass x,y coords to find which function key assoc. */
  633.     *panel_get(),          /* returns what has been typed in a panel item */
  634.     *tool_help,        /* help for tool-related things (sometimes, overlap) */
  635.     *more_prompt,    /* when NULL, we're paging a msg; else pager prompt */
  636.     blank[128];        /* use to clear to end of line */
  637.  
  638. int
  639.     is_iconic;        /* set if the mushview window is iconic. */
  640.  
  641. Notify_value
  642.     do_check(),        /* check for new mail on timeout */
  643.     destroy_proc(),    /* Destroy procedure. */
  644.     my_wait3(),        /* Handle wait for child exit */
  645.     scroll_textwin(),    /* Do fancy TEXTSW scrolling */
  646.     edit_msg_textwin();    /* Auto-positioning in compose TEXTSW */
  647.  
  648. Frame tool;        /* Main frame. */
  649. Frame compose_frame;    /* Compose frame. */
  650. Textsw pager_textsw;    /* for "paging" messages and other lists.. */
  651. Textsw mfprint_sw;    /* Textsw in main mush frame for wprint() */
  652. Canvas hdr_sw;         /* Canvas for message headers */
  653. Tty tty_sw;         /* subwindow which forks a shell (usually editor) */
  654.  
  655. Pixwin
  656.     *hdr_win;        /* pixwin for message headers */
  657.  
  658. struct pixfont *mush_font;    /* array of fonts */
  659.  
  660. struct itimerval mail_timer;    /* frequency to check for new mail */
  661.  
  662. extern Cursor l_cursor, m_cursor, r_cursor;
  663. extern Icon mail_icon;
  664.  
  665. /* When trapping events that represent scrolling actions */
  666. typedef enum {
  667.     MUSH_SCROLL_TO,
  668.     MUSH_SCROLL_RELATIVE,
  669.     MUSH_SCROLL_IGNORE,
  670.     MUSH_SCROLL_PASS_EVENT
  671. } Scroll_action;
  672. #endif /* SUNTOOL */
  673.