home *** CD-ROM | disk | FTP | other *** search
- From: argv@zipcode.com (Dan Heller)
- Newsgroups: comp.sources.misc
- Subject: v18i069: mush - Mail User's Shell, Part12/22
- Message-ID: <1991Apr22.000412.18858@sparky.IMD.Sterling.COM>
- Date: 22 Apr 91 00:04:12 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: e46a1855 4e24d409 846c84c5 a349d102
-
- Submitted-by: Dan Heller <argv@zipcode.com>
- Posting-number: Volume 18, Issue 69
- Archive-name: mush/part12
- Supersedes: mush: Volume 12, Issue 28-47
-
- #!/bin/sh
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file mail.c continued
- #
- if test ! -r _shar_seq_.tmp; then
- echo 'Please unpack part 1 first!'
- exit 1
- fi
- (read Scheck
- if test "$Scheck" != 12; 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 mail.c'
- else
- echo 'x - continuing file mail.c'
- sed 's/^X//' << 'SHAR_EOF' >> 'mail.c' &&
- X case 'x':
- X /* don't save dead.letter -- simulate normal rm_edfile() call */
- X rm_edfile(0);
- X return -1;
- X /* break; (not specified for lint) */
- X default:
- X if (line[1] == *escape) {
- X (void) fputs(&line[1], ed_fp);
- X (void) fputc('\n', ed_fp);
- X (void) fflush(ed_fp);
- X return 1;
- X } else if (line[1] == '?') {
- X register int x;
- X (void) do_pager(NULL, TRUE); /* start pager */
- X for (x = 0; tilde_commands[x]; x++) {
- X if (ison(flags, EDIT_HDRS) && TC_EDIT(x))
- X continue;
- X (void) sprintf(buf, "%s%s\n", escape, tilde_commands[x]);
- X if (do_pager(buf, FALSE) == EOF)
- X break;
- X }
- X if (tilde_commands[x] == NULL) {
- X (void) sprintf(buf,
- X "%s%s\t\tBegin a line with a single %s\n",
- X escape, escape, escape);
- X (void) do_pager(buf, FALSE);
- X }
- X (void) do_pager(NULL, FALSE); /* end pager */
- X } else
- X print("`%c': unknown %c escape. Use %c? for help.\n",
- X line[1], *escape, *escape);
- X return 1;
- X }
- X if (ed_fp)
- X (void) fseek(ed_fp, 0L, 2);
- X if (!istool)
- X wprint("(continue editing letter)\n");
- X return 1;
- }
- X
- /*
- X * finish up the letter. ask for the cc line, if verify is set, ask to
- X * verify sending, continue editing, or to dump the whole idea.
- X * Then check for signature and fortune. Finally, pass it to send_it()
- X * to actually send it off.
- X * Return 0 on success, -1 on failure.
- X */
- static int
- finish_up_letter()
- {
- X register char *p;
- X int c;
- X char buf[MAXPATHLEN];
- X
- X /* forwarded mail has no additional personalized text */
- X if (ison(flags, FORWARD)) {
- X if (send_it() == -1) {
- X wprint("Message not sent!\n");
- X return -1;
- X }
- X turnoff(glob_flags, IS_GETTING);
- X return 0;
- X }
- X
- X /* REDIRECT should never be on here, but just in case */
- X if (isoff(glob_flags, REDIRECT)) {
- X if (!istool) {
- X if (isoff(flags, EDIT_HDRS) && do_set(set_options, "askcc")) {
- X if (p = set_header("Cc: ", Cc, 1))
- X (void) strcpy(Cc, p);
- X }
- X }
- X /* ~v on the Cc line asks for verification, first initialize p! */
- X p = NULL;
- X if (!strncmp(Cc, "~v", 2) ||
- X /* Flashy test for $verify either empty or set to "mail" */
- X glob(p = do_set(set_options, "verify"),
- X "{,{,*[ \\,]}mail{,[ \\,]*}}")) {
- X if (!p) /* so we don't Cc to ~v! */
- X *Cc = 0;
- X for (;;) {
- #ifdef SUNTOOL
- X if (istool)
- X c = (ask("Send Message?") == TRUE)? 's' : 'c';
- X else
- #endif /* SUNTOOL */
- X {
- X print("send, continue editing, discard [s,c,d]? ");
- X c = Getstr(buf, sizeof(buf), 0);
- X if (c < 0)
- X putchar('\n');
- X else if (!istool)
- X c = lower(*buf);
- X }
- X if (c == 'd') {
- X rm_edfile(-2);
- X return 0;
- X } else if (c == 'c') {
- X wprint("(continue editing letter)\n");
- X return -1;
- X } else if (c == 's')
- X break;
- X }
- X }
- X }
- X
- X if (send_it() == -1) {
- X if (isoff(flags, SEND_NOW))
- X wprint("(continue)\n");
- X return -1;
- X }
- X return 0;
- }
- X
- /*
- X * actually send the letter.
- X * 1. reset all the signals because of fork.
- X * 2. determine recipients (users, address, files, programs)
- X * 3. determine mailer, fork and return (if not verbose).
- X * 4. popen mailer, $record, and other files specified in step 1.
- X * 5. make the headers; this includes To: line, and user set headers, etc...
- X * 6. copy the letter right into the array of file pointers (step 1).
- X * 7. close the mailer and other files (step 1) and remove the edit-file.
- X * return -1 if mail wasn't sent. could be user error, could be the system.
- X * allow user to try again or to save message to file and abort message.
- X * return 0 if successful.
- X */
- static int
- send_it()
- {
- X register char *p, *b, *addr_list;
- #ifdef MAXFILES
- X register int size = MAXFILES - 1;
- X FILE *files[MAXFILES];
- X char *names[MAXFILES];
- #else
- X register int size = getdtablesize() - 1;
- X FILE *files[30]; /* 30 should be sufficiently large enough */
- X char *names[30];
- #endif /* MAXFILES */
- #if defined(VERBOSE_ARG)
- X SIGRET (*oldchld)();
- #endif /* VERBOSE_ARG */
- X int next_file = 1; /* reserve files[0] for the mail delivery program */
- X int log_file = -1; /* the index into the files array for mail logging */
- X char buf[3*HDRSIZ];
- X char *orig_to, *orig_cc, *orig_bcc; /* save originals to restore on error */
- X char expand = !do_set(set_options, "no_expand");
- X int fork_pid;
- X
- X names[0] = names[1] = NULL; /* for free_vec() */
- X /* If edit_hdrs, make sure the correct headers exist and are intact
- X * before bothering to continue.
- X */
- X if (ison(flags, EDIT_HDRS)) {
- X /* fool header_field into thinking that the file is the folder */
- X FILE *save_tmpf = tmpf;
- X long old_offset = msg[msg_cnt].m_offset;
- X
- X if (!ed_fp) {
- X wprint("No file for headers!\n");
- X return -1;
- X }
- X Debug("Getting headers from file ... ");
- X
- X tmpf = ed_fp;
- X msg[msg_cnt].m_offset = 0L;
- X if (p = header_field(msg_cnt, "to")) {
- X (void) strcpy(To, p);
- X Cc[0] = Bcc[0] = 0;
- X if (p = header_field(msg_cnt, "cc"))
- X (void) strcpy(Cc, p);
- X if (p = header_field(msg_cnt, "bcc"))
- X (void) strcpy(Bcc, p);
- X if (p = header_field(msg_cnt, "fcc"))
- X next_file += find_files(p, names+next_file, size-next_file, 1);
- X } else
- X *To = 0; /* Error caught below */
- X msg[msg_cnt].m_offset = old_offset;
- X tmpf = save_tmpf;
- X Debug("\n");
- X }
- X if (!*To) {
- X wprint("You must have a To: recipient to send mail.\n");
- X if (!istool) {
- X (void) signal(SIGINT, oldint);
- X (void) signal(SIGQUIT, oldquit);
- X (void) signal(SIGTERM, oldterm);
- X }
- X free_vec(&names[1]);
- X return -1;
- X }
- X
- X if (!(p = do_set(set_options, "sendmail")))
- X p = MAIL_DELIVERY;
- X
- #ifdef VERBOSE_ARG
- X /* Tool mode can't do verbosity -- no window for the MTA output */
- X if (!istool && (ison(flags, VERBOSE) || do_set(set_options, "verbose"))) {
- X turnon(flags, VERBOSE); /* prevent fork when "verbose" has changed */
- X oldchld = signal(SIGCHLD, SIG_DFL); /* let pclose() do the wait() */
- #ifdef MMDF
- X b = &buf[strlen(sprintf(buf, "%s%s", p, VERBOSE_ARG))];
- #else /* MMDF */
- X b = &buf[strlen(sprintf(buf, "%s %s", p, VERBOSE_ARG))];
- #endif /* MMDF */
- X } else
- #endif /* VERBOSE_ARG */
- X b = buf + Strcpy(buf, p);
- #ifdef METOO_ARG
- X if (!strcmp(p, MAIL_DELIVERY) && do_set(set_options, "metoo"))
- X b += strlen(sprintf(b, " %s", METOO_ARG));
- #endif /* METOO_ARG */
- X *b++ = ' ', *b = 0; /* strcat(b, " "); */
- X addr_list = b; /* save this position to check for addresses later */
- X
- X /* save original list. If alias expansion fails, replace address lists
- X * with what was originally typed so user can fix it. This isn't necessary
- X * if the lists are already in the file the user is editing (edit_hdrs).
- X */
- X if (isoff(flags, EDIT_HDRS))
- X orig_to = savestr(To);
- X /*
- X * Build the address lines to give to the mail transfer system. This
- X * address line cannot contain comment fields! First, expand aliases
- X * since they may contain comment fields within addresses. Copy this
- X * result back into the Buffer since this will go into the header ...
- X * Next, remove all comments so the buffer contains ONLY valid addresses.
- X * Next, strip off any filenames/programs which might occur in the list.
- X * Finally, add this information to the command line buffer (buf).
- X * Remove commas if necessary (see ifdefs). In the event of errors,
- X * force a dead letter by rm_edfile(-1).
- X */
- X if (!(p = alias_to_address(To))) {
- X print("address expansion failed for To: list.\n");
- X free_vec(&names[1]);
- X if (isoff(flags, EDIT_HDRS))
- X strcpy(To, orig_to), xfree(orig_to);
- X return -1;
- X } else {
- X next_file += find_files(p, names+next_file, size-next_file, 0);
- X if (expand)
- X (void) strcpy(To, p);
- X rm_cmts_in_addr(p);
- X skipspaces(0);
- X b += Strcpy(b, p);
- X }
- X if (isoff(flags, EDIT_HDRS))
- X orig_cc = savestr(Cc);
- X if (*Cc) {
- X if (!(p = alias_to_address(Cc))) {
- X wprint("address expansion failed for Cc: list.\n");
- X free_vec(&names[1]);
- X if (isoff(flags, EDIT_HDRS)) {
- X strcpy(To, orig_to), xfree(orig_to);
- X strcpy(Cc, orig_cc), xfree(orig_cc);
- X }
- X return -1;
- X } else {
- X next_file += find_files(p, names+next_file, size-next_file, 0);
- X if (expand)
- X (void) strcpy(Cc, p);
- X rm_cmts_in_addr(p);
- X skipspaces(0);
- X if (*p) {
- X *b++ = ',', *b++ = ' ';
- X b += Strcpy(b, p);
- X }
- X }
- X }
- X
- X /* expand Bcc addrs, but don't add to list yet. sign letter first */
- X if (isoff(flags, EDIT_HDRS))
- X orig_bcc = savestr(Bcc);
- X if (*Bcc) {
- X if (p = alias_to_address(Bcc))
- X p = strcpy(Bcc, p);
- X else {
- X wprint("address expansion failed for Bcc: list.\n");
- X free_vec(&names[1]);
- X /* rm_edfile(-1); */
- X if (isoff(flags, EDIT_HDRS)) {
- X strcpy(To, orig_to), xfree(orig_to);
- X strcpy(Cc, orig_cc), xfree(orig_cc);
- X strcpy(Bcc, orig_bcc), xfree(orig_bcc);
- X }
- X return -1;
- X }
- X } else
- X p = NULL;
- X
- X /* Sign the letter before adding the Bcc list since they aren't
- X * considered when adding a signature.
- X */
- X if (*addr_list && ison(flags, SIGN|DO_FORTUNE) &&
- X isoff(glob_flags, REDIRECT) && isoff(flags, FORWARD))
- X sign_letter(addr_list, flags, ed_fp);
- X
- X if (p) { /* p still points to expanded Bcc list */
- X next_file += find_files(p, names+next_file, size-next_file, 0);
- X rm_cmts_in_addr(p);
- X skipspaces(0);
- X if (*p) {
- X *b++ = ',', *b++ = ' ';
- X b += Strcpy(b, p);
- X }
- X }
- X if (!*addr_list && next_file == 1) {
- X wprint("There must be at least 1 legal recipient.\n");
- X if (isoff(flags, EDIT_HDRS)) {
- X strcpy(To, orig_to), xfree(orig_to);
- X strcpy(Cc, orig_cc), xfree(orig_cc);
- X strcpy(Bcc, orig_bcc), xfree(orig_bcc);
- X }
- X return -1;
- X }
- X
- #ifdef NO_COMMAS
- X for (p = buf; p = index(p, ','); p++)
- X *p = ' ';
- #endif /* NO_COMMAS */
- X
- X Debug("mail command: %s\n", buf);
- X
- X if (isoff(flags, VERBOSE) && debug < 3)
- X switch (fork_pid = fork()) {
- X case 0: /* the child will send the letter. ignore signals */
- #if defined(SYSV) && !defined(AUX)
- X if (setpgrp() == -1)
- #else /* !SYSV || AUX */
- X if (setpgrp(0, getpid()) == -1)
- #endif /* SYSV && !AUX */
- X error("setpgrp");
- X /* NOTE: No special case needed for tool here because
- X * this is the sending child -- it's going to pclose()
- X * and then exit(), so who cares about the notifier?
- X */
- X (void) signal(SIGCHLD, SIG_DFL);
- X (void) signal(SIGTERM, SIG_IGN);
- X (void) signal(SIGINT, SIG_IGN);
- X (void) signal(SIGHUP, SIG_IGN);
- X (void) signal(SIGQUIT, SIG_IGN);
- #ifdef SIGTTIN
- X (void) signal(SIGTTOU, SIG_IGN);
- X (void) signal(SIGTTIN, SIG_IGN);
- #endif /* SIGTTIN */
- #ifdef SIGCONT
- X (void) signal(SIGCONT, SIG_IGN);
- X (void) signal(SIGTSTP, SIG_IGN);
- #endif /* SIGCONT */
- X turnon(glob_flags, IGN_SIGS);
- X when -1:
- X error("fork failed trying to send mail");
- X if (isoff(flags, EDIT_HDRS)) {
- X strcpy(To, orig_to);
- X strcpy(Cc, orig_cc);
- X strcpy(Bcc, orig_bcc);
- X }
- X /* fall thru */
- X default:
- X if (fork_pid > 0) {
- #ifdef SUNTOOL
- X /* If we're a tool, we have to register a handler
- X * for the fork_pid. Otherwise, it's used only as
- X * an error indicator, so reset it to zero.
- X */
- X if (istool)
- X notify_set_wait3_func(mfprint_sw, my_wait3, fork_pid);
- #endif /* SUNTOOL */
- X fork_pid = 0;
- X }
- X /* istool doesn't need ed_fp, so don't keep it around */
- X if (istool || !fork_pid && isoff(glob_flags, REDIRECT))
- X (void) fclose(ed_fp), ed_fp = NULL_FILE;
- X free_vec(&names[1]);
- X if (isoff(flags, EDIT_HDRS))
- X xfree(orig_to), xfree(orig_cc), xfree(orig_bcc);
- X if (!istool) {
- X (void) signal(SIGINT, oldint);
- X (void) signal(SIGQUIT, oldquit);
- X (void) signal(SIGTERM, oldterm);
- X }
- X return fork_pid;
- X }
- X
- #ifdef MMDF
- X *(addr_list-1) = '\0';
- #endif /* MMDF */
- X if (debug > 2) {
- X files[0] = stdout;
- X if (!*addr_list)
- X addr_list = "[no recipients]";
- X } else if (*addr_list) {
- X if (!(files[0] = open_file(buf, TRUE, FALSE))) {
- X rm_edfile(-1); /* force saving of undeliverable mail */
- X if (isoff(flags, VERBOSE) && debug < 3)
- X exit(-1);
- X else
- X return 0;
- X }
- X } else
- X files[0] = NULL_FILE;
- X
- X if (ison(flags, VERBOSE))
- X wprint("Sending letter ... "), (void) fflush(stdout);
- #ifdef MMDF
- X /* give address list to submit */
- X for (p = addr_list; *p && (p = any(p, ",<")); p++)
- X if (*p == ',')
- X *p = '\n';
- X else
- X p = index(p, '>');
- X if (*addr_list)
- X (void) fprintf(files[0], "%s\n\n", addr_list);
- #endif /* MMDF */
- X
- X /* see if log is set. This is just to add message headers. No msg body. */
- X if (p = do_set(set_options, "logfile")) {
- X if (!*p)
- X p = "~/mail.log";
- X if (!index("~|/+", *p))
- X (void) sprintf(buf, "%s/%s", do_set(set_options, "cwd"), p);
- X else
- X (void) strcpy(buf, p);
- X log_file = next_file;
- X next_file += find_files(buf, names+next_file, size-next_file, 0);
- X if (log_file == next_file)
- X log_file = -1;
- X }
- X
- X /* see if record is set. If so, open that file for appending and add
- X * the letter in a format such that mail can be read from it
- X */
- X if (p = do_set(set_options, "record")) {
- X if (!*p)
- X p = "~/record";
- X if (!index("~|/+", *p))
- X (void) sprintf(buf, "%s/%s", do_set(set_options, "cwd"), p);
- X else
- X (void) strcpy(buf, p);
- X next_file += find_files(buf, names+next_file, size-next_file, 0);
- X }
- X
- X /* Don't need to open names[0] as files[0], so skip those */
- X next_file = 1 + open_list(names + 1, files + 1, next_file - 1);
- X
- X /* First, put the message separator in... */
- X for (size = 1; size < next_file; size++)
- #ifndef MSG_SEPARATOR
- X {
- X time_t t;
- X (void) time(&t);
- X (void) fprintf(files[size], "From %s %s", login, ctime(&t));
- X }
- #else /* MSG_SEPARATOR */
- #ifdef MMDF
- X (void) fputs(MSG_SEPARATOR, files[size]);
- #else /* MMDF */
- X (void) fprintf(files[size], "%s\n", MSG_SEPARATOR);
- #endif /* MMDF */
- #endif /* MSG_SEPARATOR */
- X
- X /* if redirection, ed_fp = stdin, else rewind the file just made */
- X if (isoff(glob_flags, REDIRECT))
- X rewind(ed_fp);
- X else
- X ed_fp = stdin;
- X
- #ifndef MSG_SEPARATOR
- X /* If forwarding or reading a draft, skip the leading From_ line.
- X * This is done for drafts so that messages saved by dead_letter()
- X * can be read back in as a draft; in other cases, this isn't done
- X * for edit_hdrs because FORWARD wouldn't be set.
- X */
- X if (ison(flags, FORWARD|SEND_NOW) && fgets(buf, sizeof buf, ed_fp) &&
- X strncmp(buf, "From ", 5) != 0)
- X rewind(ed_fp); /* No From_ line (should never happen) */
- #endif /* MSG_SEPARATOR */
- X {
- X long offset = add_headers(ed_fp, files, next_file, flags);
- X if (offset == -1)
- X offset = 0L;
- X (void) fseek(ed_fp, offset, L_SET);
- X }
- X
- X /* Read from stdin or the edfile till EOF and send it all to the mailer
- X * and other open files/folders/programs. Check for "From " at the
- X * beginnings of these lines to prevent creating new messages in folders.
- X */
- X while (fgets(buf, sizeof buf, ed_fp))
- X for (size = 0; size < next_file; size++) {
- X if (!files[size]) /* files[0] will be NULL if not calling MTA */
- X continue;
- X if (size == log_file)
- X continue;
- #ifndef MSG_SEPARATOR
- X if (!strncmp(buf, "From ", 5))
- X (void) fputc('>', files[size]);
- #endif /* MSG_SEPARATOR */
- X if (fputs(buf, files[size]) == EOF) {
- X if (size == 0) {
- X error("Lost connection to MTA");
- X dead_letter(-1);
- X break;
- X } else {
- X /* Drop this file, but continue writing others */
- X if (names[size]) {
- X error("Write failed: %s", names[size]);
- X (void) close_lock(names[size], files[size]);
- X xfree(names[size]);
- X } else
- X error("Write failed");
- X if (size < --next_file) {
- X names[size] = names[next_file];
- X files[size--] = files[next_file];
- X }
- X files[next_file] = NULL_FILE;
- X names[next_file] = NULL;
- X }
- X }
- X }
- X
- X /* loop thru the open files (except for the first: the mail delivery agent)
- X * and append a blank line so that ucb-mail can read these folders.
- X * Then close the files.
- X */
- X for (size = 1; size < next_file; size++) {
- #ifdef END_MSG_SEP
- X (void) fputs(END_MSG_SEP, files[size]);
- #endif /* END_MSG_SEP */
- X if (names[size]) {
- #ifndef END_MSG_SEP
- X (void) fputc('\n', files[size]);
- #endif /* !END_MSG_SEP */
- X if (close_lock(names[size], files[size]) == EOF) {
- X error("Warning: Close failed: %s", names[size]);
- X }
- X xfree(names[size]);
- X } else {
- X if (debug < 3)
- X (void) fclose(files[size]); /* Don't mess with pclose() */
- X else
- X (void) pclose(files[size]); /* unless we never forked */
- X }
- X }
- X
- X if (debug < 3) {
- X int reply_code = files[0]? pclose(files[0]) : (MTA_EXIT << 8);
- X Debug("pclose reply_code = %d\n", reply_code);
- X rm_edfile((reply_code == (MTA_EXIT << 8))? 0 : -1);
- X } else
- X rm_edfile(0);
- X
- #ifdef VERBOSE_ARG
- X if (!istool && ison(flags, VERBOSE))
- X (void) signal(SIGCHLD, oldchld);
- #endif /* VERBOSE_ARG */
- X
- X if (ison(flags, VERBOSE) || debug > 2) {
- X if (isoff(glob_flags, REDIRECT))
- X wprint("sent.\n");
- X if (!istool) {
- X (void) signal(SIGINT, oldint);
- X (void) signal(SIGQUIT, oldquit);
- X (void) signal(SIGTERM, oldterm);
- X }
- X } else
- X exit(0); /* not a user exit -- a child exit */
- X return 0;
- }
- X
- /*
- X * Add the necessary headers to make a file a legitimate mail message.
- X * This could be for a file which the user will edit (via edit_hdrs) or
- X * for delivery to an MTA.
- X * Make folders conform to RFC-822 by adding From: and Date: headers.
- X * Prefix certain header with the "Resent-" prefix when forwarding.
- X * Return offset of fp if we're parsing it for headers (for delivery to MTA).
- X */
- static long
- add_headers(fp, files, size, flags)
- FILE *fp, *files[];
- int size;
- u_long flags;
- {
- X char buf[BUFSIZ], From_buf[256], *pF = From_buf, date_str[64];
- X char *host = NULL, *p, *subj = NULL, *own_from = NULL; /* See WARNING */
- X int i, for_editor = (fp == NULL_FILE);
- X int got_date = for_editor, got_from = for_editor;
- X struct options *opts;
- X
- X if (for_editor && hfile) {
- X i = file_to_fp(hfile, files[0], "r");
- X xfree(hfile), hfile = NULL;
- X return (i < 0 ? -1 : TRUE);
- X }
- X
- X buf[0] = 0;
- X if (ourname)
- X host = ourname[0];
- X if (for_editor)
- X turnoff(flags,FORWARD); /* forwarded messages must not be edited */
- X
- X /* [Re]create a From: header -- check first to see if the user has
- X * created a From: header with the my_hdr command (the own_hdrs list).
- X * If his is not legitimate, warn user and use the other header.
- X */
- X if ((for_editor || isoff(flags, EDIT_HDRS)) &&
- X own_hdrs && !do_set(set_options, "no_hdrs")) {
- X for (opts = own_hdrs; opts; opts = opts->next)
- X if (!strcmp(opts->option, "From:")) {
- X p = opts->value;
- X skipspaces(0);
- X sprintf(buf, "%sFrom: %s\n",
- X ison(flags, FORWARD)? "Resent-" : "", p);
- X own_from = buf;
- X /* WARNING: the above depends on the following facts:
- X * 1. If for_editor, own_from will be output immediately,
- X * so buf will not be overwritten;
- X * 2. If !for_editor but EDIT_HDRS, the "real" from line
- X * will be read from the file so own_from isn't needed;
- X * 3. If neither, From: is the first line output, so
- X * buf will not be overwritten.
- X * Any change in the above means a new buffer for own_from
- X * may be needed. Check carefully.
- X */
- X }
- X }
- X if (ison(flags, FORWARD))
- X pF += Strcpy(From_buf, "Resent-");
- X pF += Strcpy(pF, "From: ");
- #ifdef UUCP
- X if (host && *host)
- X pF += strlen(sprintf(pF, "%s!", host));
- #endif /* UUCP */
- X pF += Strcpy(pF, login);
- #ifndef UUCP
- X if (host && *host)
- X pF += strlen(sprintf(pF, "@%s", host));
- #endif /* UUCP */
- X if ((p = do_set(set_options, "realname")) ||
- X (p = do_set(set_options, "name")))
- X pF += strlen(sprintf(pF, " (%s)", p));
- X *pF++ = '\n', *pF++ = 0;
- X
- X /* First print From, Date, In-Reply-To */
- X for (i = 0; i < size; i++) {
- X if (!files[i])
- X continue;
- X if (for_editor)
- X if (own_from)
- X (void) fputs(own_from, files[i]);
- X else
- X (void) fputs(From_buf, files[i]);
- X else if (isoff(flags, EDIT_HDRS)) {
- #ifdef PICKY_MAILER
- X if (i > 0)
- #endif /* PICKY_MAILER */
- X if (own_from)
- X (void) fputs(own_from, files[i]);
- X else
- X (void) fputs(From_buf, files[i]);
- X got_from = TRUE;
- X }
- X if (for_editor || isoff(flags, EDIT_HDRS)) {
- #ifdef PICKY_MAILER
- X if (i > 0 && !for_editor)
- #endif /* PICKY_MAILER */
- X (void) fprintf(files[i], "%sDate: %s\n",
- X ison(flags, FORWARD) ? "Resent-" : "", rfc_date(date_str));
- X got_date = TRUE;
- X if (*in_reply_to)
- X fprintf(files[i], "In-Reply-To: %s\n", in_reply_to);
- X }
- X }
- X if (own_from)
- X *own_from = 0; /* buf[0] must be 0 below */
- X /* next print user's own message headers */
- X if (for_editor || isoff(flags, EDIT_HDRS))
- X if (own_hdrs && !do_set(set_options, "no_hdrs")) {
- X for (opts = own_hdrs; opts; opts = opts->next) {
- X if (!strcmp(opts->option, "From:"))
- X continue;
- X for (i = 0; i < size; i++) {
- X if (!files[i])
- X continue;
- X p = opts->value;
- X skipspaces(0);
- X fprintf(files[i], "%s %s\n", opts->option, p);
- X }
- X }
- X }
- X
- X /*
- X * Now either prepare to put the rest of the headers into the file
- X * or (when sending edited headers) copy them back out of the file
- X */
- X if (for_editor) {
- X char *orig = NULL;
- X /* for edit_hdrs, print the headers followed by a blank line */
- X if (To[0]) {
- X orig = savestr(To);
- X if (!(p = alias_to_address(To))) {
- X wprint("To: list unmodified.\n");
- X p = orig;
- X }
- X (void) strcpy(To, p);
- X }
- X if (Cc[0]) {
- X strdup(orig, Cc);
- X if (!(p = alias_to_address(Cc))) {
- X wprint("Cc: list unmodified.\n");
- X p = orig;
- X }
- X (void) strcpy(Cc, p);
- X }
- X if (Bcc[0]) {
- X strdup(orig, Bcc);
- X if (!(p = alias_to_address(Bcc))) {
- X wprint("Bcc: list unmodified.\n");
- X p = orig;
- X }
- X (void) strcpy(Bcc, p);
- X }
- X xfree(orig);
- X } else if (ison(flags, EDIT_HDRS)) {
- X /* copy the headers of the message removing special headers */
- X int print_hdr = FALSE;
- X if (isoff(flags, SEND_NOW))
- X rewind(fp); /* Drafts may have had fp positioned */
- X while (fgets(buf, sizeof(buf), fp)) {
- X (void) no_newln(buf);
- X if (!buf[0])
- X break;
- X /* if the first char is NOT a space, it MUST be a new header.
- X * Otherwise, it is considered part of the message body.
- X */
- X if (!isspace(buf[0])) {
- X print_hdr = TRUE;
- X if (!(p = any(buf, " \t:")) || isspace(*p))
- X break; /* this is not a legitimate header */
- X skipspaces(1);
- X if (!*p)
- X print_hdr = FALSE; /* blank headers are not allowed */
- X p = buf;
- X if (!lcase_strncmp(buf, "resent-", 7)) {
- X if (ison(flags, EDIT_HDRS))
- X wprint("You can't use \"Resent-\" headers in edited messages.\n");
- X p += 7;
- X }
- X if (!lcase_strncmp(p, "to:", 3) ||
- X !lcase_strncmp(p, "cc:", 3) ||
- X !lcase_strncmp(p, "bcc:", 4) ||
- X !lcase_strncmp(p, "fcc:", 4) ||
- X !lcase_strncmp(p, "x-mailer:", 9) ||
- X !lcase_strncmp(p, "status:", 7))
- X print_hdr = FALSE;
- X else if (!lcase_strncmp(p, "date:", 5))
- X if (got_date)
- X wprint("You can't change or add date headers.\n");
- X else {
- X got_date = TRUE;
- X (void) sprintf(buf, "Date: %s", rfc_date(date_str));
- X p = buf;
- X }
- X else if (!lcase_strncmp(p, "subject:", 8))
- X (print_hdr = FALSE), strdup(subj, p);
- X else if (!lcase_strncmp(p, "from:", 5)) {
- X char not_me[BUFSIZ];
- X (void) strcpy(not_me, buf + 5);
- X take_me_off(not_me);
- X if (*not_me) {
- X /* Ignore bogus From: if we have a good one */
- X if (got_from)
- X print_hdr = FALSE;
- X /* otherwise, output a good one */
- X else {
- X (void) strcpy(buf, From_buf);
- X (void) no_newln(buf);
- X }
- X }
- X got_from = TRUE;
- #ifdef PICKY_MAILER
- X /* don't send From: to mta -- fool "for loop" below
- X * by initializing the loop at files[1], not files[0]
- X */
- X if (!for_editor)
- X print_hdr = 2;
- #endif /* PICKY_MAILER */
- X }
- X }
- X if (print_hdr)
- X /* print_hdr may be 2 for From: header */
- X for (i = print_hdr-1; i < size; i++)
- X if (files[i]) {
- X (void) fputs(buf, files[i]);
- X (void) fputc('\n', files[i]);
- X }
- X }
- X }
- X /* Finally, do the required (or changed) headers (Date, To, Cc) */
- X (void) wrap_addrs(To, 80);
- X (void) wrap_addrs(Cc, 80);
- X (void) wrap_addrs(Bcc, 80);
- X for (i = 0; i < size; i++) {
- X if (!files[i])
- X continue;
- #ifdef PICKY_MAILER
- X if (i > 0) {
- #endif /* PICKY_MAILER */
- X if (!got_from)
- X (void) fputs(From_buf, files[i]);
- X if (!got_date)
- X (void) fprintf(files[i], "%sDate: %s\n",
- X ison(flags, FORWARD) ? "Resent-" : "", rfc_date(date_str));
- #ifdef PICKY_MAILER
- X }
- #endif /* PICKY_MAILER */
- X (void) fprintf(files[i], "X-Mailer: %s\n", check_internal("version"));
- X (void) fprintf(files[i], "%sTo: %s\n",
- X ison(flags, FORWARD) ? "Resent-" : "", To);
- X if (for_editor || isoff(flags, EDIT_HDRS)) {
- X if (isoff(flags, FORWARD) &&
- X (*Subject || for_editor && (do_set(set_options, "ask") ||
- X do_set(set_options, "asksub"))))
- X (void) fprintf(files[i], "Subject: %s\n", Subject);
- X } else if (subj && *subj && strlen(subj) > 9)
- X (void) (fputs(subj, files[i]), fputc('\n', files[i]));
- X if (*Cc || for_editor && do_set(set_options, "askcc"))
- X (void) fprintf(files[i], "%sCc: %s\n",
- X ison(flags, FORWARD) ? "Resent-" : "", Cc);
- X if (i > 0 || for_editor)
- X /* Do not send these to mail transfer agent */
- X if (*Bcc)
- X (void) fprintf(files[i], "%sBcc: %s\n",
- X ison(flags, FORWARD) ? "Resent-" : "", Bcc);
- X if (i > 0)
- X (void) fprintf(files[i], "Status: OR\n");
- X }
- X for (i = 0; i < size; i++)
- X if (files[i])
- X (void) fflush(files[i]);
- X if (buf[0]) /* last attempted header read was a line of msg text */
- X for (i = 0; i < size; i++) {
- X if (files[i]) {
- X (void) fputs(buf, files[i]);
- X (void) fputc('\n', files[i]);
- X (void) fflush(files[i]);
- X }
- X }
- X else
- X if (isoff(flags, FORWARD))
- X for (i = 0; i < size; i++)
- X if (files[i]) {
- X (void) fputc('\n', files[i]);
- X (void) fflush(files[i]);
- X }
- X return fp? ftell(fp) : (long)TRUE;
- }
- X
- /* ARGSUSED */
- SIGRET
- rm_edfile(sig)
- {
- X if (sig > 0) {
- X char *fix;
- X if (ison(glob_flags, IGN_SIGS))
- X return;
- X /* wrapcolumn may have been trashed -- restore it */
- X if ((fix = do_set(set_options, "wrapcolumn")) && *fix)
- X wrapcolumn = atoi(fix);
- X mac_flush(); /* abort pending macros */
- X }
- X /* now check whether we should abort the letter */
- X if (sig > 0 && !killme && ison(glob_flags, IS_GETTING)) {
- X if (!istool)
- X (void) signal(sig, rm_edfile);
- X killme = 1;
- X print("\n** interrupt -- one more to kill letter **\n");
- X longjmp(cntrl_c_buf, 1);
- X }
- X killme = 0;
- X /* if sig == -1, force a save into dead.letter.
- X * else, check for nosave not being set and save anyway if it's not set
- X * sig == 0 indicates normal exit (or ~x), so don't save a dead letter.
- X */
- X if (sig == -1 || sig != 0 && !do_set(set_options, "nosave"))
- X dead_letter(sig);
- X if (isoff(glob_flags, REDIRECT) && ed_fp) /* ed_fp may be null in toolmode*/
- X (void) fclose(ed_fp), ed_fp = NULL_FILE;
- X (void) unlink(edfile);
- X
- X turnoff(glob_flags, IS_GETTING);
- X if (sig == -1)
- X return;
- X
- X if (sig == SIGHUP)
- X cleanup(0);
- X if (!istool) {
- X (void) signal(SIGINT, oldint);
- X (void) signal(SIGQUIT, oldquit);
- X (void) signal(SIGTERM, oldterm);
- X }
- X
- X if (sig == 0 || sig == -2 || istool) /* make sure sigchld is reset first */
- X return;
- X
- X if (isoff(glob_flags, DO_SHELL)) { /* If we're not in a shell, exit */
- X puts("exiting");
- X echo_on();
- X exit(1);
- X }
- X longjmp(jmpbuf, 1);
- }
- X
- /* save letter into dead letter */
- dead_letter(sig)
- int sig; /* signal passed to rm_edfile() or 0 */
- {
- X char *p, buf[BUFSIZ];
- X long t;
- X FILE *dead;
- X
- X if (ison(glob_flags, REDIRECT)) {
- X print("input redirected -- can't save dead letter.\n");
- X return;
- X }
- X /* If the file doesn't exist, get outta here. File may not exist if
- X * user generated a ^C from a promptable header and catch sent us here.
- X */
- X if (!ed_fp && Access(edfile, R_OK) != 0)
- X return;
- X /* User may have killed mush via a signal while he was in an editor.
- X * ed_fp will be NULL in this case. Since the file does exist (above),
- X * open it so we can copy it to dead letter.
- X */
- X if (!ed_fp && !(ed_fp = fopen(edfile, "r"))) {
- X error("can't save dead letter from %s", edfile);
- X return;
- X }
- X /* don't save a dead letter if there's nothing to save. */
- X if (fseek(ed_fp, 0L, 2) || ftell(ed_fp) <= 1L)
- X return;
- X if (!(p = do_set(set_options, "dead")))
- X p = "~/dead.letter";
- X if (!(dead = open_file(p + (*p == '|'), (*p == '|'), TRUE)))
- X return;
- X (void) time (&t);
- X (void) fflush(ed_fp);
- X rewind(ed_fp);
- #ifdef MSG_SEPARATOR
- X (void) fputs(MSG_SEPARATOR, dead);
- #ifndef MMDF
- X (void) fputc('\n', dead);
- #endif /* MMDF */
- #else /* MSG_SEPARATOR */
- X (void) fprintf(dead, "From %s %s", login, ctime(&t));
- #endif /* MSG_SEPARATOR */
- X (void) fprintf(dead, "From: %s\nTo: %s\nSubject: %s\n", login, To, Subject);
- X (void) fprintf(dead, "Date: %s\n", rfc_date(buf));
- X if (*Cc)
- X (void) fprintf(dead, "Cc: %s\n", Cc);
- X if (*Bcc)
- X (void) fprintf(dead, "Bcc: %s\n", Bcc);
- X (void) fputc('\n', dead);
- X while (fgets(buf, sizeof(buf), ed_fp))
- X (void) fputs(buf, dead);
- X (void) fputc('\n', dead);
- #ifdef END_MSG_SEP
- X (void) fputs(END_MSG_SEP, dead);
- #endif /* END_MSG_SEP */
- X if (*p != '|')
- X (void) close_lock(p, dead);
- X else
- X (void) pclose(dead);
- X wprint("Saved%s letter in %s.\n", sig > 0? " unfinished" : "", p);
- }
- SHAR_EOF
- echo 'File mail.c is complete' &&
- chmod 0644 mail.c ||
- echo 'restore of mail.c failed'
- Wc_c="`wc -c < 'mail.c'`"
- test 57669 -eq "$Wc_c" ||
- echo 'mail.c: original size 57669, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= mail.icon.1 ==============
- if test -f 'mail.icon.1' -a X"$1" != X"-c"; then
- echo 'x - skipping mail.icon.1 (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting mail.icon.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'mail.icon.1' &&
- /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
- X */
- X 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001,
- X 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
- X 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
- X 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
- X 0x8000,0x0000,0x0000,0x0001,0x8000,0x1FFF,0xFFFF,0xFE01,
- X 0x8000,0xFE00,0x0000,0x0181,0x8007,0x01C0,0x0000,0x0061,
- X 0x8018,0x0030,0x0000,0x0011,0x8020,0x7008,0x0000,0x0011,
- X 0x80C1,0xFC06,0x0000,0x0009,0x8101,0xFC01,0x0000,0x0009,
- X 0x8103,0xFE01,0x0000,0x0005,0x8203,0xFE00,0x8000,0x0005,
- X 0x8403,0xFE00,0x4000,0x0005,0x8401,0xFC00,0x4000,0x0005,
- X 0x8801,0xFC00,0x2000,0x0005,0x8800,0x7000,0x2000,0x0005,
- X 0x8800,0x0000,0x3000,0x0005,0x9000,0x0000,0x1000,0x0005,
- X 0x9000,0x0000,0x1000,0x0005,0x93FF,0xFFFF,0x9000,0x0025,
- X 0xA200,0x0000,0x9000,0x00E5,0xA200,0x0000,0x9000,0x03A5,
- X 0xA200,0x0000,0x9000,0x0625,0xA3FF,0xFFFF,0x9000,0x1C25,
- X 0xA000,0x0000,0x1000,0x3425,0xA000,0x0000,0x1000,0xC425,
- X 0xA000,0x0000,0x1003,0x8425,0xA000,0x0000,0x1006,0x0425,
- X 0xA000,0x0000,0x101C,0x0425,0xA000,0x0000,0x11F0,0x0425,
- X 0xA000,0x0000,0x13E0,0x0445,0xA000,0x0000,0x13E0,0x0585,
- X 0xA000,0x0000,0x13E0,0x0605,0xA000,0x0000,0x11C0,0x0405,
- X 0xA000,0x0000,0x1000,0x000D,0xA000,0x0000,0x1000,0x0011,
- X 0xA000,0x0000,0x1000,0x0021,0xA000,0x0000,0x1000,0x00C1,
- X 0xA000,0x0000,0x1000,0x0101,0xA000,0x0000,0x1000,0x0601,
- X 0xA000,0x0000,0x1000,0x0801,0xA000,0x0000,0x1000,0x3801,
- X 0xA000,0x0000,0x1000,0x4801,0xA000,0x0000,0x1000,0x8801,
- X 0xA000,0x0000,0x1003,0x0801,0xA000,0x0000,0x1004,0x0801,
- X 0xA000,0x0000,0x101C,0x0801,0xA000,0x0000,0x1024,0x0801,
- X 0xA000,0x0000,0x1044,0x0801,0xA000,0x0000,0x1184,0x0801,
- X 0xA000,0x0000,0x1204,0x0801,0xA000,0x0000,0x1404,0x0801,
- X 0xBFFF,0xFFFF,0xF804,0x0801,0x8000,0x0000,0x0004,0x0801,
- X 0x8000,0x0000,0x0004,0x0801,0x8000,0x0000,0x0004,0x0801,
- X 0x8000,0x0000,0x0004,0x0801,0xFFFF,0xFFFF,0xFFFF,0xFFFF
- SHAR_EOF
- chmod 0644 mail.icon.1 ||
- echo 'restore of mail.icon.1 failed'
- Wc_c="`wc -c < 'mail.icon.1'`"
- test 1933 -eq "$Wc_c" ||
- echo 'mail.icon.1: original size 1933, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= mail.icon.2 ==============
- if test -f 'mail.icon.2' -a X"$1" != X"-c"; then
- echo 'x - skipping mail.icon.2 (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting mail.icon.2 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'mail.icon.2' &&
- /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
- X */
- X 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001,
- X 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x00E0,0x0001,
- X 0x8000,0x0000,0x00DE,0x0001,0x8000,0x0000,0x00C1,0xE001,
- X 0x8000,0x0000,0x00C0,0x1801,0x8000,0x0000,0x00C0,0x0801,
- X 0x8000,0x0000,0x00C0,0x0801,0x8000,0x1FFF,0xFFC0,0x0E01,
- X 0x8000,0xFE00,0x00C0,0x0981,0x8007,0x01C0,0x00C0,0x0861,
- X 0x8018,0x0030,0x00C0,0x0811,0x8020,0x7008,0x00C0,0x0811,
- X 0x80C1,0xFC06,0x00C0,0x1809,0x8101,0xBC01,0x00C0,0x6009,
- X 0x8103,0x1E01,0x00C1,0x8005,0x8202,0x0E00,0x80C6,0x0005,
- X 0x8404,0x0400,0x40D8,0x0005,0x8408,0x0200,0x40E0,0x0005,
- X 0x8810,0x0100,0x20C0,0x0005,0x8820,0x6080,0x20C0,0x0005,
- X 0x8840,0x4040,0x30C0,0x0005,0x9081,0x3020,0x10C0,0x0005,
- X 0x9041,0x9C10,0x10C0,0x0005,0x93E0,0x8A0F,0x90C0,0x0005,
- X 0xA210,0x6404,0x90C0,0x0005,0xA208,0x3002,0x90C0,0x0005,
- X 0xA204,0x1401,0x90C0,0x0005,0xA3FF,0xFFFF,0x90C0,0x0005,
- X 0xA000,0x0000,0x10C0,0x0005,0xA000,0x0000,0x10C0,0x0005,
- X 0xA000,0x0000,0x10C0,0x0005,0xA000,0x0000,0x10C0,0x0005,
- X 0xA000,0x0000,0x10C0,0x0005,0xA000,0x0000,0x11C0,0x0005,
- X 0xA000,0x0000,0x13E0,0x0005,0xA000,0x0000,0x13E0,0x0005,
- X 0xA000,0x0000,0x13E0,0x0005,0xA000,0x0000,0x11C0,0x0005,
- X 0xA000,0x0000,0x1000,0x000D,0xA000,0x0000,0x1000,0x0011,
- X 0xA000,0x0000,0x1000,0x0021,0xA000,0x0000,0x1000,0x00C1,
- X 0xA000,0x0000,0x1000,0x0101,0xA000,0x0000,0x1000,0x0601,
- X 0xA000,0x0000,0x1000,0x0801,0xA000,0x0000,0x1000,0x3001,
- X 0xA000,0x0000,0x1000,0x4001,0xA000,0x0000,0x1000,0x8001,
- X 0xA000,0x0000,0x1003,0x8001,0xA000,0x0000,0x1004,0x8001,
- X 0xA000,0x0000,0x1018,0x8001,0xA000,0x0000,0x1020,0x8001,
- X 0xA000,0x0000,0x1060,0x8001,0xA000,0x0000,0x1180,0x8001,
- X 0xA000,0x0000,0x1280,0x8001,0xA000,0x0000,0x1480,0x8001,
- X 0xBFFF,0xFFFF,0xFC80,0x8001,0x8000,0x0000,0x0080,0x8001,
- X 0x8000,0x0000,0x0080,0x8001,0x8000,0x0000,0x0080,0x8001,
- X 0x8000,0x0000,0x0080,0x8001,0xFFFF,0xFFFF,0xFFFF,0xFFFF
- SHAR_EOF
- chmod 0644 mail.icon.2 ||
- echo 'restore of mail.icon.2 failed'
- Wc_c="`wc -c < 'mail.icon.2'`"
- test 1933 -eq "$Wc_c" ||
- echo 'mail.icon.2: original size 1933, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= main.c ==============
- if test -f 'main.c' -a X"$1" != X"-c"; then
- echo 'x - skipping main.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting main.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
- /* @(#)main.c (c) copyright 10/18/86 (Dan Heller) */
- X
- #include "mush.h"
- #include "options.h"
- X
- #if defined(sun) && defined(M_DEBUG)
- cpu()
- {
- X print("CPU time limit exceeded!\n");
- }
- #endif /* sun && DEBUG */
- X
- #ifdef LCKDFLDIR
- extern char *lckdfldir;
- #endif /* LCKDFLDIR */
- X
- #ifdef DOT_LOCK
- int sgid;
- #ifdef BSD
- int rgid;
- #endif /* BSD */
- #endif /* DOT_LOCK */
- X
- /*ARGSUSED*/ /* we ignore envp */
- main(argc, argv)
- int argc;
- char *argv[];
- {
- X int n;
- X char buf[MAXPATHLEN];
- X register char *p;
- X struct mush_flags Flags;
- X
- #ifndef INTERNAL_MALLOC
- X extern char *stackbottom; /* used by xfree() */
- X
- X stackbottom = (char *) &argc;
- #endif /* INTERNAL_MALLOC */
- X
- #ifdef AUX
- X set42sig(); /* Use 4.2 BSD signal handling conventions */
- #endif /* AUX */
- X
- #ifdef LCKDFLDIR
- X lckdfldir = LCKDFLDIR;
- #endif /* LCKDFLDIR */
- X prog_name = basename(*argv);
- X
- X (void) signal(SIGBUS, bus_n_seg);
- X (void) signal(SIGSEGV, bus_n_seg);
- X (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
- X
- #if defined(sun) && defined(M_DEBUG)
- X (void) signal(SIGXCPU, cpu);
- X
- X if (p = getenv("MALLOC_DEBUG"))
- X malloc_debug(atoi(p));
- X else
- X malloc_debug(0);
- #endif /* sun && debug */
- X
- X if (!isatty(0))
- X turnon(glob_flags, REDIRECT);
- X else
- X (void) setbuf(stdin, NULL);
- X
- X init(); /* must be done before checking mail since "login" is set here */
- X mailfile = "";
- #ifdef HOMEMAIL
- X {
- X char *home = do_set(set_options, "home");
- X if (!home)
- X home = ALTERNATE_HOME;
- X strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE));
- X }
- #else /* HOMEMAIL */
- X strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
- #endif /* HOMEMAIL */
- X
- X n = preparse_opts(&argc,argv);
- X
- X /* check for any mail at all and exit if we're not continuing */
- X if (!n) {
- X struct stat statb;
- X if (stat(spoolfile, &statb) || statb.st_size == 0) {
- X (void) printf("No mail for %s.\n", login);
- X exit(0);
- X }
- X }
- X
- #ifdef DOT_LOCK
- X sgid = getegid();
- #ifdef BSD
- X rgid = getgid();
- X setregid(sgid, rgid);
- #else
- X setgid(getgid());
- #endif /* BSD */
- #endif /* DOT_LOCK */
- X
- X parse_options(&argv, &Flags);
- X
- X (void) cmd_line(strcpy(buf, "set cmd_help"), NULL);
- #ifdef SUNTOOL
- X if (istool)
- X (void) cmd_line(strcpy(buf, "set tool_help"), NULL);
- #endif /* SUNTOOL */
- X
- X set_cwd();
- X
- X if (Flags.init_file)
- X (void) cmd_line(sprintf(buf, "source %s", Flags.init_file), msg_list);
- X if (Flags.source_rc > 0) {
- X /* use cmd_line() in case DEFAULT_RC has expandable chars */
- X (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
- X }
- X if (Flags.source_rc > -1)
- X (void) source(0, DUBL_NULL);
- X mailfile = Flags.folder;
- X
- X if (*spoolfile != '/') {
- X n = 1;
- X p = getpath(spoolfile, &n);
- X if (n == -1)
- X (void) fputs(p, stderr), exit(1);
- X else if (n)
- X (void) fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1);
- X else if (*p != '/') {
- X /* if it still isn't a full path, make it one */
- X char *wd = do_set(set_options, "cwd");
- X if (*wd) {
- X (void) sprintf(buf, "%s/%s", wd, p);
- X strdup(spoolfile, buf);
- X } else
- X strdup(spoolfile, p);
- X } else
- X strdup(spoolfile, p);
- X }
- X
- #ifdef SUNTOOL
- X if (istool) {
- X make_tool();
- X turnon(glob_flags, DO_SHELL);
- X turnoff(glob_flags, REDIRECT); /* -- SunOS-4.0 has a problem here */
- X }
- #endif /* SUNTOOL */
- X
- X /* now we're ready for I/O */
- X if (isoff(glob_flags, REDIRECT)) {
- X /* make sure we can always recover from no echo mode */
- X (void) signal(SIGINT, catch);
- X (void) signal(SIGQUIT, catch);
- X (void) signal(SIGHUP, catch);
- X if (istool)
- X turnon(glob_flags, ECHO_FLAG);
- X tty_settings();
- #ifdef SIGCONT
- X (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
- #endif /* SIGCONT */
- X /* echo_off() checks to see if echo_flg is set, so don't worry */
- X echo_off();
- X }
- X
- X if (!istool && ison(glob_flags, IS_SENDING)) {
- X char recipients[BUFSIZ], *mailv[16];
- X (void) argv_to_string(recipients, argv);
- X fix_up_addr(recipients);
- X mailv[0] = "mail";
- X n = 1;
- X if (ison(Flags.flg, VERBOSE))
- X mailv[n++] = "-v";
- X if (Flags.Subj && *(Flags.Subj)) {
- X mailv[n++] = "-s";
- X mailv[n++] = Flags.Subj;
- X }
- X if (Flags.Cc && *(Flags.Cc)) {
- X fix_up_addr(Flags.Cc);
- X mailv[n++] = "-c";
- X mailv[n++] = Flags.Cc;
- X }
- X if (Flags.Bcc && *(Flags.Bcc)) {
- X fix_up_addr(Flags.Bcc);
- X mailv[n++] = "-b";
- X mailv[n++] = Flags.Bcc;
- X }
- X if (ison(Flags.flg, NO_SIGN))
- X mailv[n++] = "-u";
- X if (ison(Flags.flg, SEND_NOW))
- X mailv[n++] = "-U";
- X if (Flags.draft) {
- X if (isoff(Flags.flg, SEND_NOW))
- X mailv[n++] = "-E";
- X mailv[n++] = "-h";
- X mailv[n++] = Flags.draft;
- X }
- X mailv[n++] = recipients;
- X mailv[n] = NULL;
- X /* set now in case user is not running shell, but is running debug */
- X if (!istool)
- X (void) signal(SIGCHLD, sigchldcatcher);
- X if (!setjmp(jmpbuf))
- X (void) do_mail(n, mailv, msg_list);
- X /* do shell set from above: "mush -S user" perhaps */
- X if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
- X if (isoff(glob_flags, REDIRECT))
- X echo_on();
- X exit(0);
- X }
- X }
- X turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
- X
- X if (ison(glob_flags, REDIRECT)
- X && (!Flags.src_file || !Flags.src_n_exit)) {
- X puts("You can't redirect input unless you're sending mail.");
- X puts("If you want to run a shell with redirection, use \"-i\"");
- X cleanup(0);
- X }
- X if (!*mailfile) {
- X strdup(mailfile, spoolfile);
- X if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
- X /* we know it's not the spool file here */
- X (void) printf("No mail in %s.\n", mailfile);
- X echo_on(), exit(0);
- X }
- X }
- X
- X if (!hdrs_only) {
- X /* catch will test DO_SHELL and try to longjmp if set. this is a
- X * transition state from no-shell to do-shell to ignore sigs to
- X * avoid a longjmp botch. Note setjmp isn't called until do_loop().
- X */
- X turnon(glob_flags, IGN_SIGS);
- #ifdef CURSES
- X if (ison(glob_flags, PRE_CURSES))
- X (void) curses_init(0, DUBL_NULL);
- X turnoff(glob_flags, PRE_CURSES);
- #endif /* CURSES */
- X }
- X
- X /* find a free tmpfile */
- X if (!(p = getdir(do_set(set_options, "tmpdir"))))
- alted:
- X p = ALTERNATE_HOME;
- X {
- X int pid = getpid();
- X while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, pid++), F_OK))
- X ;
- X }
- X /* just create the file, make sure it's empty. It'll close later and
- X * be reopened for reading only.
- X */
- X if (!(tmpf = mask_fopen(tempfile, "w"))) {
- X if (strcmp(p, ALTERNATE_HOME))
- X goto alted;
- X error("Can't create tempfile %s", tempfile);
- X cleanup(0);
- X }
- X
- X /* do pseudo-intelligent stuff with certain signals */
- X (void) signal(SIGINT, catch);
- X (void) signal(SIGQUIT, catch);
- X (void) signal(SIGHUP, catch);
- X
- X if (!hdrs_only && !istool && (!Flags.src_file || !Flags.src_n_exit) &&
- X !glob(do_set(set_options, "quiet"), "{,{,*[ \\,]}startup{,[ \\,]*}}"))
- X (void) printf("%s: Type '?' for help.\n", check_internal("version"));
- X
- X (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile);
- X if ((argv = mk_argv(buf, &argc, TRUE)) && argc > 0) {
- X if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) {
- X if (iscurses)
- X putchar('\n');
- X turnoff(glob_flags, IGN_SIGS), cleanup(0);
- X }
- #ifdef CURSES
- X if (iscurses)
- X (void) curses_help_msg(TRUE);
- #endif /* CURSES */
- X free_vec(argv);
- X }
- X
- X if (hdrs_only) {
- X (void) sprintf(buf, "headers %s", hdrs_only);
- X if (argv = make_command(buf, TRPL_NULL, &argc))
- X (void) do_hdrs(argc, argv, NULL);
- X cleanup(0);
- X }
- X
- X turnon(glob_flags, DO_SHELL);
- X
- X /* finally, if the user wanted to source a file to execute, do it now */
- X if (Flags.src_file) {
- X char *s_argv[2];
- X s_argv[1] = Flags.src_file;
- X (void) source(2, s_argv);
- X if (!istool && Flags.src_n_exit)
- X cleanup(0);
- X }
- X
- #ifdef SUNTOOL
- X if (istool) {
- X char buf[16];
- X n = 0;
- X if (time_out < 30)
- X time_out = 30;
- X turnoff(glob_flags, IGN_SIGS);
- X (void) do_hdrs(0, DUBL_NULL, NULL);
- X timerclear(&(mail_timer.it_interval));
- X timerclear(&(mail_timer.it_value));
- X
- X /* Reload time with value of timeout upon timer expiration. */
- X mail_timer.it_interval.tv_sec = time_out;
- X
- X mail_timer.it_value.tv_sec = time_out;
- X (void) notify_set_itimer_func(tool, do_check,
- X ITIMER_REAL, &mail_timer, (struct itimerval *) 0);
- X timeout_cursors(FALSE);
- X window_main_loop(tool);
- X cleanup(0);
- X }
- #endif /* SUNTOOL */
- X do_loop();
- }
- X
- do_version()
- {
- X print("%s\n", check_internal("version"));
- X return -1;
- }
- X
- /* set the current working directory */
- set_cwd()
- {
- X char cwd[MAXPATHLEN];
- X
- X if (GetCwd(cwd, MAXPATHLEN) == NULL) {
- X error("set_cwd: %s", cwd);
- X (void) un_set(&set_options, "cwd");
- X } else {
- X char *argv[4];
- X argv[0] = "cwd";
- X argv[1] = "=";
- X argv[2] = cwd;
- X argv[3] = NULL;
- X (void) add_option(&set_options, argv);
- X }
- }
- SHAR_EOF
- chmod 0644 main.c ||
- echo 'restore of main.c failed'
- Wc_c="`wc -c < 'main.c'`"
- test 8757 -eq "$Wc_c" ||
- echo 'main.c: original size 8757, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= makefile.bsd ==============
- if test -f 'makefile.bsd' -a X"$1" != X"-c"; then
- echo 'x - skipping makefile.bsd (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting makefile.bsd (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'makefile.bsd' &&
- # makefile.bsd (c) copyright 1991 (Dan Heller)
- # SunOS users should add -DSUN_3_5, -DSUN_4_0, or -DSUN_4_1 to CFLAGS.
- #
- HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h
- X
- SRCS= main.c init.c misc.c mail.c hdrs.c execute.c commands.c print.c dates.c \
- X signals.c setopts.c msgs.c pick.c sort.c expr.c folders.c \
- X loop.c viewopts.c curses.c curs_io.c bind.c file.c strings.c \
- X lock.c macros.c options.c addrs.c malloc.c glob.c command2.c
- OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
- X signals.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
- X folders.o dates.o loop.o viewopts.o curses.o curs_io.o bind.o \
- X lock.o macros.o options.o addrs.o malloc.o glob.o command2.o
- X
- HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
- X cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
- X
- MAKES= makefile.bsd makefile.xenix makefile.sys.v makefile.hpux makefile.sun
- X
- # See the README for changes needed to compile under Ultrix.
- # In particular, you may need -DSIGRET=void and/or -ltermcap.
- CFLAGS= -O -DCURSES -DBSD
- LDFLAGS=
- LINTFLAGS= -bxah -Dlint -DCURSES -DBSD
- LIBES= -lcurses -ltermlib
- OTHERLIBS=
- # Use some variant of this one if you #define MMDF in config.h
- #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
- X
- mush: $(OBJS)
- X @echo loading...
- X @cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
- X
- $(OBJS): config.h mush.h
- loop.o: version.h
- X
- tape:
- X @tar cv $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES)
- X
- tar:
- X @tar fcv MUSH $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES)
- X
- tarmail:
- X tar fcv - $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES) | \
- X compress | btoa > mush.tarmail
- X
- lint:
- X lint $(LINTFLAGS) $(SRCS)
- X
- clean:
- X rm -f *.o core mush
- X
- BINDIR= /usr/local/bin
- LIBDIR= /usr/local/lib
- MRCDIR= /usr/lib
- MANDIR= /usr/local/man/man1
- MANEXT= 1
- X
- install: mush
- X mv mush $(BINDIR)
- X strip $(BINDIR)/mush
- X chmod 0755 $(BINDIR)/mush
- X cp mush.1 $(MANDIR)/mush.$(MANEXT)
- X chmod 0644 $(MANDIR)/mush.$(MANEXT)
- X cp cmd_help $(LIBDIR)
- X chmod 0644 $(LIBDIR)/cmd_help
- X cp Mushrc $(MRCDIR)/Mushrc
- X chmod 0644 $(MRCDIR)/Mushrc
- SHAR_EOF
- chmod 0644 makefile.bsd ||
- echo 'restore of makefile.bsd failed'
- Wc_c="`wc -c < 'makefile.bsd'`"
- test 2096 -eq "$Wc_c" ||
- echo 'makefile.bsd: original size 2096, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= makefile.hpux ==============
- if test -f 'makefile.hpux' -a X"$1" != X"-c"; then
- echo 'x - skipping makefile.hpux (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting makefile.hpux (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'makefile.hpux' &&
- # Mush makefile for HP/UX.
- #
- HDRS1= mush.h config.h
- HDRS2= strings.h options.h
- HDRS3= bindings.h glob.h
- HDRS4= version.h
- SRCS1= commands.c dates.c execute.c expr.c folders.c \
- X hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
- X print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
- SRCS2= bind.c curs_io.c curses.c file.c strings.c macros.c \
- X addrs.c malloc.c glob.c command2.c
- X
- OBJS1= commands.o dates.o execute.o expr.o folders.o \
- X hdrs.o init.o loop.o mail.o main.o misc.o msgs.o pick.o \
- X print.o setopts.o signals.o sort.o viewopts.o options.o lock.o
- OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \
- X addrs.o malloc.o glob.o command2.o
- X
- HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
- X cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
- X
- # If your HP-UX version is older than 6.5, you will need remove -DDIRECTORY
- X
- HPFLAGS= -DHPUX -DSELECT -DDIRECTORY
- CFLAGS= -O -DSYSV -DUSG -DCURSES -DREGCMP -DSIGRET=void $(HPFLAGS)
- LDFLAGS=
- LIBS= -lcurses -lPW -lmalloc
- OTHERLIBS=
- # Use some variant of this one if you #define MMDF in config.h
- #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
- PROG= mush
- X
- $(PROG): $(OBJS1) $(OBJS2)
- X @echo loading...
- X @$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
- X
- $(OBJS1): $(HDRS1) $(HDRS2)
- $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
- loop.o: version.h
- X
- BINDIR= /usr/local/bin
- LIBDIR= /usr/local/lib
- MRCDIR= /usr/lib
- MANDIR= /usr/local/man/man1
- MANEXT= 1
- X
- install: mush
- X cp mush $(BINDIR)
- X strip $(BINDIR)/mush
- X chmod 0755 $(BINDIR)/mush
- X cp mush.1 $(MANDIR)/mush.$(MANEXT)
- X chmod 0644 $(MANDIR)/mush.$(MANEXT)
- X cp cmd_help $(LIBDIR)
- X chmod 0644 $(LIBDIR)/cmd_help
- X cp Mushrc $(MRCDIR)/Mushrc
- X chmod 0644 $(MRCDIR)/Mushrc
- SHAR_EOF
- chmod 0644 makefile.hpux ||
- echo 'restore of makefile.hpux failed'
- Wc_c="`wc -c < 'makefile.hpux'`"
- test 1735 -eq "$Wc_c" ||
- echo 'makefile.hpux: original size 1735, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= makefile.sun ==============
- if test -f 'makefile.sun' -a X"$1" != X"-c"; then
- echo 'x - skipping makefile.sun (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting makefile.sun (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'makefile.sun' &&
- # makefile.sun (c) copyright 1986 (Dan Heller)
- SHAR_EOF
- true || echo 'restore of makefile.sun failed'
- fi
- echo 'End of part 12'
- echo 'File makefile.sun is continued in part 13'
- echo 13 > _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.
-