home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-05-06 | 53.9 KB | 1,712 lines |
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # If this archive is complete, you will see the following message at the end:
- # "End of archive 10 (of 19)."
- # Contents: mush/curses.c mush/mush.h mush/version.h
- # Wrapped by argv@turnpike on Wed May 2 13:59:31 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'mush/curses.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/curses.c'\"
- else
- echo shar: Extracting \"'mush/curses.c'\" \(28433 characters\)
- sed "s/^X//" >'mush/curses.c' <<'END_OF_FILE'
- X/* @(#)curses.c (c) copyright 3/18/87 (Dan Heller) */
- X
- X/* curses.c -- routine to deal with the curses interface */
- X#ifdef CURSES
- X
- X#include "mush.h"
- X#include "bindings.h"
- X
- Xcurses_init(argc, argv)
- Xregister char **argv;
- X{
- X char buf[80];
- X extern char *UP, ttytype[];
- X
- X if (argv && *++argv && !strcmp(*argv, "-?"))
- X return help(0, "curses", cmd_help);
- X#ifdef SUNTOOL
- X if (istool) {
- X print("Sorry, can't change to curses mode from tool.\n");
- X return -1;
- X } else
- X#endif /* SUNTOOL */
- X if (!is_shell) {
- X /*
- X * Can't start curses, but we can prepare to.
- X * Also allow -C switch to be shut off.
- X */
- X if (argv && *argv && !lcase_strncmp(*argv, "off", -1))
- X turnoff(glob_flags, PRE_CURSES);
- X else
- X turnon(glob_flags, PRE_CURSES);
- X return 0;
- X } else if (argc && (iscurses || ison(glob_flags, PRE_CURSES))) {
- X print("You are already using curses mode.\n");
- X return -1;
- X } else if (ison(glob_flags, IS_GETTING)) {
- X print("Finish your letter first.\n");
- X return -1;
- X }
- X
- X#ifndef attrset /* terminfo version of curses */
- X /* you can not start curses in no echo mode.. must be in normal mode */
- X echom();
- X nocrmode();
- X#endif /* attrset */
- X (void) initscr();
- X#ifdef SIGCONT
- X /* initscr will play with signals -- make sure they're set right. */
- X (void) signal(SIGTSTP, stop_start);
- X (void) signal(SIGCONT, stop_start);
- X#endif /* SIGCONT */
- X#if !defined(SYSV) && !defined(USG)
- X if (!UP || !*UP)
- X#else /* ~SYSV && ~USG */
- X if (!stdscr)
- X#endif /* ~SYSV && ~USG */
- X {
- X print("Terminal type %s can not use the curses interface.\n", ttytype);
- X return -1;
- X }
- X iscurses = TRUE;
- X noechom(); /* reset tty state -- */
- X crmode(); /* do not use "echo_on/off()" */
- X scrollok(stdscr, TRUE);
- X /* if the user hasn't set his screen explicitly, set it for him */
- X set_screen_size();
- X if (crt > LINES - 1 || !do_set(set_options, "crt")) {
- X crt = LINES;
- X (void)cmd_line(sprintf(buf, "\\set screen = %d crt = %d", screen, crt),
- X msg_list);
- X } else
- X (void)cmd_line(sprintf(buf, "\\set screen = %d", screen), msg_list);
- X if (argc) {
- X (void) cmd_line(sprintf(buf, "\\headers %d", current_msg+1), msg_list);
- X (void) curses_help_msg(TRUE);
- X }
- X if (!do_set(set_options, "no_reverse"))
- X turnon(glob_flags, REV_VIDEO);
- X turnoff(glob_flags, CONT_PRNT);
- X return 0; /* doesn't affect messages */
- X}
- X
- Xstruct cmd_map *active_cmd; /* See bindings.h for description */
- X
- X/*
- X * get input in cbreak mode and execute the appropriate command.
- X * when the command is done (usually), the user is prompted to
- X * hit any key to continue. At this point, the user may enter a
- X * new command so no screen refreshing needs to be done. This
- X * new command is returned to caller and may be passed back.
- X *
- X * The flag CNTD_CMD (continued command) is set if
- X * this routine is called with the passed parameter (c) != 0. If
- X * so, then the character passed is the character input by the
- X * user at the last "hit return" prompt indicating that he wants
- X * to execute a new command and not draw the screen.
- X *
- X * CNTD_CMD is also set if the command that the user invokes
- X * causes any sort of output that requires a screen refresh. The
- X * variable redo is set to 1 if the header page not only requires
- X * redrawing, but updating ... (new call to do_hdrs)
- X *
- X * calls that say: print("%s", compose_hdr(current_msg)) are constructed
- X * that way because if the header has a `%' in it, then print will try to
- X * expand it.
- X */
- Xcurses_command(c)
- Xregister int c;
- X{
- X char buf[BUFSIZ], file[128], list[128];
- X int n, curlin;
- X static int redo = 0; /* set if headers should be redrawn */
- X
- X if (c != 0)
- X turnon(glob_flags, CNTD_CMD);
- X else
- X turnoff(glob_flags, CNTD_CMD);
- X clear_msg_list(msg_list); /* play it safe */
- X if (isoff(glob_flags, CNTD_CMD)) {
- X (void) check_new_mail();
- X curlin = max(1, current_msg - n_array[0] + 1);
- X scrn_line(curlin, buf);
- X if (ison(glob_flags, REV_VIDEO) && msg_cnt)
- X STANDOUT(curlin, 0, buf);
- X mail_status(0);
- X move(curlin, 0), refresh();
- X /* reprint to remove reverse video from current line (don't refresh) */
- X if (ison(glob_flags, REV_VIDEO))
- X mvaddstr(curlin, 0, buf);
- X c = getcmd(); /* get input AFTER line redrawn without reverse video */
- X }
- X buf[0] = list[0] = file[0] = '\0';
- X
- X if (c == C_WRITE_LIST || c == C_SAVE_LIST || c == C_COPY_LIST
- X || c == C_DELETE_LIST || c == C_UNDEL_LIST) {
- X if (msg_cnt < 1) {
- X mac_flush();
- X print("Not enough messages.");
- X c = C_NULL;
- X } else if (c == C_DELETE_LIST && ison(glob_flags, READ_ONLY)) {
- X mac_flush();
- X print("Folder is read-only.");
- X c = C_NULL;
- X } else if (!curses_msg_list(sprintf(buf, "%s msg list: ",
- X (c == C_WRITE_LIST)? "write" : (c == C_SAVE_LIST)? "save" :
- X (c == C_COPY_LIST)? "copy" :
- X (c == C_DELETE_LIST)? "delete" : "undelete"), list, msg_list))
- X c = C_NULL;
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X }
- X
- X /* first do non-mail command type stuff */
- X switch (c) {
- X case C_ERROR :
- X bell();
- X mac_flush();
- X
- X when C_NULL :
- X if (isoff(glob_flags, CNTD_CMD))
- X bell();
- X
- X /* goto a specific message number */
- X when C_GOTO_MSG :
- X if (curses_msg_list(strcpy(buf, "goto msg: "), list, msg_list)) {
- X /*
- X * Reset the current message in case a
- X * backquoted command (like `from`) changed it
- X */
- X n = current_msg;
- X do if (++n >= msg_cnt)
- X n = 0;
- X while (n != current_msg && !msg_bit(msg_list, n));
- X if (n == current_msg && !msg_bit(msg_list, n)) {
- X mac_flush(); /* bail out if in macro processing */
- X print("Message not found.");
- X }
- X else if ((current_msg = n) < n_array[0]
- X || n > n_array[screen-1])
- X redo = 1;
- X } else {
- X mac_flush();
- X bell();
- X }
- X if (ison(glob_flags, CNTD_CMD) && msg_cnt)
- X print("%-.*s", COLS-2, compose_hdr(current_msg));
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X
- X /* screen optimization stuff */
- X when C_REVERSE :
- X if (ison(glob_flags, REV_VIDEO))
- X turnoff(glob_flags, REV_VIDEO);
- X else
- X turnon(glob_flags, REV_VIDEO);
- X
- X when C_REDRAW : redo = 1;
- X
- X /*
- X * screen movement
- X */
- X when C_NEXT_MSG :
- X if (current_msg + 2 > msg_cnt ||
- X isoff(glob_flags, CNTD_CMD) && curlin == LINES-2) {
- X mac_flush(); /* Bail out if in macro processing */
- X bell(); /* reached the end */
- X } else {
- X if (ison(glob_flags, CNTD_CMD)) {
- X if (++current_msg > n_array[screen-1])
- X redo = 1;
- X print("%-.*s", COLS-2, compose_hdr(current_msg));
- X putchar('\n');
- X } else {
- X if (++current_msg > n_array[screen-1])
- X n_array[screen++] = current_msg;
- X move(++curlin, 0);
- X printw("%-.*s", COLS-2, compose_hdr(current_msg));
- X clrtoeol();
- X }
- X }
- X
- X when C_PREV_MSG :
- X if (isoff(glob_flags, CNTD_CMD) && curlin == 1 || current_msg == 0)
- X {
- X mac_flush(); /* Bail out if in macro processing */
- X bell(); /* at the beginning */
- X } else {
- X if (--current_msg < n_array[0])
- X redo = 1;
- X if (ison(glob_flags, CNTD_CMD)) {
- X print("%-.*s", COLS-2, compose_hdr(current_msg));
- X putchar('\n');
- X }
- X }
- X
- X when C_FIRST_MSG : case C_LAST_MSG :
- X if (!msg_cnt) {
- X mac_flush();
- X bell();
- X break;
- X }
- X n = current_msg;
- X move(LINES-1, 0), refresh();
- X if (c == C_FIRST_MSG && (current_msg = 0) < n_array[0] ||
- X c == C_LAST_MSG && (current_msg = msg_cnt-1)> n_array[screen-1])
- X if (isoff(glob_flags, CNTD_CMD))
- X (void) cmd_line(sprintf(buf, "\\headers %d", current_msg+1),
- X msg_list);
- X else
- X redo = 1;
- X if (ison(glob_flags, CNTD_CMD) && n != current_msg)
- X print("%-.*s", COLS-2, compose_hdr(current_msg)), putchar('\n');
- X
- X /* top and bottom of headers screen */
- X when C_TOP_PAGE : case C_BOTTOM_PAGE :
- X if (msg_cnt && isoff(glob_flags, CNTD_CMD))
- X if (c == C_TOP_PAGE)
- X current_msg = n_array[0];
- X else
- X current_msg = min(n_array[screen-1], msg_cnt-1);
- X else {
- X mac_flush();
- X bell();
- X }
- X
- X when C_NEXT_SCREEN : /* next page */
- X move(LINES-1, 0), refresh();
- X if (msg_cnt-1 > n_array[screen-1]) {
- X clear();
- X set_screen_size();
- X (void) cmd_line(strcpy(buf, "\\headers +"), msg_list);
- X if (current_msg < n_array[0])
- X current_msg = n_array[0];
- X (void) curses_help_msg(TRUE);
- X return redo = 0;
- X } else {
- X mac_flush();
- X bell();
- X }
- X
- X when C_PREV_SCREEN : /* previous page */
- X move(LINES-1, 0), refresh();
- X if (n_array[0] > 0) {
- X clear();
- X set_screen_size();
- X (void) cmd_line(strcpy(buf, "\\headers -"), msg_list);
- X if (current_msg > n_array[screen-1])
- X current_msg = n_array[screen-1];
- X (void) curses_help_msg(TRUE);
- X return redo = 0;
- X } else {
- X mac_flush();
- X bell();
- X }
- X
- X /* read from/save to record file (.mushrc) */
- X when C_SOURCE : case C_SAVEOPTS : {
- X int argc;
- X char *argv[3];
- X print("%s filename [default]: ",
- X (c == C_SOURCE)? "source" : "save options to");
- X argc = Getstr(file, LINES-40, 0);
- X clr_bot_line();
- X if (argc < 0)
- X break;
- X if (argc > 0)
- X argv[1] = file, argc = 2;
- X else
- X argc = 1;
- X argv[argc] = NULL;
- X turnon(glob_flags, PRE_CURSES);
- X if (c == C_SOURCE) {
- X (void) source(argc, argv);
- X mac_flush(); /* can't change things in mid-macro */
- X redo = isoff(glob_flags, CNTD_CMD);
- X } else
- X (void) save_opts(argc, argv);
- X turnoff(glob_flags, PRE_CURSES);
- X }
- X
- X /*
- X * search commands
- X */
- X when C_NEXT_SEARCH : case C_PREV_SEARCH : case C_CONT_SEARCH :
- X if (c != C_CONT_SEARCH)
- X c = search(0 + (c == C_PREV_SEARCH));
- X else
- X c = search(-1);
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X if (c == 0)
- X break;
- X if (ison(glob_flags, CNTD_CMD))
- X print("%-.*s",COLS-2, compose_hdr(current_msg)), putchar('\n');
- X if (n_array[0] > current_msg || n_array[screen-1] < current_msg) {
- X redo = 1;
- X if (isoff(glob_flags, CNTD_CMD))
- X (void) cmd_line(sprintf(buf, "\\headers %d",
- X current_msg+1), msg_list);
- X }
- X
- X /*
- X * actions on messages
- X */
- X /* delete/undelete */
- X when C_DELETE_MSG : case C_DELETE_LIST :
- X case C_UNDEL_MSG : case C_UNDEL_LIST :
- X if (!msg_cnt) {
- X print("No messages.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X break;
- X }
- X if (ison(glob_flags, READ_ONLY)) {
- X mac_flush();
- X print("Folder is read-only.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X break;
- X }
- X Debug("current message = %d", current_msg + 1);
- X if (!*list)
- X set_msg_bit(msg_list, current_msg);
- X turnon(glob_flags, DO_UPDATE);
- X for (n = 0; n < msg_cnt; n++)
- X if (msg_bit(msg_list, n)) {
- X if (c == C_DELETE_MSG || c == C_DELETE_LIST)
- X turnon(msg[n].m_flags, DELETE);
- X else
- X turnoff(msg[n].m_flags, DELETE);
- X if (isoff(glob_flags, CNTD_CMD) && (msg_cnt < screen ||
- X n >= n_array[0] && n <= n_array[screen-1])) {
- X move(max(1, n - n_array[0] + 1), 0);
- X printw("%-.*s", COLS-1, compose_hdr(n));
- X } else
- X redo = 1;
- X }
- X if (ison(glob_flags, CNTD_CMD) || *list) {
- X /* print(), THEN putchar() -- overwrite line */
- X if (ison(glob_flags, CNTD_CMD)) {
- X print("%sdeleted %s",
- X (c == C_DELETE_MSG || c == C_DELETE_LIST)? "":"un", list);
- X putchar('\n');
- X }
- X if (c == C_DELETE_MSG || c == C_DELETE_LIST) {
- X if (ison(msg[current_msg].m_flags, DELETE) ||
- X ison(msg[current_msg].m_flags, SAVED))
- X (void) next_msg();
- X if (isoff(msg[current_msg].m_flags, DELETE) &&
- X do_set(set_options, "autoprint"))
- X return C_DISPLAY_MSG;
- X }
- X if (ison(glob_flags, CNTD_CMD))
- X puts(compose_hdr(current_msg));
- X else if (current_msg < n_array[0]
- X || current_msg > n_array[screen-1])
- X redo = 1;
- X }
- X
- X /*
- X * write/save messages. If a list is necessary, the user already
- X * entered it above since he must have used a capital letter. If so,
- X * list will contain good data (already been validated above).
- X * if a list is given, set iscurses to 0 so that print statements
- X * will scroll and the user sees the multiple output. else, one
- X * line can go on the bottom line just fine.
- X */
- X when C_WRITE_MSG : case C_SAVE_MSG : case C_COPY_MSG :
- X case C_WRITE_LIST : case C_SAVE_LIST : case C_COPY_LIST : {
- X register char *p =
- X (c == C_WRITE_MSG || c == C_WRITE_LIST)? "write" :
- X (c == C_SAVE_MSG || c == C_SAVE_LIST)? "save" : "copy";
- X if (!msg_cnt) {
- X print("No messages.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X break;
- X }
- X print(sprintf(buf, "filename to %s%s: ", p,
- X (c != C_WRITE_MSG && c != C_WRITE_LIST)? " [mbox]" : ""));
- X if (Getstr(file, COLS-1-strlen(buf), 0) >= 0) {
- X char *argv[3];
- X clr_bot_line();
- X argv[0] = strcpy(buf, p);
- X p = file; skipspaces(0);
- X argv[1] = (*p) ? p : NULL;
- X argv[2] = NULL;
- X if (!*list)
- X set_msg_bit(msg_list, current_msg);
- X move(LINES-1, 0), refresh();
- X if (*list)
- X iscurses = FALSE;
- X /* Turn on piping to make save_msg look at msg_list */
- X turnon(glob_flags, IS_PIPE);
- X if (save_msg(1 + (*file != '\0'), argv, msg_list) < 0)
- X *list = 0;
- X turnoff(glob_flags, IS_PIPE);
- X if (ison(glob_flags, CNTD_CMD))
- X redo = 1, putchar('\n'), puts(compose_hdr(current_msg));
- X if (*list)
- X iscurses = redo = TRUE, turnon(glob_flags, CNTD_CMD);
- X else if (isoff(glob_flags, CNTD_CMD) && msg_cnt) {
- X move(curlin, 0);
- X printw("%-.*s", COLS-1, compose_hdr(current_msg));
- X }
- X } else {
- X print("No messages saved.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X }
- X }
- X
- X /* preserve message */
- X when C_PRESERVE :
- X if (!msg_cnt) {
- X print("No messages.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X break;
- X }
- X if (ison(msg[current_msg].m_flags, PRESERVE))
- X turnoff(msg[current_msg].m_flags, PRESERVE);
- X else
- X turnon(msg[current_msg].m_flags, PRESERVE);
- X turnon(glob_flags, DO_UPDATE);
- X if (ison(glob_flags, CNTD_CMD)) {
- X wprint("%-.*s\n", COLS-1, compose_hdr(current_msg));
- X redo = 1;
- X } else {
- X move(curlin, 0);
- X printw("%-.*s", COLS-1, compose_hdr(current_msg));
- X }
- X
- X /* order messages (sort) and redisplay the headers */
- X when C_SORT : case C_REV_SORT :
- X (void) strcpy(file, "sort");
- X if (c == C_REV_SORT) {
- X print("Reverse "), turnon(glob_flags, CONT_PRNT);
- X (void) strcat(file, " -");
- X }
- X print(
- X "Order messages by [author, date, length, Status, subject]: "
- X );
- X if ((c = m_getchar()) == 'a' || c == 'd' || c == 'l' ||
- X c == 'S' || c == 's' || c == 'R') {
- X print("reordering messages...");
- X (void) cmd_line(sprintf(buf, "%s %c", file, c), msg_list);
- X print_more("done.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n'), puts(compose_hdr(current_msg));
- X redo = 1;
- X } else
- X clr_bot_line();
- X
- X when C_QUIT_HARD :
- X (void) mush_quit(0, DUBL_NULL);
- X redo = 1; /* new mail must have come in */
- X
- X /* quit or update -- vrfy_update (returns 1 if updated) */
- X when C_QUIT : case C_UPDATE : {
- X clr_bot_line();
- X redo = (c == C_UPDATE);
- X if (!vrfy_update(&redo))
- X if (c == C_UPDATE)
- X break;
- X if (isoff(glob_flags, CNTD_CMD))
- X (void) cmd_line(sprintf(buf, "\\headers %d", current_msg+1),
- X msg_list);
- X }
- X
- X when C_EXIT : case C_EXIT_HARD :
- X clr_bot_line();
- X iscurses = FALSE;
- X if (c != C_EXIT && c != C_EXIT_HARD)
- X putchar('\n');
- X cleanup(0);
- X
- X /* change to a new folder */
- X when C_FOLDER :
- X for (;;) {
- X SIGRET (*oldint)(), (*oldquit)();
- X on_intr();
- X print("New folder (?=list): ");
- X c = Getstr(file, COLS-22, 0);
- X off_intr();
- X if (c > 0) {
- X if (!strcmp(file, "?")) {
- X clr_bot_line();
- X iscurses = 0;
- X puts("folders in your folder directory:");
- X (void) cmd_line(strcpy(buf, "\\folders"), msg_list);
- X puts("Precede folder names with a +. `%' to specify system mailbox.");
- X turnon(glob_flags, CNTD_CMD), iscurses = 1;
- X continue;
- X }
- X clearok(stdscr, FALSE);
- X /* if vrfy_update doesn't verify, but folder command fails,
- X * then we need to reset the updatability of current folder
- X */
- X c = (ison(glob_flags, DO_UPDATE))? TRUE : FALSE;
- X if (strcmp(file, "-?")) {
- X redo = 1; /* so vrfy_update() won't quit */
- X (void) vrfy_update(&redo);
- X }
- X move(LINES-1, 0), refresh();
- X if (cmd_line(sprintf(buf, "folder ! -N %s", file),
- X msg_list) == -1) {
- X if (c) /* remember state of updatability of folder */
- X turnon(glob_flags, DO_UPDATE);
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X } else
- X redo = 1, turnoff(glob_flags, CNTD_CMD);
- X break;
- X } else {
- X print("\"%s\" unchanged.", mailfile);
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X break;
- X }
- X }
- X
- X /* shell escape */
- X when C_SHELL_ESC :
- X print("Shell command: ");
- X if (Getstr(file, COLS-24, 0) < 0)
- X clr_bot_line();
- X else {
- X putchar('\n');
- X iscurses = FALSE;
- X (void) cmd_line(sprintf(buf, "sh %s", file), msg_list);
- X iscurses = TRUE;
- X turnon(glob_flags, CNTD_CMD);
- X }
- X
- X /* do a line-mode like command */
- X when C_CURSES_ESC :
- X print(":");
- X if (Getstr(buf, COLS-2, 0) < 0)
- X break;
- X putchar('\n');
- X iscurses = FALSE;
- X if (!*buf) {
- X /* return -1 because iscurses = 0 is not enough! */
- X redo = 0;
- X endwin(); /* this turns echoing back on! */
- X echo_off();
- X return -1;
- X }
- X /* The "source" and "curses" commands need some indication
- X * that we are in curses mode, so use the PRE_CURSES flag.
- X */
- X turnon(glob_flags, PRE_CURSES);
- X (void) cmd_line(buf, msg_list);
- X /* they may have affected message status or had text output */
- X turnon(glob_flags, CNTD_CMD), redo = 1;
- X turnoff(glob_flags, PRE_CURSES);
- X iscurses = TRUE;
- X if (msg_cnt)
- X puts(compose_hdr(current_msg));
- X
- X /* send message to printer, redo to display 'p' status */
- X when C_PRINT_MSG : redo = (lpr(0, DUBL_NULL, msg_list) == 0);
- X
- X /* cd */
- X when C_CHDIR :
- X print("chdir to [~]: ");
- X if (Getstr(file, COLS-12, 0) < 0)
- X break;
- X clr_bot_line();
- X (void) cmd_line(sprintf(buf, "cd %s", file), msg_list);
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X
- X /* variable settings */
- X when C_VAR_SET : case C_IGNORE : case C_ALIAS : case C_OWN_HDR :
- X curs_vars(c); /* CNTD_CMD is reset if there's output! */
- X
- X when C_VERSION :
- X (void) do_version();
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X
- X when C_MAIL_FLAGS :
- X print("flags [-?]: ");
- X if ((c = Getstr(file, COLS-12, 0)) < 0)
- X break;
- X putchar('\n');
- X if (c == 0)
- X (void) strcpy(file, "-?");
- X else
- X redo = 1; /* In case of -f flag, to display the 'f' status */
- X /* Fall thru */
- X case C_MAIL : {
- X u_long flgs = glob_flags;
- X turnon(glob_flags, IGN_BANG);
- X clr_bot_line();
- X iscurses = FALSE;
- X (void) cmd_line(sprintf(buf, "mail %s", file), msg_list);
- X glob_flags = flgs;
- X iscurses = TRUE, turnon(glob_flags, CNTD_CMD);
- X if (msg_cnt)
- X print("%-.*s", COLS-2, compose_hdr(current_msg)), putchar('\n');
- X }
- X
- X /* reply to mail */
- X when C_REPLY_SENDER : case C_REPLY_ALL : {
- X register char *p = (c == C_REPLY_ALL)? "replyall" : "replysender";
- X clr_bot_line();
- X iscurses = FALSE;
- X if (isoff(msg[current_msg].m_flags, REPLIED))
- X redo = 1;
- X (void) cmd_line(sprintf(buf, "%s %d", p, current_msg+1),
- X msg_list);
- X if (msg_cnt)
- X puts(compose_hdr(current_msg));
- X iscurses = TRUE, turnon(glob_flags, CNTD_CMD);
- X }
- X
- X /* type out a message */
- X when C_DISPLAY_MSG : case C_TOP_MSG : case C_DISPLAY_NEXT :
- X if (!msg_cnt ||
- X c != C_DISPLAY_NEXT && ison(msg[current_msg].m_flags, DELETE)) {
- X if (!msg_cnt)
- X print("No messages.");
- X else
- X print("Message %d deleted; type 'u' to undelete.",
- X current_msg+1);
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X break;
- X }
- X clr_bot_line();
- X iscurses = FALSE;
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X if (c == C_DISPLAY_MSG)
- X c = cmd_line(strcpy(buf, "type"), msg_list);
- X else if (c == C_TOP_MSG)
- X c = cmd_line(strcpy(buf, "top"), msg_list);
- X else {
- X /* "next" screws up the screen whether it displays or not */
- X (void) cmd_line(strcpy(buf, "next"), msg_list);
- X c = 0;
- X }
- X if (c > -1)
- X turnon(glob_flags, CNTD_CMD), redo = 1;
- X iscurses = TRUE;
- X puts(compose_hdr(current_msg));
- X
- X /* bind a key or string to a curses-mode command */
- X when C_BIND : case C_UNBIND : case C_MAP : case C_BIND_MACRO :
- X case C_MAP_BANG : {
- X char *argv[2];
- X argv[0] = (c == C_BIND) ? "bind" :
- X (c == C_UNBIND) ? "unbind" :
- X (c == C_MAP) ? "map" :
- X (c == C_MAP_BANG) ? "map!" : "bind-macro";
- X argv[1] = NULL;
- X if (bind_it(1, argv) < -1)
- X turnon(glob_flags, CNTD_CMD);
- X else if (ison(glob_flags, CNTD_CMD)) /* if it was set anyway */
- X putchar('\n');
- X else
- X (void) curses_help_msg(TRUE);
- X }
- X
- X when C_MACRO :
- X turnon(glob_flags, IN_MACRO);
- X /* Current macro should already be in the mac_stack, so
- X * all we have to do here is look for the next character
- X */
- X
- X /* help stuff */
- X when C_HELP :
- X move(LINES-1, 0), refresh();
- X (void) help(0, "curses", cmd_help);
- X turnon(glob_flags, CNTD_CMD);
- X if (msg_cnt)
- X puts(compose_hdr(current_msg));
- X
- X otherwise :
- X mac_flush();
- X bell();
- X if (ison(glob_flags, CNTD_CMD)) {
- X /* use print instead of puts to overwrite hit_return msg */
- X print("unknown command"), putchar('\n');
- X redo = 1;
- X }
- X }
- X
- X if (ison(glob_flags, CNTD_CMD)) {
- X int old_cnt = msg_cnt;
- X if (!(c = hit_return()) && !redo && msg_cnt == old_cnt)
- X redraw();
- X clr_bot_line();
- X if (old_cnt != msg_cnt)
- X redo = 1;
- X if (c)
- X return c;
- X }
- X if (redo) {
- X set_screen_size(); /* it may have changed */
- X n = current_msg;
- X clear();
- X if (/* msg_cnt < screen || */ n_array[0] < n && n < n_array[screen-1])
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X else
- X (void) cmd_line(sprintf(buf, "\\headers %d", n+1), msg_list);
- X (void) curses_help_msg(TRUE);
- X redo = 0;
- X }
- X return 0;
- X}
- X
- Xvrfy_update(redo)
- Xint *redo;
- X{
- X char buf[16];
- X int c;
- X
- X /* update current folder */
- X if (ison(glob_flags, DO_UPDATE)) {
- X if (ison(glob_flags, READ_ONLY)) {
- X mac_flush();
- X print("Folder is read-only.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X return 0;
- X }
- X print("Update folder [y]? ");
- X if ((c = getchar()) != 'y' && c != 'Y' && c != '\n' && !isspace(c)) {
- X print("Folder unchanged.");
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X return 0;
- X }
- X } else if (*redo)
- X return 1;
- X if (cmd_line(strcpy(buf, *redo? "update" : "quit"), msg_list) != -1
- X && ison(glob_flags, CNTD_CMD))
- X *redo = 1, turnoff(glob_flags, CNTD_CMD);
- X turnoff(glob_flags, DO_UPDATE);
- X return 1; /* make sure bottom line is clear and no reverse video */
- X}
- X
- Xscrn_line(line, buf)
- Xchar *buf;
- X{
- X#ifndef A_CHARTEXT
- X (void) strncpy(buf, stdscr->_y[line], COLS-1);
- X buf[COLS-1] = 0; /* strncpy does not null terminate */
- X#else
- X int n;
- X
- X for (n = 0; n < COLS; n++)
- X if ((buf[n] = (mvinch(line, n) & A_CHARTEXT)) == '\0')
- X break;
- X buf[n] = '\0';
- X#endif /* A_CHARTEXT */
- X}
- X
- X/*
- X * Generate the help message from the variable curses_help.
- X * If visible is true, the message is displayed,
- X * otherwise its size (in lines) is computed and returned.
- X */
- Xcurses_help_msg(visible)
- Xint visible;
- X{
- X int count, i, len, siz = 0, mxm = 0;
- X static int old_siz = 0;
- X register struct cmd_map *list;
- X extern struct cmd_map map_func_names[];
- X char *curs_help = do_set(set_options, "curses_help"), **format;
- X
- X if (!curs_help) {
- X if (old_siz && visible) {
- X int bot = min(n_array[screen-1], msg_cnt-1);
- X move(max(0, bot - n_array[0]) + 2, 0), clrtobot();
- X old_siz = 0;
- X }
- X return 0;
- X } else if (!*curs_help)
- X curs_help = DEF_CURSES_HELP;
- X /* Split the help string into words */
- X if (!(format = mk_argv(curs_help, &count, FALSE)) || count <= 0)
- X return 0;
- X /* Generate a help message for each word */
- X for (i = 0; i < count; i++) {
- X char buf[MAX_BIND_LEN*2+MAX_LONG_CMD+5], asc[MAX_BIND_LEN*2];
- X
- X buf[0] = '\0'; /* default to empty in case of no match */
- X for (list = cmd_map; list; list = list->m_next) {
- X if (!strcmp(format[i], map_func_names[list->m_cmd].m_str)) {
- X len = strlen(sprintf(buf, "(%s) %s ",
- X ctrl_strcpy(asc, list->m_str, FALSE),
- X map_func_names[list->m_cmd].m_str));
- X if (len > mxm)
- X mxm = len;
- X break;
- X }
- X }
- X strdup(format[i], buf); /* replace word with its "definition" */
- X }
- X /* Columnate the output nicely */
- X if (mxm > 0) {
- X len = (COLS - 1) / mxm;
- X if (len == 0) {
- X if (visible)
- X print("Curses help message too long!");
- X return 0;
- X }
- X siz = count / len;
- X if (count % len)
- X siz++;
- X if (siz > LINES / 3) {
- X if (visible)
- X print("Curses help message too long!");
- X return 0;
- X }
- X if (visible) {
- X int next = LINES - 1 - siz;
- X if (old_siz > siz) {
- X int bot = min(n_array[screen-1], msg_cnt-1);
- X move(max(0, bot - n_array[0]) + 2, 0), clrtobot();
- X }
- X old_siz = siz;
- X for (i = 0; i < count; i++) {
- X if (!(i % len))
- X move(next, 0), clrtoeol(), ++next;
- X if (format[i][0])
- X printw("%-*.*s", mxm, mxm, format[i]);
- X }
- X refresh();
- X }
- X }
- X free_vec(format);
- X return siz;
- X}
- X
- Xset_screen_size()
- X{
- X int hlp_siz = LINES - 2 - curses_help_msg(FALSE);
- X
- X if (!do_set(set_options, "screen"))
- X#ifdef USG
- X switch (_tty.sg_ospeed & CBAUD)
- X#else /* USG */
- X switch (_tty.sg_ospeed)
- X#endif /* USG */
- X {
- X case B300 : screen = min(hlp_siz, 7);
- X when B1200 : screen = min(hlp_siz, 14);
- X when B2400 : screen = min(hlp_siz, 22);
- X otherwise : screen = hlp_siz;
- X }
- X else
- X screen = min(screen, hlp_siz);
- X}
- X
- X/*
- X * prompt for a carriage return, but return whatever user types unless
- X * it's a character which he might regret (like 'q' or 'x'). Ignore
- X * interrupts (kind of) because we have nowhere to longjmp to. When we
- X * return, we'll setjmp again (top of loop.c)
- X */
- Xhit_return()
- X{
- X int c;
- X
- X turnon(glob_flags, IGN_SIGS);
- X iscurses = FALSE;
- X (void) check_new_mail();
- X iscurses = TRUE;
- X mail_status(1), addstr("...continue... "), refresh();
- X c = getcmd();
- X turnoff(glob_flags, IGN_SIGS);
- X
- X /* don't let the user type something he might regret */
- X if (c == C_QUIT || c == C_EXIT)
- X return C_NULL;
- X return c;
- X}
- X
- Xcurses_msg_list(str, list, m_list)
- Xregister char *str, *list;
- Xchar m_list[];
- X{
- X register char *p = NULL;
- X int c, sv_cur_msg = current_msg;
- X
- X print(str);
- X c = Getstr(list, COLS-13, 0);
- X move(LINES-1, 0), refresh();
- X if (c <= 0 || !(p = do_range(list, m_list)) ||
- X (p == list && *p && *p != '$' && *p != '^')) {
- X if (p)
- X print("Invalid message list: %s", p);
- X current_msg = sv_cur_msg;
- X return 0;
- X }
- X current_msg = sv_cur_msg;
- X return 1;
- X}
- X
- Xcurs_vars(which)
- Xint which; /* really, a char */
- X{
- X char c, buf[128], buf2[128], *string;
- X struct options **list;
- X
- X switch(which) {
- X case C_OWN_HDR : string = "my_hdr", list = &own_hdrs;
- X when C_ALIAS : string = "alias", list = &aliases;
- X when C_IGNORE : string = "ignore", list = &ignore_hdr;
- X when C_VAR_SET : string = "set", list = &set_options;
- X otherwise : clr_bot_line(); return;
- X }
- X
- X print("%s [? Set Unset All]: ", string);
- X c = m_getchar();
- X clr_bot_line();
- X switch (Lower(c)) {
- X /* if help, print help -- if "all", show all settings. */
- X case '?' : case 'a' :
- X if (c == '?') {
- X if (!strcmp(string, "set")) {
- X print("which variable? [all <var>]: ");
- X if ((c = Getstr(buf+1, COLS-40, 0)) < 0)
- X return;
- X clr_bot_line();
- X buf[0] = '?';
- X if (c > 0) {
- X char *argv[3];
- X argv[0] = string;
- X argv[1] = buf;
- X argv[2] = NULL;
- X Lower(buf[1]);
- X if (!strcmp(buf+1, "a"))
- X (void) strcpy(buf+1, "all");
- X if (!strcmp(buf+1, "all"))
- X turnon(glob_flags, CNTD_CMD);
- X (void) set(2, argv, (char *) 0);
- X break;
- X }
- X }
- X /* help returns next command (hit_return) */
- X (void) help(0, string, cmd_help);
- X turnon(glob_flags, CNTD_CMD);
- X return;
- X }
- X turnon(glob_flags, CNTD_CMD);
- X (void) do_set(*list, NULL);
- X
- X /* if set, prompt for string and let user type */
- X when 's' :
- X print("set: ");
- X c = Getstr(buf, COLS-18, 0);
- X clr_bot_line();
- X if (c > 0)
- X (void) cmd_line(sprintf(buf2, "%s %s", string, buf), msg_list);
- X
- X /* if unset, just as easy as set! */
- X when 'u' :
- X print("unset: ", string);
- X if (Getstr(buf, COLS-18, 0) > 0 && !un_set(list, buf))
- X print("%s isn't set", buf);
- X }
- X if (ison(glob_flags, CNTD_CMD))
- X putchar('\n');
- X else
- X (void) curses_help_msg(TRUE);
- X}
- X#endif /* CURSES */
- END_OF_FILE
- if test 28433 -ne `wc -c <'mush/curses.c'`; then
- echo shar: \"'mush/curses.c'\" unpacked with wrong size!
- fi
- # end of 'mush/curses.c'
- fi
- if test -f 'mush/mush.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/mush.h'\"
- else
- echo shar: Extracting \"'mush/mush.h'\" \(22786 characters\)
- sed "s/^X//" >'mush/mush.h' <<'END_OF_FILE'
- X/* @(#)mush.h (c) copyright 1986 (Dan Heller) */
- X
- X#include "config.h"
- X
- X#ifdef CURSES
- X
- X#ifdef USG
- X# define _USG
- X# undef USG
- X#endif /* USG */
- X#ifdef SYSV
- X# define _SYSV
- X# undef SYSV
- X#endif /* SYSV */
- X#include <curses.h>
- X#if !defined(USG) && defined(_USG)
- X# define USG
- X#endif /* USG */
- X#if !defined(SYSV) && defined(_SYSV)
- X# define SYSV
- X#endif /* SYSV */
- X
- X#else /* CURSES */
- X#include <stdio.h>
- X#if defined(SYSV) && defined(USG)
- X#include <termio.h>
- X#endif /* SYSV && USG */
- X#endif /* CURSES */
- X
- X#include <ctype.h>
- X#include <errno.h>
- X#include <setjmp.h>
- X#include "strings.h"
- X
- X#ifdef BSD
- X#define fputs Fputs /* See comments in print.c */
- X#endif /* BSD */
- X
- Xextern char
- X *malloc(), /* allocate memory */
- X *calloc(), /* allocate and clear memory */
- X *realloc(); /* re-allocate memory */
- X
- Xextern void
- X free_vec(), /* free a malloc'ed argv */
- X xfree(); /* free malloc'ed pointers */
- X
- X#if defined(SUNTOOL) || defined(SUN_3_5) || defined(SUN_4_0) || defined(SUN_4_1)
- X#if !defined(BSD) && !defined(SYSV)
- X# define BSD /* default to BSD */
- X#endif /* !BSD && !SYSV */
- X#if !defined(SUN_3_5) && !defined(SUN_4_0)
- X# define SUN_4_0 /* default to sun 4.0 */
- X#endif /* !SUN_3_5 && !SUN_4_0 */
- X#ifdef SUN_4_0
- X# undef SUN_3_5
- X# undef SIGRET
- X# define SIGRET void
- X#endif /* SUN_4_0 */
- X#endif /* SUNTOOL || SUN_3_5 || SUN_4_0 */
- X
- X#ifdef SUNTOOL
- X# include <suntool/sunview.h>
- X#ifdef SUN_4_0
- X# include <suntool/alert.h>
- X#endif /* SUN_4_0 */
- X# include <suntool/textsw.h>
- X# include <sys/ioctl.h> /* for ltchars */
- X#else
- X# include <sys/types.h>
- X# include <signal.h>
- X# ifndef SYSV
- X# include <sys/time.h>
- X# include <sys/ioctl.h> /* for ltchars */
- X# else
- X# include <time.h>
- X# include <fcntl.h>
- X# endif /* SYSV */
- X#endif /* SUNTOOL */
- X
- X#include <sys/stat.h>
- X#include <sys/file.h>
- X
- X#ifdef SUNTOOL
- X# include <suntool/panel.h>
- X# include <suntool/canvas.h>
- X# include <suntool/tty.h>
- X# include <suntool/menu.h>
- X# include <suntool/icon.h>
- X# include <suntool/scrollbar.h>
- X# include <suntool/icon_load.h>
- X#endif /* SUNTOOL */
- X
- X/* if no maximum number of files can be found, we'll use getdtablesize() */
- X#ifdef _NFILE
- X# define MAXFILES _NFILE
- X#else
- X#ifdef NOFILE
- X# define MAXFILES NOFILE
- X#endif /* NOFILE */
- X#endif /* _NFILE */
- X
- X#ifndef MAXPATHLEN
- X#define MAXPATHLEN BUFSIZ
- X#endif /* MAXPATHLEN */
- X
- X#ifdef CTRL
- X#undef CTRL
- X#endif /* CTRL */
- X#define CTRL(c) ((c) & 037)
- X
- X#define ESC '\033'
- X
- X#define NO_STRING ""
- X#ifdef NULL
- X#undef NULL
- X#endif /* NULL */
- X#define NULL (char *)0
- X#define NULL_FILE (FILE *)0
- X#define DUBL_NULL (char **)0
- X#define TRPL_NULL (char ***)0
- X#ifdef putchar
- X#undef putchar
- X#endif /* putchar */
- X#define putchar(c) (void) (fputc(c, stdout), fflush(stdout))
- X#ifdef SUNTOOL
- Xextern int bell();
- X#else /* SUNTOOL */
- X#define bell() (void) (fputc('\007', stderr), fflush(stderr))
- X#endif /* SUNTOOL */
- X
- X/* For error recovery purposes, send keyboard generated signals to a special
- X * routine (interrupt) to set a global flag (WAS_INTR) and return to the
- X * calling routine which is responsible for checking the flag. For both
- X * on_intr() and off_intr() macros, initialize WAS_INTR to false.
- X */
- X#define on_intr() \
- X turnoff(glob_flags, WAS_INTR), oldint = signal(SIGINT, intrpt), \
- X oldquit = signal(SIGQUIT, intrpt)
- X
- X#define off_intr() \
- X (void) (turnoff(glob_flags, WAS_INTR), signal(SIGINT, oldint), \
- X signal(SIGQUIT, oldquit))
- X
- X/* Don't flush input when setting echo or cbreak modes (allow typeahead) */
- X#ifdef TIOCSETN
- X#ifdef stty
- X#undef stty
- X#endif /* stty */
- X#define stty(fd, sgttybuf) ioctl(fd, TIOCSETN, sgttybuf)
- X#endif /* TIOCSETN */
- X
- X/* for system-V machines that run termio */
- X#if defined(SYSV) && defined(USG)
- Xunsigned char vmin, vtime;
- X#define sg_erase c_cc[2]
- X#define sg_flags c_lflag
- X#define sg_kill c_cc[3]
- X#define sg_ospeed c_cflag
- X#define gtty(fd, SGTTYbuf) ioctl(fd, TCGETA, SGTTYbuf)
- X#undef stty
- X#define stty(fd, SGTTYbuf) ioctl(fd, TCSETAW, SGTTYbuf)
- X#define echon() (_tty.sg_flags |= (ECHO|ECHOE), stty(0, &_tty))
- X#define echoff() (_tty.sg_flags &= ~ECHO, stty(0, &_tty))
- X#define cbrkon() \
- X (_tty.sg_flags &= ~ICANON, _tty.c_cc[VMIN] = 1, stty(0, &_tty))
- X#define cbrkoff() \
- X (_tty.sg_flags |= ICANON,_tty.c_cc[VMIN] = vmin,_tty.c_iflag |= ICRNL, \
- X _tty.c_cc[VTIME] = vtime, stty(0, &_tty))
- X#define savetty() \
- X (void) gtty(0, &_tty), vtime = _tty.c_cc[VTIME], vmin = _tty.c_cc[VMIN]
- X#define cbreak() cbrkon()
- X#define nocbreak() cbrkoff()
- X
- X/* If curses isn't defined, declare our 'tty' and macros for echo/cbreak */
- X#ifndef CURSES
- Xtypedef struct termio SGTTY;
- X#define echom() echon()
- X#define noechom() echoff()
- X#define crmode() cbrkon()
- X#define nocrmode() cbrkoff()
- X
- X#else /* CURSES */
- X/* If curses is defined, use the echo/cbreak commands in library only
- X * if curses is running. If curses isn't running, use macros above.
- X */
- X#define echom() ((iscurses) ? echo(): echon())
- X#define noechom() ((iscurses) ? noecho(): echoff())
- X#define crmode() ((iscurses) ? cbreak() : cbrkon())
- X#define nocrmode() ((iscurses) ? nocbreak() : cbrkoff())
- X#endif /* CURSES */
- X#endif /* SYSV && USG */
- X
- X#if !defined(USG)
- X#ifndef CURSES
- X/* if curses is not defined, simulate the same tty based macros */
- Xtypedef struct sgttyb SGTTY;
- X/* Do real ioctl calls to set the tty modes */
- X#define crmode() (_tty.sg_flags |= CBREAK, stty(0, &_tty))
- X#define nocrmode() (_tty.sg_flags &= ~CBREAK, stty(0, &_tty))
- X#define echom() (_tty.sg_flags |= ECHO, stty(0, &_tty))
- X#define noechom() (_tty.sg_flags &= ~ECHO, stty(0, &_tty))
- X#define savetty() (void) gtty(0, &_tty)
- X#else /* CURSES */
- X#define echom() echo()
- X#define noechom() noecho()
- X#endif /* ~CURSES */
- X#endif /* ~USG */
- X
- X/* With all that out of the way, we can now declare our tty type */
- XSGTTY _tty;
- X
- Xextern char
- X del_line, /* tty delete line character */
- X del_word, /* tty delete word character */
- X del_char, /* backspace */
- X reprint_line, /* usually ^R */
- X eofc, /* usually ^D */
- X lit_next, /* usually ^V */
- X complete, /* word completion, usually ESC */
- X complist; /* completion listing, usually tab */
- X
- X/* These macros now turn on/off echo/cbreak independent of the UNIX running */
- X#define echo_on() \
- X if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) nocrmode(), echom()
- X#define echo_off() \
- X if (_tty.sg_flags && isoff(glob_flags, ECHO_FLAG)) crmode(), noechom()
- X
- X#define strdup(dst, src) (xfree (dst), dst = savestr(src))
- X#define Debug if (debug == 0) {;} else (void) wprint
- X
- X#ifdef SYSV
- X#ifndef L_SET
- X#define L_SET 0
- X#endif /* L_SET */
- X#ifndef F_OK
- X#define F_OK 000
- X#define R_OK 004
- X#define W_OK 002
- X#define E_OK 001
- X#endif /* F_OK */
- X#ifdef u_long
- X#undef u_long
- X#endif /* u_long */
- X#define u_long unsigned long
- X#ifndef HPUX
- X#define vfork fork
- X#endif /* HPUX */
- X#ifndef SIGCHLD
- X#define SIGCHLD SIGCLD
- X#endif /* SIGCHLD */
- X#endif /* SYSV */
- X
- X#if !defined(SUNTOOL) && !defined(CURSES)
- X
- X#define TRUE 1
- X#define FALSE 0
- X#define print (void) printf
- X#define wprint (void) printf
- X#define print_more (void) printf
- X
- X#endif /* !SUNTOOL && !CURSES */
- X
- X#ifndef max
- X#define max(a,b) (((a) > (b)) ? (a) : (b))
- X#define min(a,b) (((a) < (b)) ? (a) : (b))
- X#endif /* max */
- X
- X#if defined(CURSES) && (!defined(SUNTOOL))
- X#define wprint (void) printf
- X#endif /* CURSES && (!SUNTOOL) */
- X
- X#ifdef SUNTOOL
- X/* stdout may be closed */
- X#define printf wprint
- X#endif /* SUNTOOL */
- X
- X#if defined(CURSES) || defined(SUNTOOL)
- X#define print_more turnon(glob_flags, CONT_PRNT), print
- Xvoid print(); /* printf to window or curses or tty accordingly */
- X#endif /* CURSES || SUNTOOL */
- X
- X#define ArraySize(o) (sizeof(o) / sizeof(*o))
- X
- X#ifdef SUNTOOL
- X
- X#define NO_ITEM (Panel_item)0
- X#define NO_EVENT (struct inputevent *)0
- X#define TIME_OUT 60 /* sleep 60 secs between mailchecks */
- X#define PIX_XOR PIX_SRC ^ PIX_DST
- X#define ID event_id(event)
- X#define l_width() mush_font->pf_defaultsize.x /* width of letter */
- X#define l_height() mush_font->pf_defaultsize.y /* height of letter */
- X#define Clrtoeol(w,x,y) ((void) pw_text(w, x, y, PIX_SRC, mush_font, blank))
- X
- X/* Miscellaneous old-SunView cleanup */
- X#ifndef TTY_ARGV_DO_NOT_FORK
- X#define TTY_ARGV_DO_NOT_FORK (-1)
- X#endif
- X
- X#endif /* SUNTOOL */
- X
- X/* bits and pieces */
- X#define turnon(flg,val) ((flg) |= (u_long)(val))
- X#define turnoff(flg,val) ((flg) &= ~(u_long)(val))
- X#define ison(flg,val) ((u_long)(flg) & (u_long)(val))
- X#define isoff(flg,val) (!ison((flg), (val)))
- X#define set_replied(n) \
- X if (isoff(msg[n].m_flags, REPLIED)) \
- X turnon(glob_flags, DO_UPDATE), turnon(msg[n].m_flags, REPLIED)
- X#define set_isread(n) \
- X if (ison(msg[n].m_flags, UNREAD)) \
- X turnon(glob_flags, DO_UPDATE), turnoff(msg[n].m_flags, UNREAD)
- X
- X#define in_pipe() (ison(glob_flags, DO_PIPE|IS_PIPE))
- X#define in_macro() (ison(glob_flags, LINE_MACRO|IN_MACRO))
- X#define line_macro(s) (void) (turnon(glob_flags, LINE_MACRO), mac_push(s))
- X#define curs_macro(s) (void) (turnon(glob_flags, IN_MACRO), mac_push(s))
- X#define Ungetstr(s) (void) (turnon(glob_flags, QUOTE_MACRO), mac_push(s))
- X
- X/* global conditions */
- X#define is_shell (mailfile && *mailfile)
- X
- X/* msg lists represented by bits (8 should be replaced by sizeof(char) */
- X#define clear_msg_list(list) ((void) bzero(list, (msg_cnt+7)/8))
- X#define msg_bit(list, n) ((list[(n) / 8] >> ((n) % 8)) & 1)
- X#define set_msg_bit(list, n) (list[(n) / 8] |= (1 << ((n) % 8)))
- X#define unset_msg_bit(list, n) (list[(n) / 8] &= ~(1 << ((n) % 8)))
- X#define bput(S1, S2, Len, op) \
- X do { \
- X register char *s1 = S1, *s2 = S2; \
- X register int len = Len; \
- X while(len--) \
- X *s2++ op *s1++; \
- X } while (0)
- X#define bitput(m1,m2,len,op) bput(m1, m2, (((len)+7)/8), op)
- X
- X/* convenience and/or readability */
- X#define when break;case
- X#define otherwise break;default
- X#define lower(c) (isupper(c)? tolower(c): c)
- X#define Lower(c) (c = lower(c))
- X#define upper(c) (islower(c)? toupper(c): c)
- X#define Upper(c) (c = upper(c))
- X#define skipspaces(n) for(p += (n); *p == ' ' || *p == '\t'; ++p)
- X#define skipdigits(n) for(p += (n); isdigit(*p); ++p)
- X#define ismsgnum(c) (isdigit(c)||c=='.'||c=='^'||c=='$'||c=='*')
- X#define skipmsglist(n)\
- X for(p += (n); ismsgnum(*p) || index(" \t,-{`}", *p); ++p)\
- X if (*p != '`' || !p[1]) {;} else do ++p; while (*p && *p != '`')
- X
- X/* define a macro to declare unsigned-long bits */
- X#define ULBIT(bit) ((u_long)1 << (u_long)(bit))
- X
- X/* various flags */
- Xu_long glob_flags; /* global boolean flags thruout the whole program */
- X#define DO_UPDATE ULBIT(0) /* folder has been modified -- update it */
- X#define REV_VIDEO ULBIT(1) /* reverse video for curses or toolmode */
- X#define CONT_PRNT ULBIT(2) /* continue to print without a '\n' */
- X#define DO_SHELL ULBIT(3) /* run a shell even if no mail? (true if tool) */
- X#define DO_PIPE ULBIT(4) /* if commands are piping to other commands */
- X#define IS_PIPE ULBIT(5) /* true if commands' "input" comes from a pipe */
- X#define IGN_SIGS ULBIT(6) /* true if catch() should not longjmp */
- X#define IGN_BANG ULBIT(7) /* ignore ! as a history reference */
- X#define ECHO_FLAG ULBIT(8) /* if true, echo|cbreak is ON, echo typing (-e) */
- X#define IS_GETTING ULBIT(9) /* true if we're getting input for a letter */
- X#define PRE_CURSES ULBIT(10) /* true if curses will run, but hasn't started */
- X#define READ_ONLY ULBIT(11) /* -r passed to folder() for read only */
- X#define REDIRECT ULBIT(12) /* true if stdin is being redirected */
- X#define WAS_INTR ULBIT(13) /* catch interrupts, set this flag (signals.c) */
- X#define WARNING ULBIT(14) /* if set, various warning messages are printed */
- X#define NEW_MAIL ULBIT(15) /* new mail has arrived; mush is busy or closed */
- X#define CNTD_CMD ULBIT(16) /* curses.c -- promotes "...continue..." prompt */
- X#define IS_SENDING ULBIT(17) /* was run to send mail, not run as a shell */
- X#define MIL_TIME ULBIT(19) /* if $mil_time is set, use 24hr time fmt */
- X#define DATE_RECV ULBIT(20) /* $date_received: show date received on msgs */
- X#define IN_MACRO ULBIT(21) /* input is currently being read from a macro */
- X#define LINE_MACRO ULBIT(22) /* escape to line mode from curses in progress */
- X#define QUOTE_MACRO ULBIT(23) /* protect current macro from recursive expan.. */
- X#define NEW_FRAME ULBIT(24) /* toolmode should build a new frame for pager */
- X#define HELP_TEXT ULBIT(25) /* create textsw frame for paging help messages */
- X
- X/* flags to control composition */
- X#define VERBOSE ULBIT(0) /* verbose flag for sendmail */
- X#define INCLUDE ULBIT(1) /* include msg in response */
- X#define INCLUDE_H ULBIT(2) /* include msg with header */
- X#define EDIT ULBIT(3) /* enter editor by default on mailing */
- X#define SIGN ULBIT(4) /* auto-include ~/.signature in mail */
- X#define DO_FORTUNE ULBIT(5) /* add a fortune at end of msgs */
- X#define EDIT_HDRS ULBIT(6) /* user edits headers using editor */
- X#define SEND_NOW ULBIT(7) /* send without further changes */
- X#define NO_SIGN ULBIT(8) /* override SIGN and DO_FORTUNE */
- X
- X/* msg flags */
- X#define PRINTED ULBIT(4) /* sent through lpr command */
- X#define NO_HEADER ULBIT(6) /* don't print header of message */
- X#define DELETE ULBIT(7)
- X#define OLD ULBIT(8)
- X#define UNREAD ULBIT(9)
- X#define UPDATE_STATUS ULBIT(10) /* change status of msg when copyback */
- X#define NO_PAGE ULBIT(11) /* don't page this message */
- X#define INDENT ULBIT(12) /* indent included msg with string */
- X#define NO_IGNORE ULBIT(13) /* don't ignore headers */
- X#define PRESERVE ULBIT(14) /* preserve in mailbox unless deleted */
- X#define M_TOP ULBIT(14) /* just print the top of msg (same as pre) */
- X#define FORWARD ULBIT(15) /* Forward messages into the message buffer */
- X#define REPLIED ULBIT(16) /* Messages that have been replied to */
- X#define NEW_SUBJECT ULBIT(17) /* new subject regardless of $ask (mail -s) */
- X#define SAVED ULBIT(18) /* when message has been saved */
- X#ifdef MSG_SEPARATOR
- X#define NO_SEPARATOR ULBIT(19) /* don't include message separator lines */
- X#endif /* MSG_SEPARATOR */
- X
- X#define MAXMSGS_BITS MAXMSGS/sizeof(char) /* number of bits for bitmap */
- X
- Xstruct msg {
- X u_long m_flags;
- X long m_offset; /* offset in tempfile of msg */
- X long m_size; /* number of bytes in msg */
- X int m_lines; /* number of lines in msg */
- X char *m_date_recv;/* Date user received msg (see dates.c for fmt) */
- X char *m_date_sent;/* Date author sent msg (see dates.c for fmt) */
- X} msg[MAXMSGS];
- X
- Xstruct options {
- X char *option;
- X char *value;
- X struct options *next;
- X} *set_options, *aliases, *ignore_hdr, *functions, *fkeys, *own_hdrs;
- X
- X#define chk_option(v,f) chk_two_lists(do_set(set_options,(v)), (f), "\t ,")
- X
- Xstruct cmd {
- X char *command;
- X int (*func)();
- X};
- Xextern struct cmd ucb_cmds[];
- Xextern struct cmd cmds[], hidden_cmds[];
- X
- XFILE
- X *tmpf, /* temporary holding place for all mail */
- X *mask_fopen(), /* open a file with umask 077 (permissions 600) */
- X *open_file(), /* open a file or program for write/append */
- X *lock_fopen(), /* open and lock a file as an atomic operation */
- X *popen(); /* this should be in stdio.h */
- X
- Xextern char
- X *sys_errlist[], /* system's list of global error messages */
- X **environ; /* user's environment variables */
- X
- Xextern int errno; /* global system error number */
- Xjmp_buf jmpbuf; /* longjmp to jmpbuf on sigs (not in tool) */
- X
- Xchar
- X debug, /* debug causes various print statements in code */
- X tempfile[MAXPATHLEN], /* path to filename of temporary file */
- X msg_list[MAXMSGS_BITS], /* MAXMSGS bits of boolean storage */
- X **alternates, /* alternates list --see alts() */
- X *cmd_help, /* filename of location for "command -?" commands. */
- X *login, /* login name of user */
- X *mailfile, /* path to filename of current mailfile */
- X **ourname, /* the name and aliases of the current host */
- X **known_hosts, /* the names of all hosts connected via uucp */
- X *prompt, /* the prompt string -- may have %d */
- X *format_prompt(), /* function to format prompts from the prompt string */
- X *escape, /* the "tilde escape" when inputting text to letter */
- X *hdrs_only, /* true if -H flag was given --set to args */
- X *hdr_format, /* set to the header format string; referenced a lot */
- X *spoolfile, /* MAILDIR/$USER in a string -- this is used a lot */
- X *msg_get(), /* find start of message and return From_ line */
- X *do_range(), /* parse a string converting to a "range" of numbers */
- X *getpath(), /* static char returning path (expanding ~, +, %, #) */
- X *getdir(), /* uses getpath() to expand and test directory names */
- X *do_set(), /* set/unset an option, alias, ignored-hdr */
- X *reverse(), /* reverse a string */
- X *trim_filename(), /* remove or condense leading file name path */
- X *prog_name,
- X
- X /* from loop.c */
- X **make_command(), /* build a command vector (argv) */
- X **mk_argv(), /* given a string, make a vector */
- X *variable_stuff(), /* return information about variables */
- X *check_internal(), /* test or evaluate internal variables */
- X
- X /* from dates.c */
- X *Time(), /* returns string expression of time (takes args) */
- X *date_to_ctime(), /* convert a date into ctime() format */
- X *date_to_string(), /* returns a string described by parse_date() */
- X *msg_date(), /* return a string of the date of a message */
- X *parse_date(), /* parse an ascii date, and return message-id str */
- X *rfc_date(), /* create a date string compliant to RFC822 */
- X
- X /* from hdrs.c */
- X *cc_to(), /* when responding, return str which is the cc-list */
- X *compose_hdr(), /* passes hdr_format to format_hdr() for displays */
- X *format_hdr(), /* returns a formatted line describing passed msg # */
- X *header_field(), /* the line in msg described by arg (message header) */
- X *reply_to(), /* who do we reply to when responding */
- X *subject_to(), /* when responding, return str which is the subject */
- X
- X /* addrs.c */
- X *alias_to_address(),/* convert a name[list] to "real" names */
- X *bang_form(), /* construct a !-style form of an address */
- X *get_name_n_addr(), /* get name and addr from a well-formed address */
- X *set_header(), /* [interactive] proc to set/display to/subject/cc */
- X *wrap_addrs(); /* insert newlines in between headers */
- X
- Xint
- X last_msg_cnt, /* when checking for new mail, save the last msg_cnt */
- X msg_cnt, /* total number of messages */
- X crt, /* min number of lines msg contains to invoke pager */
- X current_msg, /* the current message we're dealing with */
- X exec_pid, /* pid of a command that has been "exec"ed */
- X hist_no, /* command's history number */
- X iscurses, /* if we're running curses */
- X istool, /* argv[0] == "xxxxtool", ranges from 0 to 2 */
- X n_array[128], /* array of message numbers in the header window */
- X screen, /* number of headers window can handle */
- X wrapcolumn, /* compose mode line wrap, measured from left */
- X
- X close_lock(), /* unlock and close a file opened by lock_fopen() */
- X
- X mush_quit(), do_alias(), respond(), cd(), sh(), stop(),
- X folder(), folders(), merge_folders(), do_undigest(),
- X save_msg(), delete(), do_mail(), lpr(), alts(), set(), do_hdrs(),
- X save_opts(), preserve(), sort(), readmsg(), edit_msg(), eval_cmd(),
- X do_pick(), print_help(), question_mark(), do_from(), my_stty(),
- X do_version(), disp_hist(), source(), do_echo(), ls(), pipe_msg(),
- X await(), nopenfiles(), file_to_fp(),
- X check_new_mail(), get_new_mail(), show_new_mail(),
- X Setenv(), Unsetenv(), Printenv(), msg_flags(), toggle_debug();
- X
- X#ifndef SIGRET
- X#define SIGRET int
- X#endif /* SIGRET */
- XSIGRET
- X rm_edfile(), /* remove letter-compose file on interrupts */
- X stop_start(), /* handle job control signals */
- X bus_n_seg(), /* handle runtime segfaults -- exit gracefully */
- X sigchldcatcher(), /* account for terminated child processes */
- X catch(), /* catch user (keyboard) generated signals */
- X intrpt(); /* handle interrupts when we don't want to */
- X
- Xlong
- X spool_size, /* size of spool mail regardless of current folder */
- X last_size, /* the last size of the mailfile since last check */
- X time(); /* satisfy lint */
- X
- Xvoid
- X error(), getmail(), mail_status(), sign_letter(),
- X init(), display_msg(), cleanup(), fs_error();
- X /* printf(), fclose(), fflush(), fputs(), fputc() */
- X#ifdef TIOCGLTC
- Xstruct ltchars ltchars; /* tty character settings */
- X#endif /* TIOCGLTC */
- X#ifdef BSD /* (TIOCGETC) */
- Xstruct tchars tchars; /* more tty character settings */
- X#endif /* BSD (TIOCGETC) */
- X
- X#ifdef CURSES
- X
- X#define STANDOUT(y,x,s) standout(), mvaddstr(y,x,s), standend()
- X#define redraw() clearok(curscr, TRUE), wrefresh(curscr)
- X
- Xint
- X curses_init(); /* interpret commands via the curses interface */
- X#endif /* CURSES */
- X
- Xint
- X mac_push(), /* set up a string as a macro */
- X bind_it(); /* bind strings to functions or macros */
- X
- Xvoid
- X mac_flush(); /* Abandon macro processing (on error) */
- X
- X#ifdef SUNTOOL
- Xvoid
- X timeout_cursors(), do_file_dir(), toggle_mail_items(), ok_box(),
- X read_mail(), opts_panel_item(), view_options(), toolquit(), wprint(),
- X update_list_textsw(), check_icons();
- X
- Xchar
- X *find_key(), /* pass x,y coords to find which function key assoc. */
- X *panel_get(), /* returns what has been typed in a panel item */
- X *tool_help, /* help for tool-related things (sometimes, overlap) */
- X *more_prompt, /* when NULL, we're paging a msg; else pager prompt */
- X blank[128]; /* use to clear to end of line */
- X
- Xint
- X time_out, /* time out interval to wait for new mail */
- X is_iconic; /* set if the mushview window is iconic. */
- X
- XNotify_value
- X do_check(), /* check for new mail on timeout */
- X destroy_proc(), /* Destroy procedure. */
- X scroll_textwin(), /* Do fancy TEXTSW scrolling */
- X edit_msg_textwin(); /* Auto-positioning in compose TEXTSW */
- X
- XFrame tool; /* Main frame. */
- XFrame compose_frame; /* Compose frame. */
- XTextsw pager_textsw; /* for "paging" messages and other lists.. */
- XTextsw mfprint_sw; /* Textsw in main mush frame for wprint() */
- XTextsw cprint_sw; /* Textsw in compose frame for wprint() */
- XTextsw wprint_sw; /* Current text subwindow for wprint() */
- XCanvas hdr_sw; /* Canvas for message headers */
- XTty tty_sw; /* subwindow which forks a shell (usually editor) */
- X
- XPixwin
- X *hdr_win; /* pixwin for message headers */
- X
- Xstruct pixfont *mush_font; /* array of fonts */
- X
- Xstruct itimerval mail_timer; /* frequency to check for new mail */
- X
- Xextern Cursor l_cursor, m_cursor, r_cursor;
- Xextern Icon mail_icon;
- X
- X/* When trapping events that represent scrolling actions */
- Xtypedef enum {
- X MUSH_SCROLL_TO,
- X MUSH_SCROLL_RELATIVE,
- X MUSH_SCROLL_IGNORE,
- X MUSH_SCROLL_PASS_EVENT
- X} Scroll_action;
- X#endif /* SUNTOOL */
- END_OF_FILE
- if test 22786 -ne `wc -c <'mush/mush.h'`; then
- echo shar: \"'mush/mush.h'\" unpacked with wrong size!
- fi
- # end of 'mush/mush.h'
- fi
- if test -f 'mush/version.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mush/version.h'\"
- else
- echo shar: Extracting \"'mush/version.h'\" \(182 characters\)
- sed "s/^X//" >'mush/version.h' <<'END_OF_FILE'
- X/* @(#)version.h (c) Copyright 1989 (Dan Heller) */
- X
- X#define MUSHNAME "Mail User's Shell"
- X#define RELEASE_DATE "5/02/90"
- X#define RELEASE 7
- X#define REVISION "1"
- X#define PATCHLEVEL 1
- END_OF_FILE
- if test 182 -ne `wc -c <'mush/version.h'`; then
- echo shar: \"'mush/version.h'\" unpacked with wrong size!
- fi
- # end of 'mush/version.h'
- fi
- echo shar: End of archive 10 \(of 19\).
- cp /dev/null ark10isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 19 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-
-