home *** CD-ROM | disk | FTP | other *** search
- /*++
- /* NAME
- /* reply 3
- /* SUMMARY
- /* reply to a message
- /* PROJECT
- /* pc-mail
- /* PACKAGE
- /* mail
- /* SYNOPSIS
- /* int reply()
- /* DESCRIPTION
- /* reply() is invoked when the user has selected a mail message
- /* and wants to send a reply.
- /*
- /* If possible, the reply address and subject are extracted from
- /* the original message file. Reply-To: addresses are given precedence
- /* over From: addresses.
- /*
- /* The reply may include a quoted copy of the body of the original
- /* message.
- /*
- /* After editing the reply, the user gets a chance to modify the
- /* extracted reply address.
- /* FILES
- /* mail.msg, file being edited (in current directory)
- /* $MAILDIR/ennnnn, message file (body)
- /* $MAILDIR/cnnnnn, meta file (summary)
- /* $MAILDIR/header, template mail header file
- /* $MAILDIR/trailer, template signature file
- /* SEE ALSO
- /* email(3)
- /* DIAGNOSTICS
- /* If i/o errors are detected, an error message to that effect is
- /* displayed.
- /* BUGS
- /* Only understands From: and Reply-To: addresses. Reply-To: has higher
- /* precedence. No attempt is made to reconstruct BANG paths from
- /* successive UUCP-style From_ lines.
- /* AUTHOR(S)
- /* W.Z. Venema
- /* Eindhoven University of Technology
- /* Department of Mathematics and Computer Science
- /* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
- /* CREATION DATE
- /* Sun Dec 10 15:48:35 MET 1989
- /* LAST MODIFICATION
- /* 90/01/22 13:02:29
- /* VERSION/RELEASE
- /* 2.1
- /*--*/
-
- #include <stdio.h>
-
- #include "defs.h"
- #include "path.h"
- #include "pager.h"
- #include "screen.h"
- #include "status.h"
- #include "mail.h"
- #include "ascf.h"
- #include "ms_parse.h"
-
- /* forward declarations */
-
- hidden int make_reply();
- hidden int init_reply();
- hidden void doquote();
- hidden int getsubfrom();
-
- hidden char original[BUFSIZ]; /* file name of original message */
-
- #define LINE 256 /* max. line length supported here */
-
- hidden char from[LINE]; /* reply address */
-
- /* reply - user wants to reply to a message */
-
- public int reply()
- {
- static Screen screen[] = {
- YESNO, 0, init_reply, int_error,
- 0, 0, 0,
- "Press ESC to cancel. Include original message?",
- };
-
- kbdinp(screen);
- return(S_BREAK);
- }
-
- /* init_reply - initial reply handling */
-
- hidden int init_reply(need_quote)
- register int need_quote;
- {
- register unsigned msgno;
- register int stat;
-
- strcpy(original, message); /* keep original message name */
- msgno = newseqno();
- strcpy(message, work_mesg(msgno)); /* create message file name */
- strcpy(comment, work_meta(msgno)); /* create meta file name */
-
- if ((stat = make_reply(need_quote)) /* create template message */
- ||(stat = edit(message, MAILFILE))) /* and invoke editor */
- errdisp(stat);
- work_disp(from); /* ask disposition */
- return (S_REDRAW | S_BREAK); /* say screen was changed */
- }
-
- /* make_reply - create response file */
-
- hidden int make_reply(need_quote)
- int need_quote;
- {
- register FILE *out;
- char subj[LINE];
- int err;
-
- if (getsubfrom(original, subj, from)) { /* extract subject and sender */
- return (E_READERR);
- } else if (out = fopen(message, "w")) { /* build response file */
- (void) fprintf(out, "Subject: Re: %s\n", subj[0] ? subj : "");
- (void) textcopy(header_file(), out); /* append custom headers */
- (void) putc('\n', out);
- if (need_quote) {
- doquote(original, out); /* quote original text */
- (void) putc('\n', out);
- }
- (void) textcopy(trailer_file(), out); /* append custom signature */
-
- err = (fflush(out) || ferror(out)); /* do limited error checking */
- (void) fclose(out);
- return (err ? E_WRITERR : 0);
- } else {
- return (E_WRITERR);
- }
- }
-
- /* getsubfrom - extract Sender and Subject from original message */
-
- hidden int getsubfrom(original, subj, from)
- char *original;
- char *subj;
- char *from;
- {
- FILE *in;
- char line[LINE];
- int context = MS_UUCP;
- int err = 0;
-
- /*
- * Reply-To: addresses have higher precedence than From: addresses. Skip
- * "Re: " at the beginning of a subject.
- */
-
- subj[0] = from[0] = 0;
-
- if (in = ascopen(original, "r")) {
- while ((context != MS_BODY) && ascgets(line, sizeof(line), in)) {
- if ((context = ms_parse(context, line)) == MS_HEADER) {
- /* Process From: only if we did not see Reply-To: */
- if (from[0] == 0
- && !hscanf(line, "From:", " %*[^<] < %[^>]", from))
- (void) hscanf(line, "From:", "%s", from);
- /* Process Reply-To: even if we found a From: address */
- if (!hscanf(line, "Subject: Re:", " %[^\n]", subj)
- && !hscanf(line, "Subject:", " %[^\n]", subj)
- && !hscanf(line, "Reply-To:", " %*[^<] < %[^>]", from))
- (void) hscanf(line, "Reply-To:", " %s", from);
- }
- }
- err = ferror(in);
- (void) ascclose(in);
- }
- return (err);
- }
-
- /* doquote - quote text from original message */
-
- hidden void doquote(original, out)
- char *original;
- FILE *out;
- {
- int context = MS_UUCP;
- char line[LINE];
- FILE *in;
-
- /* Suppress the first line of the message body if it is empty. */
-
- if (in = ascopen(original, "r")) {
- while (ascgets(line, sizeof(line), in)) {
- switch (context = ms_parse(context, line)) {
- case MS_BODY:
- context++; /* hack */
- if (line[0] == 0) /* hack */
- break;
- /* FALLTHROUGH */
- case MS_BODY + 1: /* hack */
- fprintf(out, ">%s\n", line);
- break;
- }
- }
- (void) ascclose(in);
- }
- }
-