argv@zipcode.com (Dan Heller) (04/21/91)
Submitted-by: Dan Heller <argv@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@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@uunet.uu.net.