home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / uucp / qu2uu_send.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  9.1 KB  |  390 lines

  1. #include "util.h"
  2. #include "mmdf.h"
  3. #include "ch.h"
  4. #include <signal.h>
  5. #include "ap.h"
  6. #include "phs.h"
  7.  
  8. /*
  9.  *                      Q U 2 U U _ S E N D . C
  10.  *
  11.  *                  SEND FROM DELIVER TO UUCP PROGRAMS
  12.  *
  13.  *  The UUCP channel developed for MMDF at the US Army
  14.  *  Ballistics Research Lab by Doug Kingston.    <dpk@brl>
  15.  *
  16.  *                     Original Version 21 Oct 81
  17.  */
  18.  
  19. /*
  20.  *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  21.  *
  22.  *
  23.  *     Department of Electrical Engineering
  24.  *     University of Delaware
  25.  *     Newark, Delaware  19711
  26.  *
  27.  *     Phone:  (302) 738-1163
  28.  *
  29.  *
  30.  */
  31.  
  32. extern    char    *malloc();
  33. extern    char    *rindex();
  34. extern  char    *strdup();
  35. extern  char    *ap_p2s();
  36. extern  char    *multcat();
  37. extern    char    *blt();
  38.  
  39. extern struct ll_struct   *logptr;
  40. extern char *qu_msgfile;          /* name of file containing msg text   */
  41. extern Chan      *curchan;  /* Who we are */
  42.  
  43. LOCFUN qu2uu_each();
  44.  
  45.  
  46. int pbroke;             /* Set if SIGPIPE occurs (in qu2uu_each) */
  47.  
  48. LOCVAR struct rp_construct
  49.     rp_aend =
  50. {
  51.     RP_OK, 'u', 'u', 'c', 'p', ' ', 'e', 'n', 'd', ' ', 'o', 'f', ' ', 'a',
  52.     'd', 'd', 'r', ' ', 'l', 'i', 's', 't', '\0'
  53. },
  54.     rp_mok =
  55. {
  56.     RP_MOK, 'm', 'o', 'k', '\0'
  57. },
  58.     rp_noop =
  59. {
  60.     RP_NOOP, 's', 'u', 'b', '-', 'l', 'i', 's', ' ', 'n', 'o', 't', ' ',
  61.     's', 'p', 'e', 'c', 'i', 'a', 'l', '\0'
  62. },
  63.     rp_ns =
  64. {
  65.     RP_NS, 't', 'e', 'm', 'p', ' ', 'n', 'a', 'm', 'e', 's', 'e', 'r', 'v',
  66.     'e', 'r', ' ', 'f', 'a', 'i', 'l', 'u', 'r', 'e', '\0'
  67. },
  68.     rp_err =
  69. {
  70.     RP_NO, 'u', 'n', 'k', 'n', 'o', 'w', 'n', ' ', 'e', 'r', 'r', 'o', 'r', '\0'
  71. },
  72.     rp_pipe =
  73. {
  74.     RP_NO, 'u', 'u', 'x', ' ', 'p', 'i', 'p', 'e', ' ',
  75.     'b', 'r', 'o', 'k', 'e', ' ', '(', 's', 'y', 's', 't', 'e', 'm', ' ',
  76.     'u', 'n', 'k', 'n', 'o', 'w', 'n', '?', ')', '\0'
  77. },
  78.     rp_bhost =
  79. {
  80.     RP_USER, 'b', 'a', 'd', ' ', 'h', 'o', 's', 't', ' ', 'n', 'a',
  81.     'm', 'e', '\0'
  82. };
  83.  
  84. /* */
  85.  
  86. qu2uu_send ()                     /* overall mngmt for batch of msgs    */
  87. {
  88.     short   result;
  89.     char    *findfrom();
  90.     char    *realfrom;
  91.     char    info[LINESIZE],
  92.         sender[ADDRSIZE];
  93.  
  94. #ifdef DEBUG
  95.     ll_log (logptr, LLOGBTR, "qu2uu_send ()");
  96. #endif
  97.  
  98.     if (rp_isbad (result = qu_pkinit ()))
  99.     return (result);
  100.  
  101.     /*
  102.      *  AP_SAME == NO header munging.  We need to read the header
  103.      *  ourselves and the munging just gets in the way.
  104.      */
  105.     for(;;){        /* get initial info for new message   */
  106.     result = qu_rinit (info, sender, curchan -> ch_apout);
  107.     if(rp_gval(result) == RP_NS){
  108.         qu_rend();
  109.         continue;
  110.     }
  111.     if(rp_gval(result) == RP_DONE)
  112.         break;
  113.     if (rp_gval(result) == RP_FIO)          /* Can't open message file */
  114.         continue;
  115.     else if (rp_gval(result) != RP_OK)      /* Some other error */
  116.         break;
  117.     phs_note (curchan, PHS_WRSTRT);
  118.  
  119.     printx ("\r\nReformatting message from %s (%s)\r\n", sender, info);
  120.     realfrom = findfrom (sender);
  121.     if(realfrom == (char *)MAYBE){
  122.         result = RP_NS;
  123.         break;
  124.     }
  125.     printx ("Realfrom is '%s'\r\n", realfrom);
  126.  
  127.     if (rp_isbad (result = qu2uu_each (sender, realfrom)))
  128.         return (result);      /* process each adrlst/text pair     */
  129.     qu_rend();
  130.     }
  131.     qu_rend();
  132.  
  133.     if (rp_gval (result) == RP_NS)
  134.     {
  135.     ll_log (logptr, LLOGTMP, "Nameserver failure");
  136.     return (RP_NS);           /* catch protocol errors              */
  137.     }
  138.     if (rp_gval (result) != RP_DONE)
  139.     {
  140.     ll_log (logptr, LLOGTMP, "not DONE (%s)", rp_valstr (result));
  141.     return (RP_RPLY);         /* catch protocol errors              */
  142.     }
  143.  
  144.     qu_pkend ();                  /* done getting messages              */
  145.     phs_note (curchan, PHS_WREND);
  146.  
  147.     return (result);
  148. }
  149. /* */
  150.  
  151. LOCFUN
  152.     qu2uu_each (sender, realfrom)   /* generate a UUX for an address */
  153.     char *sender;
  154.     char      *realfrom;
  155. {
  156.     RP_Buf    replyval;
  157.     short     result;
  158.     char      host[ADDRSIZE];
  159.     char      adr[ADDRSIZE];
  160.     extern sigtype brpipe();
  161.     sigtype   (*oldsig)();
  162.  
  163. #ifdef DEBUG
  164.     ll_log (logptr, LLOGBTR, "qu2uu_each()");
  165. #endif
  166.  
  167.     FOREVER                       /* iterate thru list                    */
  168.     {                             /* we already have and adr              */
  169.     result = qu_radr (host, adr);
  170.     if (rp_isbad (result))
  171.         return (result);      /* get address from Deliver           */
  172.     if (rp_gval (result) == RP_HOK)
  173.     {
  174.         qu_wrply ((RP_Buf *) &rp_noop, sizeof rp_noop);
  175.         continue;
  176.     }
  177.     else if (rp_gval (result) == RP_DONE)
  178.     {
  179.         qu_wrply ((RP_Buf *) &rp_aend, sizeof rp_aend);
  180.         return (RP_OK);       /* end of address list                */
  181.     }
  182.  
  183.     /*
  184.      *  Following function takes     (name+host)     and
  185.      *  looks up a!b!c!host then puts "a" in host and
  186.      *  "b!c!name" in the adr.
  187.      */
  188.     pbroke = 0;
  189.     oldsig = signal(SIGPIPE, brpipe);
  190.     replyval.rp_val = uu_wtadr (host, adr, sender, realfrom);
  191.     switch (replyval.rp_val)
  192.     {
  193.         case RP_AOK:
  194.         case RP_OK:
  195. #ifdef DEBUG
  196.         ll_log (logptr, LLOGFTR, "Calling txtcpy()\n");
  197. #endif
  198.         replyval.rp_val = uu_txtcpy();
  199.         break;
  200.  
  201.         case RP_USER:
  202.         ll_log (logptr, LLOGFAT, "host (%s) not in table", host);
  203.         blt((char *)&rp_bhost, (char *) &replyval, sizeof rp_bhost);
  204.         break;
  205.  
  206.         case RP_NS:
  207.         ll_log (logptr, LLOGTMP, "nameserver failure in host lookup");
  208.         blt((char *)&rp_ns, (char *) &replyval, sizeof rp_ns);
  209.         break;
  210.  
  211.         default:
  212.         ll_log (logptr,LLOGFAT,"unknown error (0%o)", replyval.rp_val);
  213.         blt((char *)&rp_err, (char *) &replyval, sizeof rp_err);
  214.         replyval.rp_val = RP_NO;
  215.     }
  216.     if (replyval.rp_val != RP_MOK) {
  217.         qu_wrply (&replyval, sizeof(replyval.rp_val)
  218.               + strlen(replyval.rp_line));
  219.     } else {
  220.         replyval.rp_val = uu_wttend();
  221.         switch (replyval.rp_val) {
  222.             case RP_AOK:
  223.             case RP_OK:
  224.             case RP_MOK:
  225.             qu_wrply ((RP_Buf *)&rp_mok, sizeof rp_mok);
  226.             break;
  227.  
  228.             case RP_USER:
  229.             ll_log (logptr, LLOGFAT, "host (%s) not in table", host);
  230.             qu_wrply ((RP_Buf *)&rp_bhost, sizeof rp_bhost);
  231.             break;
  232.  
  233.             case RP_LIO:
  234.             ll_log (logptr,LLOGTMP,"uux pipe broke (unknown?)");
  235.             qu_wrply ((RP_Buf *)&rp_pipe, sizeof rp_pipe);
  236.             break;
  237.  
  238.             default:
  239.             ll_log (logptr,LLOGFAT,"unknown error on close (0%o)", replyval.rp_val);
  240.             qu_wrply ((RP_Buf *)&rp_err, sizeof rp_err);
  241.         }
  242.     }
  243.     signal(SIGPIPE, oldsig);
  244.     }
  245. }
  246.  
  247. sigtype
  248. brpipe()
  249. {
  250.     pbroke = 1;
  251.     signal(SIGPIPE, SIG_IGN);
  252. }
  253.  
  254. /**** ****/
  255.  
  256. /*
  257.  *      This function probably should be an address parser
  258.  *      but for now this will have to do.  -DPK-
  259.  *
  260.  *      Simple address parser use inserted by smb.
  261.  */
  262. extern int ap_outtype;
  263. extern AP_ptr ap_normalize ();
  264.  
  265. char *
  266. findfrom (sender)
  267. char *sender;
  268. {
  269.     int     aptypesav;
  270.     char    *adr;
  271.     register char    *p;
  272.     AP_ptr  ap;
  273.     AP_ptr  local,
  274.         domain,
  275.         route;
  276.     char    *MakeUucpFrom();
  277.  
  278. /* SEK have axed looking at top of file.  */
  279. /* This may not be wise - but very much neater */
  280. /* Delver has no business being given UUCP style messsages */
  281.  
  282.     if ((ap = ap_s2tree (sender)) == (AP_ptr) NOTOK)
  283.     {
  284.         ll_log (logptr, LLOGTMP, "Failure to parse address '%s'", sender);
  285.         return (strdup (sender));
  286.     }
  287.  
  288.     ap = ap_normalize (curchan -> ch_lname, curchan -> ch_ldomain,
  289.         ap, curchan);
  290.     if(ap == (AP_ptr)MAYBE)
  291.         return( (char *)MAYBE);
  292.     ap_t2parts (ap, (AP_ptr *) 0, (AP_ptr *) 0, &local, &domain, &route);
  293.     aptypesav = ap_outtype;
  294.     ap_outtype = AP_733;
  295.     adr = ap_p2s ((AP_ptr) 0, (AP_ptr) 0, local, domain, route);
  296.     if(adr == (char *)MAYBE){
  297.         ap_outtype = aptypesav;
  298.         return(adr);
  299.     }
  300.     if ((route == (AP_ptr) 0))
  301.     {
  302.         p = multcat (curchan -> ch_lname, ".",
  303.                 curchan -> ch_ldomain, (char *)0);
  304.         if (lexequ (p, domain -> ap_obvalue))
  305.         {
  306.             free (adr);
  307.             adr = strdup (local -> ap_obvalue);
  308.         }
  309.         free (p);
  310.     }
  311.     ll_log (logptr, LLOGFST, "sender = '%s'", adr);
  312.     ap_outtype = aptypesav;
  313.  
  314.     lowerfy(adr);
  315.     return(MakeUucpFrom(adr));
  316. }
  317.  
  318. /*
  319.  * This added by pc (UKC) to generate correct 'From' lines with
  320.  * `!' separated routes for uucp sites
  321.  * the rules
  322.  *     a@b   -> b!a
  323.  *    a%b@c -> c!b!a
  324.  *    etc
  325.  *    a%b%c%d%e@x -> x!e!d!c!b!a
  326.  *    This is done by a call to a recursive routine which I hope is OK
  327.  */
  328. static
  329. char *
  330. MakeUucpFrom(adr)
  331. char *adr;
  332. {    char *new;
  333.     char *localname;
  334.     register char *site;
  335.     
  336.     /*NOSTRICT*/
  337.     if ((new = malloc(strlen(adr)+1)) == (char *)0)
  338.         return ((char *)NOTOK);
  339.     /*
  340.      * Can we assume that this is a legal 733 address ?
  341.      * look for the first site
  342.      */
  343.     site = rindex(adr, '@');
  344.     if (site)
  345.     {    *site++ = '\0';
  346.         /*
  347.          * some input channels (notably ni_niftp) will add the
  348.          * name of the local machine into this address
  349.          * so we look for it and delete it if found
  350.          */
  351.         localname = multcat(curchan->ch_lname, ".", curchan->ch_ldomain, 0);
  352.         /*
  353.          * if not the same then put back a % to let ScanUucpFrom work
  354.          */
  355.         if (!lexequ (localname, site))
  356.             site[-1] = '%';
  357.         free(localname);
  358.     }
  359.     ScanUucpFrom(new, adr);
  360.     free(adr);
  361. #ifdef DEBUG
  362.     ll_log (logptr, LLOGBTR, "sender (From line) = '%s'", new);
  363. #endif
  364.       return(new);
  365. }
  366.  
  367. static
  368. ScanUucpFrom(new, adr)
  369. register char *new;
  370. register char *adr;
  371. {    register char *site;
  372.     char    *rindex();
  373.  
  374.     /*
  375.      * This presumes that the address we are scanning is somewhat
  376.      * legal - but the @ has been replaced by a %
  377.      */
  378.     site = rindex(adr, '%');
  379.     if (site == (char *)0)
  380.     {    (void) strcpy(new, adr);
  381.         return;
  382.     }
  383.     *site++ = '\0';
  384.     (void) strcpy(new, site);
  385.     new += strlen(site);
  386.     *new++ = '!';
  387.     *new = '\0';
  388.     ScanUucpFrom(new, adr);
  389. }
  390.