v18i062: mush - Mail User's Shell, Part05/22
Dan Heller
argv at zipcode.com
Sun Apr 21 12:49:43 AEST 1991
Submitted-by: Dan Heller <argv at zipcode.com>
Posting-number: Volume 18, Issue 62
Archive-name: mush/part05
Supersedes: mush: Volume 12, Issue 28-47
#!/bin/sh
# do not concatenate these parts, unpack them in order with /bin/sh
# file command2.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 5; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping command2.c'
else
echo 'x - continuing file command2.c'
sed 's/^X//' << 'SHAR_EOF' >> 'command2.c' &&
X return -1;
X }
X
X (void) Unsetenv(2, argv);
X
X for (i = 0; environ[i]; i++);
X if (!spaces) {
X char **new_environ =
X (char **)malloc((unsigned) ((i+2) * sizeof(char *)));
X /* add 1 for the new item, and 1 for null-termination */
X if (!new_environ) {
X xfree(newstr);
X return -1;
X }
X spaces = 1;
X for (i = 0; new_environ[i] = environ[i]; i++);
X xfree((char *) environ);
X environ = new_environ;
X }
X environ[i] = newstr;
X environ[i+1] = NULL;
X spaces--;
X return 0;
}
X
Unsetenv(n, argv)
int n;
char **argv;
{
X char **envp, **last;
X
X if (n != 2 || !strcmp(argv[1], "-?"))
X return help(0, "unsetenv", cmd_help);
X
X n = strlen(argv[1]);
X for (last = environ; *last; last++);
X last--;
X
X for (envp = environ; envp <= last; envp++) {
X if (strncmp(argv[1], *envp, n) == 0 && (*envp)[n] == '=') {
X xfree(*envp);
X *envp = *last;
X *last-- = NULL;
X spaces++;
X }
X }
X return 0;
}
X
Printenv(argc, argv)
int argc;
char **argv;
{
X char **e;
X
X if (argv && argv[1] && !strcmp(argv[1], "-?"))
X return help(0, "printenv", cmd_help);
X for (e = environ; *e; e++)
X if (argc < 2 || !strncmp(*e, argv[1], strlen(argv[1])))
X wprint("%s\n", *e);
X return 0;
}
X
/*
X * internal stty call to allow the user to change his tty character
X * settings. sorry, no way to change cbreak/echo modes. Save echo_flg
X * so that execute() won't reset it.
X */
/*ARGSUSED*/
my_stty(un_used, argv)
int un_used;
char **argv;
{
X u_long save_echo = ison(glob_flags, ECHO_FLAG);
X
X if (istool)
X return 0;
X
X if (argv && argv[1] && !strcmp(argv[1], "-?"))
X return help(0, "stty", cmd_help);
X turnon(glob_flags, ECHO_FLAG);
X execute(argv);
X if (save_echo)
X turnon(glob_flags, ECHO_FLAG);
X else
X turnoff(glob_flags, ECHO_FLAG);
X
X savetty();
#ifdef TIOCGLTC
X if (ioctl(0, TIOCGLTC, <chars))
X error("TIOCGLTC");
#endif /* TIOCGLTC */
X echo_off();
X return 0;
}
X
/*
X * Edit a message...
X */
edit_msg(i, argv, list)
int i;
char *argv[], list[];
{
X int edited = 0;
X char buf[MAXPATHLEN], *b, *dir, **edit_cmd, *editor, *mktemp();
X u_long flags = 0L;
X char *cmd = *argv;
X FILE *fp;
X
X if (istool)
X return 0;
X
X if (*++argv && !strcmp(*argv, "-?"))
X return help(0, "edit_msg", cmd_help);
X
X if (ison(glob_flags, READ_ONLY)) {
X print("\"%s\" is read-only.\n", mailfile);
X return -1;
X }
X
X if (get_msg_list(argv, list) == -1)
X return -1;
X
X if (!(editor = do_set(set_options,
X (*cmd == 'v')? "visual" : "editor")) || !*editor)
X editor = DEF_EDITOR;
X
X for (i = 0; i < msg_cnt; i++) {
X if (!msg_bit(list, i))
X continue;
X
X if (edited) {
X print("Edit message %d [y/n/q]? ", i+1);
X if (Getstr(buf, sizeof (buf), 0) < 0 || lower(buf[0]) == 'q')
X return 0;
X if (buf[0] && buf[0] != 'y')
X continue;
X }
X
X b = buf + Strcpy(buf, editor);
X *b++ = ' ';
X
X /* getdir() uses the home directory if no tmpdir */
X if (!(dir = getdir(do_set(set_options, "tmpdir"))))
alted:
X dir = ALTERNATE_HOME;
X (void) mktemp(sprintf(b, "%s/.msgXXXXXXX", dir));
X if (!(fp = mask_fopen(b, "w+"))) {
X if (strcmp(dir, ALTERNATE_HOME))
X goto alted;
X error("can't create %s", b);
X return -1;
X }
X wprint("editing message %d ...", i+1);
X /* copy message into file making sure all headers exist. */
X turnon(flags, UPDATE_STATUS);
#ifdef MMDF
X turnon(flags, NO_SEPARATOR);
#endif /* MMDF */
X wprint("(%d lines)\n", copy_msg(i, fp, flags, NULL));
X
X if (edit_cmd = mk_argv(buf, &edited, FALSE)) {
X print("Starting \"%s\"...\n", buf);
X (void) fclose(fp);
X turnon(glob_flags, IS_GETTING);
X execute(edit_cmd);
X turnoff(glob_flags, IS_GETTING);
X free_vec(edit_cmd);
X if (load_folder(b, FALSE, (char *)i) > 0) {
X (void) unlink(b);
X edited = 1;
X }
X set_isread(i); /* if you edit it, you read it, right? */
X }
X }
X return 0;
}
X
/*
X * Pipe a message list to a unix command. This function is hacked together
X * from bits of readmsg, above, and other bits of display_msg (misc.c).
X */
pipe_msg(x, argv, list)
int x;
char **argv, list[];
{
X char *p = x ? *argv : NULL;
X char buf[256], *pattern = NULL;
X u_long flg = 0L;
X extern FILE *ed_fp;
X int show_deleted = !!do_set(set_options, "show_deleted");
X
X /* Increment argv only if argv[0] is the mush command "pipe" */
X if (x && p && (!strcmp(p, "pipe") || !strcmp(p, "Pipe"))) {
X if (p && *p == 'P')
X turnon(flg, NO_HEADER);
X while (x && *++argv && **argv == '-')
X if (!strcmp(*argv, "-?"))
X return help(0, "pipe_msg", cmd_help);
X else if (!strcmp(*argv, "-p") && !(pattern = *++argv)) {
X print("Specify a pattern with -p\n");
X return -1;
X }
X }
X if (!msg_cnt) {
X print("No messages.\n");
X return -1;
X }
X
X if (x && (x = get_msg_list(argv, list)) == -1)
X return -1;
X argv += x;
X if (!*argv) {
X turnon(flg, NO_HEADER);
X /* The constant strings must be constants because user's
X * $SHELL might not be appropriate since "sh" scripts are
X * usually sent. User can always (easily) override.
X */
X (void) strcpy(buf, "/bin/sh");
X if (!pattern)
X pattern = "#!";
X } else
X (void) argv_to_string(buf, argv);
X if (!buf[0]) {
X print("Must specify a legitimate command or shell.\n");
X return -1;
X }
X current_msg = 0;
X if (!chk_option("alwaysignore", "pipe"))
X turnon(flg, NO_IGNORE);
#ifdef MMDF
X turnon(flg, NO_SEPARATOR);
#endif /* MMDF */
X (void) do_pager(buf, -1); /* start pager -- see do_pager() about "-1" */
X turnoff(glob_flags, WAS_INTR); /* if command interrupts, mush gets it */
X
X for (x = 0; x < msg_cnt && isoff(glob_flags, WAS_INTR); x++)
X if (msg_bit(list, x)) {
X current_msg = x;
X if (!show_deleted && ison(msg[x].m_flags, DELETE)) {
X print("Message %d deleted; ", x+1);
X if (iscurses)
X print_more("skipping it.");
X else
X print("skipping it.\n");
X continue;
X }
X set_isread(x);
X if (copy_msg(x, NULL_FILE, flg, pattern) == 0)
X print("No lines sent to %s!\n", buf);
X }
X (void) do_pager(NULL, FALSE); /* end pager */
X return 0;
}
X
/* echo the arguments. return 0 or -1 if -h given and there are no msgs. */
do_echo(n, argv)
int n;
char **argv;
{
X char buf[BUFSIZ], c;
X int no_return = 0, comp_hdr = 0, as_prompt = 0;
X
X while (n >= 0 && argv && *++argv && **argv == '-') {
X n = 1;
X while (n > 0 && (c = argv[0][n++]))
X switch(c) {
X case 'n': no_return++;
X when 'h': comp_hdr++;
X when 'p': as_prompt++;
X when '?': return help(0, "echo", cmd_help);
X otherwise: n = -1; break; /* Just echo whatever it was */
X }
X }
X if (comp_hdr && as_prompt) {
X print("-h and -p cannot be used together.\n");
X return -1;
X }
X
X (void) argv_to_string(buf, argv);
X if (comp_hdr) {
X if (!msg_cnt) {
X print("No messages.\n");
X return -1;
X }
X /* there may be a %-sign, so use %s to print */
X print("%s", format_hdr(current_msg, buf, FALSE)+9);
X } else if (as_prompt) {
X print("%s", format_prompt(current_msg, buf)); /* may be a %-sign */
X } else
X print("%s", buf); /* there may be a %-sign in "buf" */
X if (!no_return)
X print_more("\n");
X return 0;
}
X
eval_cmd (argc, argv, list)
int argc;
char *argv[], list[];
{
X int status = -1;
X u_long save_is_pipe;
X char **newav, buf[BUFSIZ];
X int comp_hdr = 0, as_prompt = 0, as_macro = 0;
X
X while (argv && *++argv && **argv == '-') {
X int c, n = 1;
X while (c = argv[0][n++])
X switch(c) {
X case 'h': comp_hdr++;
X when 'p': as_prompt++;
X when 'm': as_macro++;
X otherwise: return help(0, "eval", cmd_help);
X }
X }
X if (comp_hdr && as_prompt) {
X print("-h and -p cannot be used together.\n");
X return -1;
X }
X
X (void) argv_to_string(buf, argv);
X if (as_macro) {
X m_xlate(buf);
X mac_queue(buf);
X return 0;
X }
X newav = make_command(buf, TRPL_NULL, &argc);
X if (comp_hdr) {
X if (!msg_cnt) {
X print("No messages.\n");
X return -1;
X }
X /* This is inefficient, but the only way to preserve
X * imbedded quotes, tabs, etc. in format expansions.
X */
X for (argv = newav; argv && *argv; argv++) {
X /* Don't mess with one-character strings */
X if (argv[0][1]) {
X char *format = *argv;
X *argv = savestr(format_hdr(current_msg, format, FALSE)+9);
X Debug("expanding (%s) to (%s)\n", format, *argv);
X xfree(format);
X }
X }
X } else if (as_prompt) {
X for (argv = newav; argv && *argv; argv++) {
X /* Don't mess with one-character strings */
X if (argv[0][1]) {
X char *tmp = *argv;
X *argv = savestr(format_prompt(current_msg, tmp));
X Debug("expanding (%s) to (%s)\n", tmp, *argv);
X xfree(tmp);
X }
X }
X }
X /* Can't use cmd_line() because we want DO_PIPE and IS_PIPE
X * to remain on -- cmd_line() turns both of them off
X */
X if (newav) {
X save_is_pipe = ison(glob_flags, IS_PIPE);
X status = do_command(argc, newav, list);
X if (save_is_pipe)
X turnon(glob_flags, IS_PIPE);
X }
X return status;
}
X
await(argc, argv, list)
int argc;
char *argv[], list[];
{
X int done = 0, snooze = 30, last_cnt = msg_cnt;
X
X if (argc && *++argv) {
X if (!strcmp(*argv, "-?"))
X return help(0, "await", cmd_help);
X else if (!strcmp(*argv, "-T")) {
X if (*++argv && isdigit(**argv) && **argv > '0') {
X snooze = atoi(*argv);
X } else {
X print("await: integer greater than 0 required for -T\n");
X return -1;
X }
X }
X }
X Debug("snoozing %d\n", snooze);
X
X do {
X if (!(done = check_new_mail()))
X sleep((unsigned) snooze);
X } while (!done);
X /* Known to be safe to pass NULL to chk_two_lists() */
X if (!chk_option("quiet", "await"))
X bell();
X
X while (last_cnt < msg_cnt) {
X set_msg_bit(list, last_cnt);
X ++last_cnt;
X }
X
X return 0;
}
X
mark_msg(x, argv, list)
int x;
char **argv, list[];
{
X int i, set_priority = 0;
X int unmark = argv && argv[0] && argv[0][0] == 'u';
X
X if (argv && *++argv && !strcmp(*argv, "-?"))
X return help(0, "mark", cmd_help);
X
X /* command must be "mark [ -[A|B|C|D|E] ] [msg_list]" */
X if (!unmark && argv && *argv && **argv == '-') {
X if (!argv[0][1])
X set_priority = -1; /* special case for clearing priority */
X else if ((set_priority = (upper(argv[0][1]) - 'A' + 1)) < 1 ||
X set_priority > MAX_PRIORITY) {
X print("mark: priority -A through -%c required (- to clear)\n",
X MAX_PRIORITY + 'A');
X return -1;
X }
X ++argv;
X }
X if (x && (x = get_msg_list(argv, list)) == -1)
X return -1;
X argv += x;
X /* if extraneous args exist or the priority was misspecified... */
X if (argv[0]) {
X print("Unknown arg: %s. mark -? for help.\n", *argv);
X return -1;
X }
X for (x = 0; x < msg_cnt; x++)
X if (msg_bit(list, x)) {
X if (set_priority)
X /* could be setting priority or clearing all priorities */
X for (i = 1; i <= MAX_PRIORITY; i++)
X turnoff(msg[x].m_flags, M_PRIORITY(i));
X if (unmark)
X turnoff(msg[x].m_flags, M_PRIORITY(0));
X else if (set_priority > 0) {
X turnon(msg[x].m_flags, M_PRIORITY(set_priority)|DO_UPDATE);
X turnon(glob_flags, DO_UPDATE);
X } else if (set_priority == 0)
X turnon(msg[x].m_flags, M_PRIORITY(0));
X }
X if (istool > 1)
X (void) do_hdrs(0, DUBL_NULL, NULL);
X return 0;
}
SHAR_EOF
echo 'File command2.c is complete' &&
chmod 0644 command2.c ||
echo 'restore of command2.c failed'
Wc_c="`wc -c < 'command2.c'`"
test 13555 -eq "$Wc_c" ||
echo 'command2.c: original size 13555, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= commands.c ==============
if test -f 'commands.c' -a X"$1" != X"-c"; then
echo 'x - skipping commands.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting commands.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'commands.c' &&
/* @(#)commands.c (c) copyright 10/18/86 (Dan Heller) */
X
#include "mush.h"
X
/*
X * Note that all of the routines in here act upon and return 0 or -1.
X * if -1, then the main loop will clear message lists.
X */
X
struct cmd cmds[] = {
#ifdef SIGSTOP
X { "stop", stop },
#endif /* SIGSTOP */
X { "?", question_mark },{ "sh", sh },
X { "alias", do_alias }, { "unalias", do_alias },
X { "expand", do_alias }, { "cmd", do_alias },
X { "uncmd", do_alias }, { "from", do_from },
X { "un_hdr", do_alias }, { "my_hdr", do_alias },
X { "fkey", do_alias }, { "unfkey", do_alias },
X { "set", set }, { "unset", set },
X { "ignore", set }, { "unignore", set },
X { "version", do_version }, { "help", print_help },
X { "pick", do_pick }, { "sort", sort },
X { "next", readmsg }, { "previous", readmsg },
X { "type", readmsg }, { "print", readmsg },
X { "history", disp_hist }, { "top", readmsg },
X { "saveopts", save_opts }, { "source", source },
X { "headers", do_hdrs }, { "ls", ls },
X { "folder", folder }, { "update", folder },
X { "cd", cd }, { "pwd", cd },
X { "exit", mush_quit }, { "quit", mush_quit },
X { "write", save_msg }, { "save", save_msg },
X { "copy", save_msg }, { "folders", folders },
X { "merge", merge_folders },
X { "mark", mark_msg }, { "unmark", mark_msg },
#ifdef CURSES
X { "curses", curses_init }, { "bind", bind_it },
X { "unbind", bind_it }, { "bind-macro", bind_it },
X { "unbind-macro", bind_it },
#endif /* CURSES */
X { "map", bind_it }, { "unmap", bind_it },
X { "map!", bind_it }, { "unmap!", bind_it },
X { "preserve", preserve }, { "unpreserve", preserve },
X { "replyall", respond }, { "replysender", respond },
X { "delete", delete }, { "undelete", delete },
X { "mail", do_mail }, { "echo", do_echo },
X { "lpr", lpr }, { "alternates", alts },
X { "edit", edit_msg }, { "flags", msg_flags },
X { "pipe", pipe_msg }, { "eval", eval_cmd },
X { "undigest", do_undigest }, { "await", await },
X { NULL, mush_quit }
};
X
struct cmd ucb_cmds[] = {
X { "t", readmsg }, { "n", readmsg }, { "p", readmsg },
X { "+", readmsg }, { "-", readmsg }, { "P", readmsg },
X { "Print", readmsg }, { "T", readmsg }, { "Type", readmsg },
X { "x", mush_quit }, { "q", mush_quit }, { "xit", mush_quit },
X { ":a", do_hdrs }, { ":d", do_hdrs }, { ":r", do_hdrs },
X { ":o", do_hdrs }, { ":u", do_hdrs }, { ":n", do_hdrs },
X { ":s", do_hdrs }, { ":p", do_hdrs }, { ":m", do_hdrs },
X { "z", do_hdrs }, { "z-", do_hdrs }, { "z+", do_hdrs },
X { "h", do_hdrs }, { "H", do_hdrs },
X { "f", do_from }, { "m", do_mail }, { "alts", alts },
X { "d", delete }, { "dt", delete }, { "dp", delete },
X { "u", delete }, { "fo", folder },
X { "s", save_msg }, { "co", save_msg }, { "w", save_msg },
X { "pre", preserve }, { "unpre", preserve },
X { "R", respond }, { "r", respond },
X { "reply", respond }, { "respond", respond },
X { "v", edit_msg }, { "e", edit_msg },
X { NULL, mush_quit }
};
X
struct cmd hidden_cmds[] = {
X { "about", print_help },
X { "debug", toggle_debug }, { "open", nopenfiles },
X { "stty", my_stty },
X { "setenv", Setenv }, { "unsetenv", Unsetenv },
X { "printenv", Printenv }, { "Pipe", pipe_msg },
X { NULL, mush_quit }
};
X
toggle_debug(argc, argv)
int argc;
char **argv;
{
X if (argc < 2) /* no value -- toggle "debug" (off/on) */
X debug = !debug;
X else
X debug = atoi(*++argv);
X print("debugging value: %d\n", debug);
X return 0;
}
X
/* if + was specified, then print messages without headers.
X * n or \n (which will be NULL) will print next unread or undeleted message.
X */
readmsg(x, argv, list)
int x;
char **argv, list[];
{
X register char *p = x? *argv : NULL;
X register long flg = 0;
X extern FILE *ed_fp;
X
X if (x && *++argv && !strcmp(*argv, "-?"))
X return help(0, "readmsg", cmd_help);
X /* View a message as long as user isn't in the editor.
X * If ed_fp is not null, then we've got the
X * file open for typing. If it's NULL, then an editor is going.
X */
X if (ison(glob_flags, IS_GETTING) && !ed_fp) {
X print("Not while you're in the editor, you don't.\n");
X return -1;
X }
X if (!msg_cnt) {
X print("No messages.\n");
X return -1;
X }
X if (x)
X if (!strcmp(p, "top"))
X turnon(flg, M_TOP);
X else if (*p == '+') {
X turnon(flg, NO_PAGE);
X turnon(flg, NO_HEADER);
X } else if (isupper(*p))
X turnon(flg, NO_IGNORE);
X
X if (x && (x = get_msg_list(argv, list)) == -1)
X return -1;
X else if (x == 0) { /* no arguments were parsed (or given) */
X /* get_msg_list sets current msg on */
X if (isoff(glob_flags, IS_PIPE))
X unset_msg_bit(list, current_msg);
X /* most commands move to the "next" message. type and print don't */
X if ((!p || !*p || *p == 'n' || *p == '+') && current_msg < msg_cnt &&
X isoff(msg[current_msg].m_flags, UNREAD))
X current_msg++;
X if (p && (*p == '-' || !strcmp(p, "previous"))) {
X while (--current_msg >= 0 &&
X (ison(msg[current_msg].m_flags, DELETE) ||
X ison(msg[current_msg].m_flags, SAVED)))
X ;
X if (current_msg < 0) {
X print("No previous message.\n");
X current_msg = 0;
X return -1;
X }
X } else {
X /*
X * To be compatible with ucb-mail, find the next available unread
X * message. If at the end, only wrap around if "wrap" is set.
X */
X if (current_msg == msg_cnt && do_set(set_options, "wrap"))
X current_msg = 0;
X /* "type" or "print" prints the current only -- "next" goes on.. */
X if (!p || !*p || *p == 'n')
X while (current_msg < msg_cnt &&
X (ison(msg[current_msg].m_flags, DELETE) ||
X ison(msg[current_msg].m_flags, SAVED)))
X current_msg++;
X if (current_msg >= msg_cnt) {
X print("No more messages.\n");
X current_msg = msg_cnt - 1;
X return -1;
X }
X }
X if (isoff(glob_flags, IS_PIPE))
X set_msg_bit(list, current_msg);
X }
X current_msg = 0;
X for (x = 0; x < msg_cnt; x++)
X if (msg_bit(list, x)) {
X current_msg = x;
#ifdef SUNTOOL
X if (istool > 1) {
X read_mail(NO_ITEM, 0, NO_EVENT);
X return 0;
X }
#endif /* SUNTOOL */
X display_msg(x, flg);
X }
X return 0;
}
X
preserve(n, argv, list)
int n; /* no use for argc, so use space for a local variable */
char **argv, list[];
{
X register int unpre;
X
X unpre = !strncmp(*argv, "un", 2);
X if (*++argv && !strcmp(*argv, "-?"))
X return help(0, "preserve", cmd_help);
X if (get_msg_list(argv, list) == -1)
X return -1;
X for (n = 0; n < msg_cnt; n++)
X if (msg_bit(list, n))
X if (unpre) {
X if (ison(msg[n].m_flags, PRESERVE)) {
X turnoff(msg[n].m_flags, PRESERVE);
X turnon(glob_flags, DO_UPDATE);
X }
X } else {
X if (isoff(msg[n].m_flags, PRESERVE)) {
X turnon(msg[n].m_flags, PRESERVE);
X turnon(glob_flags, DO_UPDATE);
X }
X }
X if (istool)
X (void) do_hdrs(0, DUBL_NULL, NULL);
X return 0;
}
X
lpr(n, argv, list)
int n; /* no use for argc, so use its address space for a variable */
char **argv, list[];
{
X register FILE *pp;
X register long flags = 0;
X char print_cmd[128], *printer, c, *cmd;
X int total = 0;
X SIGRET (*oldint)(), (*oldquit)();
X
#ifdef PRINTER_OPT
X char *opt = PRINTER_OPT;
#else
X char opt[2];
#ifdef SYSV
X opt[0] = 'd';
#else
X opt[0] = 'P';
#endif /* SYSV */
X opt[1] = 0;
#endif /* PRINTER_OPT */
X
X if (!chk_option("alwaysignore", "printer"))
X turnon(flags, NO_IGNORE);
#ifdef MSG_SEPARATOR
X turnon(flags, NO_SEPARATOR);
#endif /* MMDF */
X if (!(printer = do_set(set_options, "printer")) || !*printer)
X printer = DEF_PRINTER;
X while (argv && *++argv && **argv == '-') {
X n = 1;
X while (c = argv[0][n++])
X switch(c) {
X case 'n': turnon(flags, NO_HEADER);
X when 'h': turnoff(flags, NO_IGNORE);
X when 'P': case 'd':
#ifndef PRINTER_OPT
X opt[0] = argv[0][n-1];
#endif /* PRINTER_OPT */
X if (!argv[0][n] && !(n = 0, *++argv)) {
X print("specify printer!\n");
X return -1;
X }
X printer = argv[0] + n;
X n += strlen(printer);
X otherwise: return help(0, "lpr", cmd_help);
X }
X }
X if (get_msg_list(argv, list) == -1)
X return -1;
X
X if (cmd = do_set(set_options, "print_cmd"))
X (void) strcpy(print_cmd, cmd);
X else
X (void) sprintf(print_cmd, "%s %s%s", LPR, opt, printer);
X Debug("print command: %s\n", print_cmd);
X if (!(pp = popen(print_cmd, "w"))) {
X error("cannot print");
X return -1;
X }
X on_intr();
X for (n = 0; isoff(glob_flags, WAS_INTR) && n < msg_cnt; n++) {
X if (msg_bit(list, n)) {
X if (total++)
X (void) fputc('\f', pp); /* send a formfeed for multiple copies */
X print("printing message %d...", n+1);
X print_more("(%d lines)\n", copy_msg(n, pp, (u_long) flags, NULL));
X turnon(msg[n].m_flags, PRINTED|DO_UPDATE);
X turnon(glob_flags, DO_UPDATE);
X }
X }
X off_intr();
X (void) pclose(pp);
X print_more("%d message%s printed ", total, (total==1)? "": "s");
X if (cmd)
X print_more("through \"%s\".\n", cmd);
X else
X print_more("at \"%s\".\n", printer);
X return 0;
}
X
/* save [msg_list] [file] */
save_msg(n, argv, list) /* argc isn't used, so use space for variable 'n' */
int n;
char **argv, list[];
{
X register FILE *mail_fp = NULL_FILE;
X register char *file = NULL, *mode, firstchar = **argv, *tmp = ".";
X int msg_number, force = 0, by_subj = 0, by_author = 0;
X char buf[MAXPATHLEN];
X long flg = 0;
X
X while (*++argv)
X if (*argv[0] != '-')
X break;
X else
X switch (argv[0][1]) {
X case 'S' :
X by_subj = 2;
X when 's' :
X by_subj = 1;
X when 'A' :
X by_author = 2;
X when 'a' :
X by_author = 1;
X when 'f' :
X force = 1;
X otherwise :
X return help(0, "save", cmd_help);
X }
X if (!force && (force = (*argv && !strcmp(*argv, "!"))))
X argv++;
X if ((n = get_msg_list(argv, list)) == -1)
X return -1;
X argv += n;
X if (*argv && *(file = *argv) == '\\')
X file++;
X else if (!file && !by_subj && !by_author) {
X /* if no filename specified, save in ~/mbox */
X if (firstchar == 'w') {
X /* mbox should have headers. If he really wants it, specify it */
X print("Must specify file name for 'w'\n");
X return -1;
X }
X if (!(file = do_set(set_options, "mbox")) || !*file)
X file = DEF_MBOX;
X }
X n = 1; /* tell getpath to ignore no such file or directory */
X if (file)
X tmp = getpath(file, &n);
X if (n < 0) {
X print("%s: %s\n", file, tmp);
X return -1;
X } else if (n && !by_subj && !by_author) {
X print("%s is a directory\n", file);
X return -1;
X }
X file = tmp;
X if (force || Access(file, F_OK))
X mode = "w", force = 0;
X else
X mode = "a";
X if (firstchar != 'w' && *mode == 'a' && !by_author && !by_subj &&
X !test_folder(file, "not a folder, save anyway?"))
X return 0;
X /*
X * open the file for writing (appending) unless we're saving by subject
X * or author name in which case we'll determine the filename later
X */
X if (!by_author && !by_subj && !(mail_fp = lock_fopen(file, mode))) {
X error("cannot save in \"%s\"", file);
X return -1;
X }
X
#ifdef SUNTOOL
X if (istool)
X timeout_cursors(TRUE);
#endif /* SUNTOOL */
X if (!chk_option("alwaysignore", "save"))
X turnon(flg, NO_IGNORE); /* presently overridden by UPDATE_STATUS */
X if (firstchar == 'w') {
X turnon(flg, NO_HEADER);
#ifdef MMDF
X turnon(flg, NO_SEPARATOR);
#endif /* MMDF */
X } else
X turnon(flg, UPDATE_STATUS);
X
X for (n = msg_number = 0; msg_number < msg_cnt; msg_number++)
X if (msg_bit(list, msg_number)) {
X if ((by_author || by_subj) && !mail_fp) {
X char buf2[256], addr[256];
X register char *p, *p2;
X if (by_subj) {
X if (p = header_field(msg_number, "subject")) {
X /* convert spaces and non-alpha-numerics to '_' */
X if (!lcase_strncmp(p, "re:", 3)) {
X p += 3;
X skipspaces(0);
X }
X for (p2 = p; *p2; p2++)
X if (!isalnum(*p2) && !index(".,@#$%-+=", *p2))
X *p2 = '_';
X } else
X p = "mbox";
X } else {
X (void) reply_to(msg_number, FALSE, buf2);
X (void) get_name_n_addr(buf2, NULL, addr);
X if (p = rindex(addr, '!'))
X p++;
X else
X p = addr;
X if (p2 = any(p, "@%"))
X *p2 = 0;
X }
X if (!p || !*p)
X p = "tmp";
X (void) sprintf(buf, "%s/%s", file, p);
X if (force || Access(buf, F_OK))
X mode = "w";
X else
X mode = "a";
X if (firstchar != 'w' && *mode == 'a' &&
X !test_folder(buf, "not a folder, save anyway?")) {
X if (by_author == 2 || by_subj == 2)
X break;
X continue;
X }
X if (!(mail_fp = lock_fopen(buf, mode))) {
X error("cannot save in \"%s\"", buf);
X if (by_author == 2 || by_subj == 2)
X break;
X continue;
X }
X }
X print("%sing msg %d ... ",
X (firstchar == 's')? "Sav" : "Writ", msg_number+1);
X print_more("(%d lines)",
X copy_msg(msg_number, mail_fp, (u_long) flg, NULL));
X if (by_author == 1 || by_subj == 1) {
X print_more(" in \"%s\"", buf);
X (void) close_lock(buf, mail_fp), mail_fp = NULL_FILE;
X }
X print_more("\n");
X n++;
X if (isoff(msg[msg_number].m_flags, SAVED) && firstchar != 'c') {
X turnon(glob_flags, DO_UPDATE);
X turnon(msg[msg_number].m_flags, SAVED|DO_UPDATE);
X }
X }
X if (mail_fp) {
X (void) close_lock(file, mail_fp);
X if (!file)
X file = buf;
X print_more("%s %d msg%s to %s\n",
X (*mode == 'a')? "Appended" : "Saved", n, (n != 1)? "s": "", file);
X }
#ifdef SUNTOOL
X if (istool) {
X extern Panel_item folder_item, save_item;
X timeout_cursors(FALSE);
X if (firstchar != 'c' && n > 0)
X (void) do_hdrs(0, DUBL_NULL, NULL);
X if (*mode == 'w' && n > 0) {
#ifndef NO_WALK_MENUS
X create_folder_menus();
#else /* NO_WALK_MENUS */
X add_folder_to_menu(folder_item, 3);
X add_folder_to_menu(save_item, 1);
#endif /* NO_WALK_MENUS */
X }
X }
#endif /* SUNTOOL */
X return 0;
}
X
respond(n, argv, list)
int n; /* no use for argc, so use its address space for a variable */
char **argv, *list;
{
X register char *cmd = *argv;
X char list1[MAXMSGS_BITS];
X int cur_msg = current_msg, save_cnt = msg_cnt;
X
X if (*++argv && !strcmp(*argv, "-?"))
X return help(0, "respond", cmd_help);
X if ((n = get_msg_list(argv, list)) == -1)
X return -1;
X
X /* make into our own list so ~: commands don't overwrite this list */
X bitput(list, list1, MAXMSGS, =);
X
X /* back up one arg to replace "cmd" in the new argv[0] */
X argv += (n-1);
X if (!strcmp(cmd, "replyall"))
X Upper(*cmd);
X if (n > 0)
X strdup(argv[0], cmd);
X
X /* make sure the *current* message is the one being replied to */
X for (current_msg = -1, n = 0; n < msg_cnt && current_msg == -1; n++)
X if (msg_bit(list1, n) && current_msg == -1)
X current_msg = n;
X if (current_msg == -1) { /* "reply -" can cause this to happen */
X current_msg = cur_msg;
X return -1;
X }
X if (do_mail(1 /* ignored */, argv, list) == -1)
X return -1;
X /* New mail may have arrived during do_mail(), which will change
X * the msg_cnt. Use the old count when examining the list of bits
X * to set the replied flag, or the wrong messages can be marked.
X */
X for (n = 0; n < save_cnt; n++)
X if (msg_bit(list1, n)) {
X /* set_isread(n); */
X set_replied(n); /* only if mail got delivered */
X }
X if (istool)
X (void) do_hdrs(0, DUBL_NULL, NULL);
X /* copy the specified list back into msg_list */
X bitput(list1, list, MAXMSGS, =);
X return 0;
}
X
/* cd to a particular directory specified by "p" */
cd(x, argv) /* argc, unused -- use space for a non-register variable */
int x;
char **argv;
{
X char *cwd, buf[MAXPATHLEN];
X register char *path, *p = argv[1], *cdpath = NULL, *p2;
X int err = 0;
X
X if (argv && argv[1] && !strcmp(argv[1], "-?"))
X return help(0, argv[0], cmd_help);
X
X if (!strcmp(*argv, "pwd")) {
X set_cwd(); /* reset in case some dummy changed $cwd */
X if ((p = do_set(set_options, "cwd")) && *p) {
X print("%s\n", p);
X return 0;
X }
X return -1;
X }
X if (!p || !*p) /* if no args, pwd = ".", cd = ~ */
X p = (**argv == 'p')? "." : "~";
X /* if a full path was not specified, loop through cdpath */
X if (**argv != 'p' && *p != '/' && *p != '~' && *p != '+')
X cdpath = do_set(set_options, "cdpath");
X (void) strcpy(buf, p);
X do {
X err = x = 0;
X path = getpath(buf, &x);
X if (x != 1 || chdir(path) == -1) {
X err = errno;
X if (cdpath) {
X char c;
X if (p2 = any(cdpath, " \t:"))
X c = *p2, *p2 = 0;
X (void) sprintf(buf, "%s/%s", cdpath, p);
X if (cdpath = p2) /* assign and compare to NULL */
X *p2 = c;
X while (cdpath && (isspace(*cdpath) || *cdpath == ':'))
X cdpath++;
X }
X }
X } while (err && cdpath && *cdpath);
X if (err)
X error(p);
X set_cwd();
X if ((istool || iscurses || err) && (cwd = do_set(set_options, "cwd"))) {
X if (err)
X turnon(glob_flags, CONT_PRNT);
X if (iscurses || istool || ison(glob_flags, WARNING))
X print("Working dir: %s\n", cwd);
X }
X return 0;
}
X
mush_quit(argc, argv)
int argc;
char **argv;
{
X u_long updated = ison(glob_flags, DO_UPDATE);
X
X if (argc > 1) {
X if (!strcmp(argv[1], "-?"))
X return help(0, "quit", cmd_help);
X else {
X print("%s: too many arguments\n", argv[0]);
X return -1;
X }
X }
X if ((!argc || (*argv && **argv == 'q')) && !copyback("Really Quit? ",TRUE))
X return -1;
#ifdef CURSES
X if (iscurses) {
X /* we may already be on the bottom line; some cases won't be */
X move(LINES-1, 0), refresh();
X if (updated)
X putchar('\n');
X }
#endif /* CURSES */
X cleanup(0);
#ifdef lint
X return 0;
#endif /* lint */
}
X
delete(argc, argv, list)
int argc;
char **argv, list[];
{
X register int prnt_next, undel = argc && **argv == 'u';
X int old_msg = current_msg;
X
X prnt_next = (argv && (!strcmp(*argv, "dt") || !strcmp(*argv, "dp")));
X
X if (argc && *++argv && !strcmp(*argv, "-?"))
X return help(0, "delete", cmd_help);
X
X if (ison(glob_flags, READ_ONLY)) {
X print("Folder is read-only\n");
X return -1;
X }
X
X if (get_msg_list(argv, list) == -1)
X return -1;
X for (argc = 0; argc < msg_cnt; argc++)
X if (msg_bit(list, argc))
X if (undel)
X turnoff(msg[argc].m_flags, DELETE);
X else
X turnon(msg[argc].m_flags, DELETE|DO_UPDATE);
X
X /* only if current_msg has been affected && not in curses mode */
X if (prnt_next == 0 && !iscurses && msg_bit(list, current_msg))
X prnt_next = !!do_set(set_options, "autoprint"); /* change to boolean */
X
X turnon(glob_flags, DO_UPDATE);
X
X /* goto next available message if current was just deleted.
X * If there are no more messages, turnoff prnt_next.
X */
X if (!iscurses && !undel && msg_bit(list, current_msg))
X (void) next_msg();
X else
X prnt_next = 0;
X
X if (prnt_next && !undel && !iscurses && isoff(glob_flags, DO_PIPE))
X if (old_msg != current_msg && isoff(msg[current_msg].m_flags, DELETE))
X display_msg(current_msg, (long)0);
X else {
X if (ison(msg[current_msg].m_flags, DELETE))
X print("No more messages.\n");
X current_msg = old_msg;
X }
#ifdef SUNTOOL
X if (istool && isoff(glob_flags, IS_PIPE)) {
X /* If deleted messages are to be shown and the current message
X * has moved off the screen, or if all messages are deleted,
X * redraw the whole display.
X * Otherwise, redraw the display starting at the current
X * topmost message, to bring the new current message on.
X */
X if (current_msg != old_msg && do_set(set_options, "show_deleted") ||
X n_array[0] > msg_cnt)
X (void) do_hdrs(0, DUBL_NULL, NULL);
X else {
X char *av[3], buf[8];
X /* do_hdrs(0, ...) repositions the display, so pass an arg */
X av[0] = "h";
X av[1] = sprintf(buf, "%d", n_array[0] + 1);
X av[2] = NULL;
X (void) do_hdrs(2, av, NULL);
X }
X }
#endif /* SUNTOOL */
X return 0;
}
X
/*
X * historically from the "from" command in ucb-mail, this just prints
X * the composed header of the messages set in list or in pipe.
X */
do_from(n, argv, list)
int n;
char **argv, list[];
{
X int inc_cur_msg = 0;
X
X if (argv && *++argv && !strcmp(*argv, "-?"))
X return help(0, "from", cmd_help);
X if (argv && *argv && (!strcmp(*argv, "+") || !strcmp(*argv, "-")))
X if (!strcmp(*argv, "+")) {
X if (!*++argv && current_msg < msg_cnt-1)
X current_msg++;
X inc_cur_msg = 1;
X } else if (!strcmp(*argv, "-")) {
X if (!*++argv && current_msg > 0)
X current_msg--;
X inc_cur_msg = -1;
X }
X if ((n = get_msg_list(argv, list)) == -1)
X return -1;
X else if (argv && argv[n]) {
X u_long save_flags = glob_flags;
X char *newargv[6], buf[BUFSIZ];
X (void) argv_to_string(buf, &argv[n]);
X newargv[0] = "pick";
X if (n == 0) {
X newargv[++n] = "-r";
X newargv[++n] = "*";
X turnoff(glob_flags, IS_PIPE);
X } else {
X n = 0;
X turnon(glob_flags, IS_PIPE);
X }
X newargv[++n] = "-f";
X newargv[++n] = buf;
X newargv[++n] = NULL;
X Debug("calling: "), print_argv(newargv);
X turnon(glob_flags, DO_PIPE);
X (void) do_pick(n, newargv, list);
X glob_flags = save_flags;
X }
X for (n = 0; n < msg_cnt; n++)
X if (msg_bit(list, n)) {
X wprint("%s\n", compose_hdr(n));
X /* if -/+ given, set current message pointer to this message */
X if (inc_cur_msg) {
X current_msg = n;
X /* if - was given, then set to first listed message.
X * otherwise, + means last listed message -- let it go...
X */
X if (inc_cur_msg < 0)
X inc_cur_msg = 0;
X }
X }
X return 0;
}
X
static
sorter(cmd1, cmd2)
register struct cmd *cmd1, *cmd2;
{
X return strcmp(cmd1->command, cmd2->command);
}
X
question_mark(x, argv)
int x;
char **argv;
{
X int n = 0, N = sizeof cmds / sizeof (struct cmd);
X char *Cmds[sizeof cmds/sizeof(struct cmd)], *p, buf[30];
X
X if (!*++argv) {
X if (N % 5)
X N = N / 5 + 1;
X else
X N = N / 5;
X
X qsort((char *)cmds, sizeof(cmds)/sizeof(struct cmd)-1,
X sizeof(struct cmd), sorter);
X
X for (x = 0; x < N * 5; x++) {
X if (!(x % 5))
X if (!(p = Cmds[n++] = malloc(80))) {
X error("malloc in question_mark()");
X free_vec(Cmds);
X return -1;
X }
X if (x%5*N+n < sizeof cmds / sizeof (struct cmd))
X p += strlen(sprintf(p, "%-14.14s ", cmds[x%5*N+n-1].command));
X }
X Cmds[n++] = savestr("Type: `command -?' for help with most commands.");
X Cmds[n] = NULL;
X (void) help(0, (char *) Cmds, NULL);
X free_vec(Cmds);
X } else if (!strcmp(*argv, "-?"))
X return help(0, "?", cmd_help);
X else {
X for (x = 0; cmds[x].command; x++)
X if (!strcmp(*argv, cmds[x].command))
X return cmd_line(sprintf(buf, "\\%s -?", *argv), msg_list);
X print("Unknown command: %s\n", *argv);
X }
X return 0 - in_pipe();
}
SHAR_EOF
chmod 0644 commands.c ||
echo 'restore of commands.c failed'
Wc_c="`wc -c < 'commands.c'`"
test 22758 -eq "$Wc_c" ||
echo 'commands.c: original size 22758, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= compose.icon ==============
if test -f 'compose.icon' -a X"$1" != X"-c"; then
echo 'x - skipping compose.icon (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting compose.icon (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'compose.icon' &&
/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
X */
X 0xFFFF,0xFFFF,0xFFFF,0xF89C,0xFFFF,0xFFFF,0xFFFF,0xF8A2,
X 0xC000,0x0000,0x0000,0x1A61,0xC000,0x0000,0x0000,0x1A91,
X 0xC000,0x0000,0x0000,0x1989,0xC000,0x0000,0x0000,0x1A46,
X 0xC000,0x0000,0x0000,0x1E26,0xC000,0x0000,0x0000,0x1B1A,
X 0xC003,0x0FDE,0x0000,0x1498,0xC003,0x8FFF,0x0000,0x2968,
X 0xC000,0x0000,0x0000,0x5262,0xC000,0x0000,0x0000,0xA4A2,
X 0xC000,0x0000,0x0001,0x4988,0xC000,0x0000,0x0002,0x9288,
X 0xC000,0x0000,0x0005,0x2622,0xC0E6,0xEFCF,0x79FA,0x4A22,
X 0xC0F7,0xEFEF,0xFDF4,0x9888,0xC000,0x0000,0x0029,0x3888,
X 0xC000,0x0000,0x0052,0x5A22,0xC7B9,0xEF9D,0x9DA4,0x9A22,
X 0xC7FD,0xFFDF,0xDF49,0x1888,0xC000,0x0000,0x0292,0x1888,
X 0xC000,0x0000,0x0524,0x1A22,0xC73F,0x3CEC,0xFA48,0x1A22,
X 0xC7BF,0xBEFE,0xF490,0x1888,0xC000,0x0000,0x2920,0x1888,
X 0xC000,0x0000,0x5240,0x1A22,0xC6E7,0x67E7,0xA4E0,0x1A22,
X 0xC7F7,0xF7F7,0x49F0,0x1888,0xC000,0x0002,0x9200,0x1888,
X 0xC000,0x0005,0x2400,0x1A22,0xC79D,0x99EA,0x4F00,0x1A22,
X 0xC7DF,0xDDF4,0x9F80,0x1888,0xC000,0x0029,0x2000,0x1888,
X 0xC000,0x0052,0x4000,0x1A22,0xC738,0x00E4,0x8000,0x1A22,
X 0xC7BC,0x0129,0x0000,0x1888,0xC000,0x0112,0x0000,0x1888,
X 0xC000,0x020C,0x0000,0x1A22,0xC000,0x0218,0x0000,0x1A22,
X 0xC000,0x0660,0x0000,0x1888,0xC000,0x0780,0x0000,0x1888,
X 0xC000,0x0E00,0x0000,0x1A22,0xC000,0x0800,0x0000,0x1A22,
X 0xC000,0x0000,0x0000,0x1888,0xC000,0x0000,0x0000,0x1888,
X 0xC000,0x0000,0x0000,0x1A22,0xC000,0x0000,0x0000,0x1A22,
X 0xC000,0x0000,0x2000,0x1888,0xC000,0x0000,0x2000,0x1888,
X 0xC006,0x888E,0x2C00,0x1A22,0xC005,0x4891,0x3200,0x1A22,
X 0xC005,0x4890,0x2200,0x1888,0xC005,0x488E,0x2200,0x1888,
X 0xC005,0x4881,0x2200,0x1A22,0xC005,0x4991,0x2200,0x1A22,
X 0xC005,0x468E,0x2200,0x1888,0xC000,0x0000,0x0000,0x1888,
X 0xC000,0x0000,0x0000,0x1A22,0xC000,0x0000,0x0000,0x1A22,
X 0xC000,0x0000,0x0000,0x1888,0xC000,0x0000,0x0000,0x1888,
X 0xFFFF,0xFFFF,0xFFFF,0xFA22,0xFFFF,0xFFFF,0xFFFF,0xFA22
SHAR_EOF
chmod 0644 compose.icon ||
echo 'restore of compose.icon failed'
Wc_c="`wc -c < 'compose.icon'`"
test 1933 -eq "$Wc_c" ||
echo 'compose.icon: original size 1933, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= config.h-dist ==============
if test -f 'config.h-dist' -a X"$1" != X"-c"; then
echo 'x - skipping config.h-dist (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting config.h-dist (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'config.h-dist' &&
/* config.h 1.1 (c) copyright 1986 (Dan Heller) */
X
/* Default names and locations for files */
#define MAILRC ".mushrc"
#define ALTERNATE_RC ".mailrc"
#define DEFAULT_RC "/usr/lib/Mushrc"
#define ALT_DEF_RC "/usr/lib/Mail.rc"
#define SIGNATURE ".signature"
#define FORTUNE "/usr/games/fortune"
#define COMMAND_HELP "/usr/lib/cmd_help"
#ifdef SUNTOOL
# define TOOL_HELP "/usr/lib/tool_help"
#endif /* SUNTOOL */
#define ALTERNATE_HOME "/tmp" /* Path must be read/write to EVERYONE */
#define EDFILE ".edXXXXXX" /* file/pathname added to user's "home" */
X
#define LS_COMMAND "ls"
#define LPR "lpr"
#define DEF_PRINTER "lp"
/* If your lpr command understands only -P or -d (or some other flag) then
X * define PRINTER_OPT to the appropriate value. If you want to be able to
X * use either one, don't define this at all. The defaults (when neither
X * -P nor -d is used on the mush "lpr" command line) are as noted here.
X * If your lpr requires that the option and the printer name be separate
X * arguments, include a trailing space in this definition.
X */
#ifdef SYSV
#define PRINTER_OPT "-d"
#endif /* SYSV */
#ifdef BSD
#define PRINTER_OPT "-P"
#endif /* BSD */
X
/* default settings for some variable strings */
#define DEF_PROMPT "Msg %m of %t: "
#define DEF_PAGER "more" /* set to "internal" to use internal pager */
#define DEF_SHELL "csh"
#define DEF_EDITOR "vi"
#define DEF_FOLDER "~/Mail" /* default Mail folder */
#define DEF_MBOX "~/mbox" /* default mbox */
#define DEF_INDENT_STR "> " /* indent included mail */
#define DEF_ESCAPE "~"
#define DEF_HDR_FMT "%25f %7d (%l/%c) \"%s\"" /* default hdr_format */
#define DEF_CURSES_HELP \
X "display save mail reply next-msg back-msg screen-next screen-back"
X
/* Headers that will NOT be included when forwarding mail */
#define IGNORE_ON_FWD "status,priority,return-receipt-to"
X
#define MAXMSGS 1000 /* Maximum number of messages we can read */
#define HDRSIZ (2*BUFSIZ) /* This should not be < BUFSIZ! */
X
/*
X * Define INTERNAL_MALLOC and recompile if you have trouble with mush
X * core-dumping due to malloc/free errors. Also, if you run a System 5
X * variant, you might notice a performance improvement if you define this
X * variable. It uses the malloc distributed by Larry Wall for perl v2.
X */
/* #define INTERNAL_MALLOC /**/
X
/*
X * Define TIMEZONE if your system has neither the SysV external variable
X * tzname nor the BSD timezone() function. The example below is for
X * Gould BSD4.3 systems; others should define it as a string, e.g. "PST"
X * If TIMEZONE is defined, DAYLITETZ can also be defined, e.g. "PDT"
X *
X * Define USA if you are using US/NorthAmerican time zone abbreviations.
X * If USA is not defined, dates in outgoing mail will include timezones
X * specified as offsets from GMT, e.g. Pacific Standard Time is -0800.
X */
/* #define TIMEZONE T->tm_zone /**/
/* #define USA /**/
X
/* mail delivery system macros and defines... */
X
/*
X * If you are using MMDF, define MMDF here.
X */
/* #define MMDF /**/
#ifdef MMDF
/*
X * If MMDF delivers mail the user's home directory, define HOMEMAIL.
X * Also check the definition of the delivery file name MAILFILE, below.
X */
/* #define HOMEMAIL /**/
#define MAIL_DELIVERY "exec /usr/mmdf/bin/submit -mlnr"
#define VERBOSE_ARG "Ww"
#define MTA_EXIT 9 /* exit status for successful submit */
#else /* MMDF */
/*
X * If you are not using MMDF, check these definitions.
X */
#define MAIL_DELIVERY "/usr/lib/sendmail -i" /* "-i" works like "-oi" */
#define VERBOSE_ARG "-v" /* undef if none exists */
#define METOO_ARG "-m" /* man sendmail for more info. */
#define MTA_EXIT 0 /* exit status for successful mail delivery */
#endif /* MMDF */
X
/* If your mail transfer agent uses something *besides* "From " to separate
X * adjacent messages in a folder, define MSG_SEPARATOR to be this string.
X * If that string is 4 ^A's, then the string would be "\001\001\001\001".
X * With the exception of MMDF, below, you should OMIT a trailing newline
X * from the setting of MSG_SEPARATOR.
X * If you don't know what any of this means, leave it alone.
X */
/* #define MSG_SEPARATOR "From " /**/
#ifdef MMDF
/*
X * These values should be identical (respectively) to the contents of
X * delim1 and delim2 in MMDFSRC/conf/yoursite/conf.c (sans newline).
X */
#define MSG_SEPARATOR "\001\001\001\001\n"
#define END_MSG_SEP "\001\001\001\001\n"
/*
X * You only need to define LCKDFLDIR if you have MMDF configured to use the
X * locking routines in lib/util/lk_lock.c (ie., link(2)-based locking).
X * Most of you WILL NOT need this, since you probably use one of the more
X * sophisticated locking modules provided with MMDF. Remember to alter the
X * Makefile so as to access the MMDF library at the link step.
X */
/* #define LCKDFLDIR "/usr/spool/mmdf/lockfiles" /* (for example) */
#else /* !MMDF */
#ifdef M_XENIX
#define DOT_LOCK /* DOT_LOCK should be used for SCO Xenix */
#endif /* M_XENIX */
#endif /* MMDF */
X
/* If your mailer does not understand commas between addresses, you should
X * define NO_COMMAS. This includes pre-3.0 smail and default MTAs used on
X * xenix, and sys-v systems.
X * This does NOT apply to MMDF or sendmail, in most cases.
X */
#ifdef SUN_4_1 /* SunOS 4.1 has warped sendmail.cf */
#define NO_COMMAS /**/
#endif /* SUN_4_1
X
/*
X * Most RFC822 compliant mailers (sendmail) will add the headers From:
X * and Date: on outgoing mail. If the user or UA sends these headers,
X * most MTAs will not append them automatically. However, there are
X * certain MTAs which will not allow this -- these "picky mailers" will
X * precede such headers with a '>' and make the headers very ugly and
X * somewhat redundant or contradictory. It is advisable to set this
X * *UNLESS* your MTA is not RFC822 compiant -- therefore you should NOT
X * set this (xenix, sys-v).
X */
/* #define PICKY_MAILER /**/
X
/* If your system supports the vprintf() functions, True for sys-v and
X * later sun versions (3.0+ ?). Typically not true for BSD systems, but
X * that will probably change in the future.
X */
#if defined(SYSV) || defined(sun)
#define VPRINTF
#endif /* SYSV || sun */
X
/* If your system uses the getwd() system call (as opposed to getcwd()),
X * and your system is not a BSD system (e.g. MIPS), define GETWD below.
X */
/* #define GETWD /**/
X
#ifdef HOMEMAIL
#define MAILFILE "Mailbox" /* or whatever */
#else /* HOMEMAIL */
#define MAILDIR "/usr/spool/mail"
#endif /* HOMEMAIL */
SHAR_EOF
chmod 0644 config.h-dist ||
echo 'restore of config.h-dist failed'
Wc_c="`wc -c < 'config.h-dist'`"
test 6407 -eq "$Wc_c" ||
echo 'config.h-dist: original size 6407, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= curs_io.c ==============
if test -f 'curs_io.c' -a X"$1" != X"-c"; then
echo 'x - skipping curs_io.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting curs_io.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'curs_io.c' &&
/* @(#)curs_io.c (c) copyright 3/18/87 (Dan Heller) */
X
/* curs_io.c -- curses based I/O */
#include "mush.h"
#include "bindings.h"
#include "glob.h"
X
static backspace();
X
#if !defined(M_XENIX) || (defined(M_XENIX) && !defined(CURSES))
char *_unctrl[] = {
X "^@", "^A", "^B", "^C", "^D", "^E", "^F", "^G", "^H", "^I", "^J", "^K",
X "^L", "^M", "^N", "^O", "^P", "^Q", "^R", "^S", "^T", "^U", "^V", "^W",
X "^X", "^Y", "^Z", "^[", "^\\", "^]", "^~", "^_",
X " ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-",
X ".", "/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";",
X "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I",
X "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
X "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e",
X "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
X "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", "^?"
};
#endif /* !M_XENIX || (M_XENIX && !CURSES) */
X
char del_line; /* tty delete line character */
char del_word; /* tty delete word character */
char del_char; /* backspace */
char reprint_line; /* usually ^R */
char eofc; /* usually ^D */
char lit_next; /* usually ^V */
char complete; /* word completion, usually ESC */
char complist; /* completion listing, usually ^D */
X
tty_settings()
{
X savetty();
X
#ifdef SYSV
X eofc = _tty.c_cc[VEOF];
#else
#ifdef BSD
X if (ioctl(0, TIOCGETC, &tchars) != -1)
X eofc = tchars.t_eofc;
X else
#endif /* BSD */
X eofc = CTRL('D');
#endif /* SYSV */
X
X if (!isatty(0)) {
X del_line = CTRL('U');
X del_char = CTRL('H');
X } else {
X del_line = _tty.sg_kill;
X del_char = _tty.sg_erase;
X }
X
#ifdef TIOCGLTC
#ifndef AUX /* AUX defines TIOCGLTC but doesn't use it */
X if (ioctl(0, TIOCGLTC, <chars) != -1) {
X del_word = ltchars.t_werasc;
X reprint_line = ltchars.t_rprntc;
X lit_next = ltchars.t_lnextc;
X } else
#endif /* AUX */
#endif /* TIOCGLTC */
X {
X del_word = CTRL('W');
X reprint_line = CTRL('R');
X lit_next = CTRL('V');
X }
}
X
#ifdef Addch
#undef Addch
#endif /* Addch */
X
#ifndef CURSES
X
/* Make sure all ifs have matching elses! */
X
#define Addch(c) \
X if (ison(glob_flags, ECHO_FLAG)) \
X {;} \
X else \
X (void) fputc(c, stdout), (void) fflush(stdout)
X
#else
X
/* see end of Getstr */
#define Addch(c) \
X if (iscurses) \
X addch(c), refresh(); \
X else if (ison(glob_flags, ECHO_FLAG)) \
X {;} \
X else \
X (void) fputc(c, stdout), (void) fflush(stdout)
#endif /* CURSES */
X
/*
X * get a string of at most 'length' chars.
X * allow backspace-space-backspace, kill word and kill line
X * (options set by user in stty).
X * length is the max length this string can get. offset is from beginning
X * of string.
X * input of ^D returns -1; otherwise, return the number of chars in string.
X */
Getstr(String, length, offset)
char String[];
register int length;
{
X register int c, literal_next = FALSE, lit_bs = FALSE;
X struct cmd_map *curr_map;
X int count = offset, save_wc = wrapcolumn;
X
X (void) fflush(stdout); /* make sure everything is flushed before getting input */
X
X if (mac_hide) {
X curr_map = NULL_MAP;
X wrapcolumn = 0;
X } else if (ison(glob_flags, IS_GETTING))
X curr_map = bang_map;
X else if (iscurses)
X curr_map = NULL_MAP;
X else
X curr_map = line_map;
X
X while ((c = m_getchar()) != '\n' && c != '\r' && c != EOF &&
X isoff(glob_flags, WAS_INTR)) {
X /* echo isn't set, so whatever the character, enter it */
X if (ison(glob_flags, QUOTE_MACRO) || ison(glob_flags, ECHO_FLAG)) {
X if (count < length) {
X String[count++] = c;
X /* Note: Addch includes ECHO_FLAG test */
X if (iscntrl(c)) {
X Addch('^');
X Addch(_unctrl[c][1]);
X } else
X Addch(c);
X } else {
X print("\nWarning: string too long. Truncated at %d chars.",
X length);
X if (ison(glob_flags, QUOTE_MACRO)) {
X mac_flush();
X m_ungetc(reprint_line);
X continue;
X } else
X break;
X }
X }
X /* ^D as the first char on a line or two ^D's in a row is EOF */
X else if (c == eofc && !count)
X break;
X else if (c == '\\' && count < length) {
X literal_next = TRUE, lit_bs = FALSE;
X Addch(String[count++] = '\\');
X } else if (c == lit_next && count < length) {
X literal_next = lit_bs = TRUE;
X String[count++] = '\\';
X if (!in_macro()) {
X /* if (iscntrl(c)) */
X Addch('^');
X /* Addch(_unctrl[c][1]); */
X }
X } else if (literal_next) {
SHAR_EOF
true || echo 'restore of curs_io.c failed'
fi
echo 'End of part 5'
echo 'File curs_io.c is continued in part 6'
echo 6 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list