home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / library / dos / communic / pcmail / main / reply.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-06-05  |  5.5 KB  |  207 lines

  1. /*++
  2. /* NAME
  3. /*      reply 3
  4. /* SUMMARY
  5. /*      reply to a message
  6. /* PROJECT
  7. /*      pc-mail
  8. /* PACKAGE
  9. /*      mail
  10. /* SYNOPSIS
  11. /*      int reply()
  12. /* DESCRIPTION
  13. /*      reply() is invoked when the user has selected a mail message
  14. /*    and wants to send a reply.
  15. /*
  16. /*    If possible, the reply address and subject are extracted from
  17. /*    the original message file. Reply-To: addresses are given precedence 
  18. /*    over From: addresses.
  19. /*
  20. /*    The reply may include a quoted copy of the body of the original
  21. /*    message.
  22. /*
  23. /*    After editing the reply, the user gets a chance to modify the 
  24. /*    extracted reply address.
  25. /* FILES
  26. /*    mail.msg, file being edited (in current directory)
  27. /*      $MAILDIR/ennnnn, message file (body)
  28. /*    $MAILDIR/cnnnnn, meta file (summary)
  29. /*    $MAILDIR/header, template mail header file
  30. /*    $MAILDIR/trailer, template signature file
  31. /* SEE ALSO
  32. /*      email(3)
  33. /* DIAGNOSTICS
  34. /*      If i/o errors are detected, an error message to that effect is
  35. /*      displayed.
  36. /* BUGS
  37. /*    Only understands From: and Reply-To: addresses. Reply-To: has higher
  38. /*    precedence. No attempt is made to reconstruct BANG paths from 
  39. /*    successive UUCP-style From_ lines.
  40. /* AUTHOR(S)
  41. /*      W.Z. Venema
  42. /*      Eindhoven University of Technology
  43. /*      Department of Mathematics and Computer Science
  44. /*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  45. /* CREATION DATE
  46. /*    Sun Dec 10 15:48:35 MET 1989
  47. /* LAST MODIFICATION
  48. /*    90/01/22 13:02:29
  49. /* VERSION/RELEASE
  50. /*    2.1
  51. /*--*/
  52.  
  53. #include <stdio.h>
  54.  
  55. #include "defs.h"
  56. #include "path.h"
  57. #include "pager.h"
  58. #include "screen.h"
  59. #include "status.h"
  60. #include "mail.h"
  61. #include "ascf.h"
  62. #include "ms_parse.h"
  63.  
  64. /* forward declarations */
  65.  
  66. hidden int make_reply();
  67. hidden int init_reply();
  68. hidden void doquote();
  69. hidden int getsubfrom();
  70.  
  71. hidden char original[BUFSIZ];        /* file name of original message */
  72.  
  73. #define    LINE    256            /* max. line length supported here */
  74.  
  75. hidden char from[LINE];            /* reply address */
  76.  
  77. /* reply - user wants to reply to a message */
  78.  
  79. public int reply()
  80. {
  81.     static Screen screen[] = {
  82.     YESNO,    0,    init_reply, int_error,
  83.     0,    0,    0,
  84.     "Press ESC to cancel. Include original message?",
  85.     };
  86.  
  87.     kbdinp(screen);
  88.     return(S_BREAK);
  89. }
  90.  
  91. /* init_reply - initial reply handling */
  92.  
  93. hidden int init_reply(need_quote)
  94. register int need_quote;
  95. {
  96.     register unsigned msgno;
  97.     register int stat;
  98.  
  99.     strcpy(original, message);            /* keep original message name */
  100.     msgno = newseqno();
  101.     strcpy(message, work_mesg(msgno));        /* create message file name */
  102.     strcpy(comment, work_meta(msgno));        /* create meta file name */
  103.  
  104.     if ((stat = make_reply(need_quote))        /* create template message */
  105.     ||(stat = edit(message, MAILFILE)))    /* and invoke editor */
  106.     errdisp(stat);
  107.     work_disp(from);                /* ask disposition */
  108.     return (S_REDRAW | S_BREAK);        /* say screen was changed */
  109. }
  110.  
  111. /* make_reply - create response file */
  112.  
  113. hidden int make_reply(need_quote)
  114. int     need_quote;
  115. {
  116.     register FILE *out;
  117.     char    subj[LINE];
  118.     int     err;
  119.  
  120.     if (getsubfrom(original, subj, from)) {    /* extract subject and sender */
  121.     return (E_READERR);
  122.     } else if (out = fopen(message, "w")) {    /* build response file */
  123.     (void) fprintf(out, "Subject: Re: %s\n", subj[0] ? subj : "");
  124.     (void) textcopy(header_file(), out);    /* append custom headers */
  125.     (void) putc('\n', out);
  126.     if (need_quote) {
  127.         doquote(original, out);        /* quote original text */
  128.         (void) putc('\n', out);
  129.     }
  130.     (void) textcopy(trailer_file(), out);    /* append custom signature */
  131.  
  132.     err = (fflush(out) || ferror(out));    /* do limited error checking */
  133.     (void) fclose(out);
  134.     return (err ? E_WRITERR : 0);
  135.     } else {
  136.     return (E_WRITERR);
  137.     }
  138. }
  139.  
  140. /* getsubfrom - extract Sender and Subject from original message */
  141.  
  142. hidden int getsubfrom(original, subj, from)
  143. char   *original;
  144. char   *subj;
  145. char   *from;
  146. {
  147.     FILE   *in;
  148.     char    line[LINE];
  149.     int     context = MS_UUCP;
  150.     int     err = 0;
  151.  
  152.     /*
  153.      * Reply-To: addresses have higher precedence than From: addresses. Skip
  154.      * "Re: " at the beginning of a subject.
  155.      */
  156.  
  157.     subj[0] = from[0] = 0;
  158.  
  159.     if (in = ascopen(original, "r")) {
  160.     while ((context != MS_BODY) && ascgets(line, sizeof(line), in)) {
  161.         if ((context = ms_parse(context, line)) == MS_HEADER) {
  162.         /* Process From: only if we did not see Reply-To: */
  163.         if (from[0] == 0
  164.         && !hscanf(line, "From:", " %*[^<] < %[^>]", from))
  165.             (void) hscanf(line, "From:", "%s", from);
  166.         /* Process Reply-To: even if we found a From: address */
  167.         if (!hscanf(line, "Subject: Re:", " %[^\n]", subj)
  168.         && !hscanf(line, "Subject:", " %[^\n]", subj)
  169.         && !hscanf(line, "Reply-To:", " %*[^<] < %[^>]", from))
  170.             (void) hscanf(line, "Reply-To:", " %s", from);
  171.         }
  172.     }
  173.     err = ferror(in);
  174.     (void) ascclose(in);
  175.     }
  176.     return (err);
  177. }
  178.  
  179. /* doquote - quote text from original message */
  180.  
  181. hidden void doquote(original, out)
  182. char   *original;
  183. FILE   *out;
  184. {
  185.     int     context = MS_UUCP;
  186.     char    line[LINE];
  187.     FILE   *in;
  188.  
  189.     /* Suppress the first line of the message body if it is empty. */
  190.  
  191.     if (in = ascopen(original, "r")) {
  192.     while (ascgets(line, sizeof(line), in)) {
  193.         switch (context = ms_parse(context, line)) {
  194.         case MS_BODY:
  195.         context++;            /* hack */
  196.         if (line[0] == 0)        /* hack */
  197.             break;
  198.         /* FALLTHROUGH */
  199.         case MS_BODY + 1:            /* hack */
  200.         fprintf(out, ">%s\n", line);
  201.         break;
  202.         }
  203.     }
  204.     (void) ascclose(in);
  205.     }
  206. }
  207.