home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / com / utils / elm / sources / hdrconfg.c < prev    next >
C/C++ Source or Header  |  1991-01-18  |  10KB  |  368 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: hdrconfg.c,v 4.1.1.2 90/06/05 20:59:30 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.2 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    hdrconfg.c,v $
  17.  * Revision 4.1.1.2  90/06/05  20:59:30  syd
  18.  * Fix log
  19.  *
  20.  * Revision 4.1.1.1  90/06/05  20:58:23  syd
  21.  * Fixes when ALLOW_SUBSHELL #define'd and you are in the
  22.  * Message Header Edit Screen and the mail you just composed
  23.  * is not a reply THEN the subshell command is executed.
  24.  * From: zvr@natasha.cs.wisc.EDU (Alexios Zavras)
  25.  *
  26.  * Revision 4.1  90/04/28  22:43:10  syd
  27.  * checkin of Elm 2.3 as of Release PL0
  28.  *
  29.  *
  30.  ******************************************************************************/
  31.  
  32. /**   This file contains the routines necessary to be able to modify
  33.       the mail headers of messages on the way off the machine.  The
  34.       headers currently supported for modification are:
  35.  
  36.     Subject:
  37.     To:
  38.     Cc:
  39.     Bcc:
  40.     Reply-To:
  41.     Expires:
  42.     Priority:
  43.         In-Reply-To:
  44.     Action:
  45.  
  46.     <user defined>
  47. **/
  48.  
  49. #include "headers.h"
  50.  
  51. #include <ctype.h>
  52.  
  53. #ifdef BSD
  54. #undef toupper
  55. #undef tolower
  56. #endif
  57.  
  58. /*
  59.  * Allow three lines for To and Cc.
  60.  * Allow two lines for Bcc, Subject and In-reply-to.
  61.  * Allow one line for all others.
  62.  */
  63. #define TO_LINE            2
  64. #define CC_LINE                 5
  65. #define BCC_LINE                8
  66. #define SUBJECT_LINE            10
  67. #define REPLY_TO_LINE           12
  68. #define ACTION_LINE             13
  69. #define EXPIRES_LINE            14
  70. #define PRIORITY_LINE           15
  71. #define IN_REPLY_TO_LINE        16
  72. #define USER_DEFINED_HDR_LINE   18
  73. #define INSTRUCT_LINE           LINES-4
  74. #define EXTRA_PROMPT_LINE    LINES-3
  75. #define INPUT_LINE        LINES-2
  76. #define ERROR_LINE        LINES-1
  77.  
  78. static  put_header();
  79.  
  80. #define put_to()        put_header(TO_LINE, 3, "To", expanded_to)
  81. #define put_cc()        put_header(CC_LINE, 3, "Cc", expanded_cc)
  82. #define put_bcc()       put_header(BCC_LINE, 2, "Bcc", expanded_bcc)
  83. #define put_subject()   put_header(SUBJECT_LINE, 2, "Subject", subject)
  84. #define put_replyto()   put_header(REPLY_TO_LINE, 1, "Reply-to", reply_to)
  85. #define put_action()    put_header(ACTION_LINE, 1, "Action", action)
  86. #define put_expires()   put_header(EXPIRES_LINE, 1, "Expires", expires)
  87. #define put_priority()  put_header(PRIORITY_LINE, 1, "Priority", priority)
  88. #define put_inreplyto() put_header(IN_REPLY_TO_LINE, 2, \
  89.                     "In-reply-to", in_reply_to)
  90. #define put_userdefined() put_header(USER_DEFINED_HDR_LINE, 1, \
  91.                     (char *) NULL, user_defined_header)
  92.  
  93. /* these are all defined in the mailmsg file! */
  94. extern char subject[SLEN], in_reply_to[SLEN], expires[SLEN],
  95.             action[SLEN], priority[SLEN], reply_to[SLEN], to[VERY_LONG_STRING],
  96.         cc[VERY_LONG_STRING], expanded_to[VERY_LONG_STRING],
  97.         expanded_cc[VERY_LONG_STRING], user_defined_header[SLEN],
  98.         bcc[VERY_LONG_STRING], expanded_bcc[VERY_LONG_STRING];
  99.  
  100. char *strip_commas(), *strcpy();
  101.  
  102. edit_headers()
  103. {
  104.     /** Edit headers.  **/
  105.     int c, displayed_error = NO;
  106.  
  107.     /*  Expand address-type headers for main part of display */
  108.     /*  (Unexpanded ones are used on the 'edit-line') */
  109.     (void) build_address(strip_commas(to), expanded_to);
  110.     (void) build_address(strip_commas(cc), expanded_cc);
  111.     (void) build_address(strip_commas(bcc), expanded_bcc);
  112.  
  113.     display_headers();
  114.  
  115.     clearerr(stdin);
  116.  
  117.     while (TRUE) {    /* forever */
  118.       PutLine0(INPUT_LINE,0,"Choice: ");
  119.       if (displayed_error)
  120.         displayed_error = NO;
  121.       else
  122.         CleartoEOS();
  123.       c = getchar();
  124.       if (isupper(c))
  125.         c = tolower(c);
  126.       clear_error();
  127.       if (c == EOF)
  128.         return(0);
  129.       switch (c) {
  130.         case RETURN:
  131.         case LINE_FEED:
  132.         case 'q' :  MoveCursor(INSTRUCT_LINE, 0);
  133.             CleartoEOS();
  134.             return(0);
  135.  
  136.         case ctrl('L') :
  137.             display_headers();
  138.             break;
  139.  
  140.         case 't' :  PutLine0(INPUT_LINE, 0, "To: "); CleartoEOLN();
  141.                      if (optionally_enter(to, INPUT_LINE, 4, TRUE, FALSE) == -1)
  142.               return(0);
  143.             (void) build_address(strip_commas(to), expanded_to);
  144.             put_to();
  145.             break;
  146.  
  147.         case 's' :  PutLine0(INPUT_LINE, 0, "Subject: "); CleartoEOLN();
  148.                 if (optionally_enter(subject,
  149.                   INPUT_LINE, 9, FALSE, FALSE) == -1)
  150.               return(0);
  151.             put_subject();
  152.             break;
  153.  
  154.         case 'b' :  PutLine0(INPUT_LINE, 0, "Bcc: "); CleartoEOLN();
  155.                 if (optionally_enter(bcc,
  156.                   INPUT_LINE, 5, TRUE, FALSE) == -1)
  157.               return(0);
  158.             (void) build_address(strip_commas(bcc), expanded_bcc);
  159.             put_bcc();
  160.             break;
  161.  
  162.         case 'c' :  PutLine0(INPUT_LINE, 0, "Cc: "); CleartoEOLN();
  163.                 if (optionally_enter(cc, INPUT_LINE, 4, TRUE, FALSE) == -1)
  164.               return(0);
  165.             (void) build_address(strip_commas(cc), expanded_cc);
  166.             put_cc();
  167.             break;
  168.  
  169.         case 'r' :  PutLine0(INPUT_LINE, 0, "Reply-To: "); CleartoEOLN();
  170.                 if(optionally_enter(reply_to,
  171.                   INPUT_LINE, 10, FALSE, FALSE) == -1)
  172.               return(0);
  173.             put_replyto();
  174.             break;
  175.  
  176.         case 'a' :  PutLine0(INPUT_LINE, 0, "Action: "); CleartoEOLN();
  177.                 if (optionally_enter(action,
  178.                   INPUT_LINE, 8, FALSE, FALSE) == -1)
  179.               return(0);
  180.             put_action();
  181.             break;
  182.  
  183.         case 'p' :  PutLine0(INPUT_LINE, 0, "Priority: "); CleartoEOLN();
  184.                 if (optionally_enter(priority,
  185.                   INPUT_LINE, 10, FALSE, FALSE)==-1)
  186.               return(0);
  187.             put_priority();
  188.             break;
  189.  
  190.         case 'e' :  enter_date(expires);
  191.             put_expires();
  192.             break;
  193.  
  194.         case 'u' :  PutLine0(EXTRA_PROMPT_LINE, 0, "User defined header: ");
  195.             CleartoEOLN();
  196.                 if (optionally_enter(user_defined_header,
  197.                  INPUT_LINE, 0, FALSE, FALSE)==-1)
  198.               return(0);
  199.             check_user_header(user_defined_header);
  200.             put_userdefined();
  201.             ClearLine(EXTRA_PROMPT_LINE);
  202.             break;
  203.  
  204. #ifdef ALLOW_SUBSHELL
  205.         case '!':   if (subshell())
  206.               display_headers();
  207.                 break;
  208. #endif
  209.  
  210.         case 'i' :  if (strlen(in_reply_to) > 0) {
  211.               PutLine0(INPUT_LINE, 0, "In-Reply-To: "); CleartoEOLN();
  212.                       if (optionally_enter(in_reply_to,
  213.                   INPUT_LINE, 13, FALSE, FALSE) == -1)
  214.                 return(0);
  215.               put_inreplyto();
  216.               break;
  217.                }
  218.  
  219.         default  : Centerline(ERROR_LINE, "No such header!");
  220.                displayed_error = YES;
  221.       }
  222.     }
  223. }
  224.  
  225. display_headers()
  226. {
  227.     char buffer[SLEN];
  228.  
  229.     ClearScreen();
  230.  
  231.     Centerline(0,"Message Header Edit Screen");
  232.  
  233.     put_to();
  234.     put_cc();
  235.     put_bcc();
  236.     put_subject();
  237.     put_replyto();
  238.     put_action();
  239.     put_expires();
  240.     put_priority();
  241.     if (in_reply_to[0])
  242.       put_inreplyto();
  243.     if (user_defined_header[0])
  244.       put_userdefined();
  245.  
  246.     strcpy(buffer, "Choose first letter of header, u)ser defined header, ");
  247. #ifdef ALLOW_SUBSHELL
  248.     strcat(buffer, "!)shell, ");
  249. #endif
  250.     strcat(buffer, "or <return>.");
  251.     Centerline(INSTRUCT_LINE, buffer);
  252. }
  253.  
  254. static
  255. put_header(hline, hcount, field, value)
  256. int     hline, hcount;
  257. char    *field, *value;
  258. {
  259.     char    *p;
  260.     int     x, y;
  261.  
  262.     MoveCursor(hline, 0);
  263.  
  264.     if (field) {
  265.       for (p = field; *p; ++p)
  266.         Writechar(*p);
  267.       Writechar(':');
  268.       Writechar(' ');
  269.     }
  270.  
  271.     GetXYLocation(&x, &y);
  272.  
  273.     for (p = value; *p; ++p) {
  274.       if (x >= (hline + hcount))
  275.           break;
  276.       /* neat hack alert -- danger will robinson */
  277.       if ((x + 1) == (hline + hcount)
  278.        && (y + 4) == COLUMNS && strlen(p) > 4)
  279.         p = " ...";
  280.       Writechar(*p);
  281.       ++y;
  282.       if (*p < 0x20 || *p >= 0x7F || y >= COLUMNS)
  283.         GetXYLocation(&x, &y);
  284.     }
  285.  
  286.     if (x < (hline + hcount)) {
  287.       CleartoEOLN();
  288.  
  289.       while (++x < (hline + hcount)) {
  290.         MoveCursor(x, 0);
  291.         CleartoEOLN();
  292.       }
  293.     }
  294. }
  295.  
  296. enter_date(datebuf)
  297. char *datebuf;
  298. {
  299.     /** Enter the number of days this message is valid for, then
  300.         display at (x,y) the actual date of expiration.  This
  301.         routine relies heavily on the routine 'days_ahead()' in
  302.         the file date.c
  303.     **/
  304.  
  305.     int days;
  306.     char numdaysbuf[SLEN];
  307.  
  308.     static char prompt[] =
  309.       "How many days in the future should this message expire? ";
  310.  
  311.     PutLine0(INPUT_LINE,0, prompt);
  312.     CleartoEOLN();
  313.     *datebuf = *numdaysbuf = '\0';
  314.  
  315.     optionally_enter(numdaysbuf, INPUT_LINE, strlen(prompt), FALSE, FALSE);
  316.     sscanf(numdaysbuf, "%d", &days);
  317.     if (days < 1)
  318.       Centerline(ERROR_LINE, "That doesn't make sense!");
  319.     else if (days > 56)
  320.       Centerline(ERROR_LINE,
  321.          "Expiration date must be within eight weeks of today.");
  322.     else {
  323.       days_ahead(days, datebuf);
  324.     }
  325. }
  326.  
  327. check_user_header(header)
  328. char *header;
  329. {
  330.     /** check the header format...if bad print error and erase! **/
  331.  
  332.     register int i = -1;
  333.  
  334.     if (strlen(header) == 0)
  335.        return;
  336.  
  337.     if (whitespace(header[0])) {
  338.       error ("You can't have leading white space in a header!");
  339.       header[0] = '\0';
  340.       ClearLine(USER_DEFINED_HDR_LINE);
  341.       return;
  342.     }
  343.  
  344.     if (header[0] == ':') {
  345.       error ("You can't have a colon as the first character!");
  346.       header[0] = '\0';
  347.       ClearLine(USER_DEFINED_HDR_LINE);
  348.       return;
  349.     }
  350.  
  351.     while (header[++i] != ':') {
  352.       if (header[i] == '\0') {
  353.         Centerline(ERROR_LINE, "You need to have a colon ending the field name!");
  354.         header[0] = '\0';
  355.         ClearLine(USER_DEFINED_HDR_LINE);
  356.         return;
  357.       }
  358.       else if (whitespace(header[i])) {
  359.         Centerline(ERROR_LINE, "You can't have white space imbedded in the header name!");
  360.         header[0] = '\0';
  361.         ClearLine(USER_DEFINED_HDR_LINE);
  362.         return;
  363.       }
  364.     }
  365.  
  366.     return;
  367. }
  368.