home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1426 < prev    next >
Internet Message Format  |  1990-12-28  |  6KB

  1. From: taylor@limbo.Intuitive.Com (Dave Taylor)
  2. Newsgroups: alt.sources,comp.mail.sendmail,comp.mail.uucp
  3. Subject: Sendmail/UUCP hack for domain qualified UUCP sites
  4. Message-ID: <810@limbo.Intuitive.Com>
  5. Date: 6 Jun 90 18:16:49 GMT
  6.  
  7. As a site that has a real domain name but UUCP only connectivity, I
  8. have been continually frustrated by the mismatch of the abilities of
  9. the Sendmail program and the needs of the UUX portion of UUCP.  In a
  10. nutshell, to have "domain-ized" email come from my site, I need to
  11. have the message queued in UUCP with the following format:
  12.  
  13.     From <username> <date> remote from <hostname>
  14.     From: <username>@<qualified.hostname> (<fullname>)
  15.  
  16. Problem is, "sendmail" wants to have the 'username' in the first From_
  17. line match the 'username@<qualified.hostname>' in the second.  The
  18. bigger problem on top of that is that uux absolutely insists on either
  19. the "remote from host" format, or having a "hostname!" prefix on the
  20. address in the From_ line.  
  21.  
  22. The easy solution, of course, is to have "sendmail" output the common
  23. address as "hostname!user@qualified-hostname", but, frankly, I think
  24. that email addresses like "limbo!taylor@limbo.intuitive.com" look 
  25. quite terrible!
  26.  
  27. Instead, what I did as a Unix style hack was to teach "sendmail" to 
  28. deliver UUCP mail to a different program instead of "uux"; the
  29. program attached below, called "uux.filter".  The "sendmail.cf" file
  30. was hacked on a bit so that it now *doesn't* think that "uux" is a
  31. UUCP style mailer (e.g the "U" flag in the "F=" mailer definition)
  32. and so that it just uses domain style "user@host.domain" addresses
  33. for both the From: and From_ lines.
  34.  
  35. So what ends up happening is that a typical message comes out of
  36. "sendmail" like:
  37.     
  38.     From taylor@limbo.intuitive.com <date>
  39.     From: taylor@limbo.intuitive.com (Dave Taylor)
  40.     Subject: hi
  41.  
  42. and then "uux.filter" rewrites it as:
  43.  
  44.     From taylor <date> remote from limbo
  45.     From: taylor@limbo.intuitive.com (Dave Taylor)
  46.     Subject: hi
  47.  
  48. and hands it to the real "uux" program.  End result: "uux" and the
  49. entire "uucp" package is happy, *and* we end up with nice looking
  50. From: addresses without mixed mode, redundant hostname addresses.
  51.  
  52. The modification to my "sendmail.cf" file is on the two mailer definition
  53. lines below - note the P= value and the F= flags...
  54.  
  55.   ############################################################
  56.   ###                   UUCP mailer                        ###
  57.   ############################################################
  58.  
  59.   Muucp, P=/usr/bin/uux.filter,  F=DFMshu,   S=13, R=23, A=uux - $h!rmail ($u)
  60.  
  61.   S13
  62.   R$+<@$+.UUX>        $@$2!$1<@$H.UUX>    host!user => my_host!host!user 
  63.   R$+<@$+>        $@$1%$2<@$j>        user@host => user%host@my_host
  64.   R<@$+>:$+        $@<@$j>:@$1:$2        prepend @my_host to route
  65.   R$+            $@$1<@$j>        user => user@my_host
  66.  
  67.   S23
  68.  
  69.   ############################################################
  70.   ###                Dumb UUCP mailer                      ###
  71.   ############################################################
  72.  
  73.   Mdumbuucp,  P=/usr/bin/uux.filter,  F=DMshux,  R=23, A=uux - $h!rmail ($u)
  74.  
  75. As you can see, we simply "stick it in the middle".
  76.  
  77.             Enjoy!
  78.                         -- Dave Taylor
  79.  
  80.                         taylor@limbo.intuitive.com
  81.  
  82. -- Attachment: "uux.filter.c"
  83.  
  84. /**                uux.filter.c                **/
  85.  
  86. /** A simple program that puts itself in front of the standard "uux" command 
  87.     to allow us to have non-UUCP style messages come from "sendmail" and end 
  88.     up, correctly formatted, in the UUCP outbound queue.  Note that the "real" 
  89.     uux is still used; we just expect "sendmail" to call us instead.
  90.  
  91.     The fixing up involved in this program is simply to change the format of 
  92.     the "From " line to ensure that it ends with the suffix of "remote from 
  93.     HOSTNAME".
  94.  
  95.     (C) Copyright 1990, Dave Taylor, Intuitive Systems.
  96.  
  97.     Distribution of any nature allowed as long as this header is retained
  98.     without modification.
  99.  
  100.     Compile with: "cc -O uux.filter.c -o uux.filter" and then fix your
  101.     "sendmail.cf" UUCP mailer definition to know about it.
  102. **/
  103.  
  104. /** include the following if you're debugging your installation... 
  105.  
  106. #define DEBUGGING
  107.  
  108. **/
  109.  
  110. #include <stdio.h>
  111. #include <errno.h>
  112. #include <ctype.h>
  113.  
  114. #define REAL_UUX    "/usr/bin/uux"
  115. #define TEMPFILE    "/tmp/uux.fix.%d"
  116.  
  117. /** the following should be changed to reflect your own site values! **/
  118.  
  119. #define HOSTNAME    "limbo"
  120. #define TO_STRIP    "@limbo.intuitive.com"
  121.  
  122. /** compares in a case-independent way... **/
  123.  
  124. #define same_char(c,d)    (c == d || c == isupper(d) ? tolower(d) : d ||  \
  125.              d == isupper(c) ? tolower(c) : c)
  126.  
  127. extern int errno;
  128.  
  129. main(argc, argv)
  130. int argc;
  131. char **argv;
  132. {
  133.     FILE   *pipe_to_uux;
  134.     char   uux_command[4096];
  135.     char   buffer[256];
  136.  
  137.     /** build up the command to the real uux program **/
  138.  
  139.     argv++;
  140.     strcpy(uux_command, REAL_UUX);
  141.  
  142.     while (--argc) {            /* grab args.. */
  143.       strcat(uux_command, " '");        /*   and quote */
  144.       strcat(uux_command, *argv++);        /*     them!   */
  145.       strcat(uux_command, "'");
  146.     }
  147.  
  148.     /** now let's try to open a write-only pipe to "uux" **/
  149.  
  150.     if ((pipe_to_uux = popen(uux_command, "w")) == NULL) {
  151.        printf("uux.filter: failed trying to popen(%s) error=%d\n", 
  152.            uux_command, errno);
  153.        exit(1);    /* This will cause a sendmail bounce messsage */
  154.     }
  155.     else {
  156.       while (gets(buffer) != NULL) {
  157.         if (strncmp(buffer, "From ", 5) == 0) {
  158.           fix_buffer(buffer);
  159.           fprintf(pipe_to_uux, "%s remote from %s\n", buffer, HOSTNAME);
  160.         }
  161.         else
  162.           fprintf(pipe_to_uux, "%s\n", buffer);
  163.       }
  164.       pclose(pipe_to_uux);
  165.     }
  166.  
  167. #ifdef DEBUGGING
  168.     printf("uux.filter: delivered message to '%s'\n", uux_command);
  169. #endif
  170.  
  171.     exit(0);
  172. }
  173.  
  174. fix_buffer(buffer)
  175. char *buffer;
  176. {
  177.     /** Given a buffer of the form "From user@host <DATE>" return
  178.         it as "From user <DATE>"  We do this by stripping out the
  179.         @host field; but only iff it matches our "TO_STRIP" value
  180.         as we go along.  As soon as it fails, we'll bail!
  181.     **/
  182.  
  183.     char ourbuffer[256];
  184.     register int i, j = 0, k=1;
  185.     int  skip = 0;
  186.  
  187.     for (i = 0; buffer[i] != 0; i++) {
  188.       if (buffer[i] == '@')         skip = 1;
  189.       if (buffer[i] == ' ' && skip) skip = 0;
  190.  
  191.       if (! skip) 
  192.         ourbuffer[j++] = buffer[i];
  193.       else
  194.        if (! same_char(buffer[i], TO_STRIP[k])) {    /* they don't match */
  195. #ifdef DEBUGGING
  196.          printf("uux.filter: fields '%s' and '%s' diverge at char %d/%d\n",
  197.              buffer, TO_STRIP, i, k);
  198. #endif
  199.          return;
  200.        }
  201.     }
  202.  
  203.     ourbuffer[j] = 0;
  204.  
  205.     strcpy(buffer, ourbuffer);
  206. }
  207.  
  208. /** end of program listing **/
  209.