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