home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / niftp / qn_rdmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-11  |  12.3 KB  |  494 lines

  1. /*                                                                      */
  2. /*                  CH_QNIFTP: NIFTP MAIL RECEIVER CHANNEL              */
  3. /*                                                                      */
  4. /*      Developed originally by Chris Bennett - May 1981                */
  5. /*                                                                      */
  6. /*      Rewritten completely by Steve Kille - August 1982               */
  7.  
  8. #include "util.h"
  9. #include "mmdf.h"
  10. #include "ap.h"
  11. #include "ch.h"
  12. #include "dm.h"
  13.  
  14. extern struct ll_struct   *logptr;
  15.  
  16. extern Chan *curchan;
  17.  
  18. extern Table *tb_nm2struct();
  19. extern Chan *ch_nm2struct();
  20. extern Domain *dm_v2route();
  21. extern char *ap_dmflip();
  22. extern char *ap_p2s();
  23.  
  24. extern qn_rdchar ();
  25.  
  26. LOCVAR  FILE    *qn_fp;         /* File pointer for current file        */
  27. LOCVAR  long    curpos;         /* Current position in file             */
  28. LOCVAR  char    eoheader;       /* Have we reached end of JNT header    */
  29. LOCVAR  char    adr_keyend[] = "\r\n,\377";
  30.                 /* Set of characters terminating JNT    */
  31.                 /* Mail address                         */
  32. LOCVAR  char    *ack_adr;       /* acknowlege-to address                */
  33.  
  34. LOCVAR  char    qn_nichanlist [LINESIZE]; /* list of valid channels     */
  35.  
  36. /*
  37. */
  38. qn_init (ni_queue)              /* Initialise channel                   */
  39.                 /* No-op                                */
  40. char    *ni_queue;              /* NIFTP queue associated with channel  */
  41. {
  42.     Table *tb_niftp;
  43.  
  44. #ifdef DEBUG
  45.     ll_log (logptr, LLOGBTR, "qn_init (%s)", ni_queue);
  46. #endif
  47.  
  48.     if ((tb_niftp = tb_nm2struct ("niftp.nets")) == (Table *) NOTOK)
  49.     {
  50.     ll_err (logptr, LLOGTMP, "Failure to locate NIFTP net table");
  51.     return (RP_NO);
  52.     }
  53.                 /* Extract name of current channel      */
  54.                 /* from list of NIFTP channels          */
  55.     if (tb_k2val (tb_niftp, TRUE, ni_queue, qn_nichanlist)!=OK)
  56.     {
  57.     ll_err (logptr, LLOGFAT, "Unknown NIFTP queue \"%s\"", ni_queue );
  58.     return (RP_PARM);
  59.                 /* all NIFTP channels should be in the  */
  60.                 /* mapping table - if not then error    */
  61.     }
  62.  
  63.     return (RP_OK);
  64. }
  65.  
  66. qn_end (state)                  /* Terminate channel                    */
  67. int state;                      /* No-op                                */
  68. {
  69. #ifdef DEBUG
  70.     ll_log (logptr, LLOGBTR, "qn_end (%d)", state);
  71. #endif
  72.     return (RP_OK);
  73. }
  74.  
  75. qn_pkinit ()                    /* Initialise for batch submission      */
  76.                 /* Not now, but perhaps later on again  */
  77.                 /* when NIFTP is working properly       */
  78.                 /* No-op                                */
  79. {
  80. #ifdef DEBUG
  81.     ll_log (logptr, LLOGBTR, "qn_pkinit ()");
  82. #endif
  83.     return (RP_OK);
  84. }
  85.  
  86. qn_pkend ()                     /* End batch submission                 */
  87.                 /* No-op                                */
  88. {
  89. #ifdef DEBUG
  90.     ll_log (logptr, LLOGBTR, "qn_pkend ()");
  91. #endif
  92.     return (RP_OK);
  93. }
  94.  
  95. /*
  96. */
  97.                 /* Initialise for processing message    */
  98. qn_rinit (fname, TSname, info, sender)
  99. char    *fname;                 /* Name of file containing JNT message  */
  100. char    *TSname;                /* TS name of calling host              */
  101. char    *info;                  /* place to stuff info                  */
  102. char    *sender;                /* place to stuff name of message sender*/
  103. {
  104.      char       *reverse;       /* Pointer to reverse ordered domain    */
  105.      char       tmpstr [LINESIZE];
  106.      char       official [LINESIZE];
  107.      Dmn_route  route;
  108.      char       chan_buf [LINESIZE];
  109.      int        argc, n;
  110.      char       *argv[20];      /* lots of channels */
  111.  
  112. #ifdef DEBUG
  113.     ll_log (logptr, LLOGBTR, "qn_rinit (%s, %s)", fname, TSname );
  114. #endif
  115.  
  116.     rtn_init ();
  117.     ack_adr = (char *) 0;
  118.  
  119.     reverse = ap_dmflip (TSname);
  120.     official [0] = 0;
  121.  
  122.     strcpy (chan_buf, qn_nichanlist);
  123.     if ((argc = str2arg (chan_buf, 20, argv, (char *)0)) == NOTOK)
  124.     {
  125.     ll_err (logptr, LLOGFAT, "qn_rinit: str2arg failed '%s'", chan_buf);
  126.     return (RP_LIO);
  127.     }
  128.     for ( n = 0 ; n < argc ; n++)
  129.     {
  130.     if ((curchan = ch_nm2struct (argv[n])) == (Chan *) NOTOK)
  131.     {
  132.         ll_err (logptr, LLOGTMP, "qn_rinit: Bad channel '%s'", argv[n]);
  133.         continue;
  134.     }
  135.  
  136.             /* See if we know it, NRS order first    */
  137.     if (tb_k2val (curchan -> ch_table, TRUE, reverse, tmpstr)==OK)
  138.     {
  139.         /* should check return value ?? */
  140.         dm_v2route (reverse, official, &route);
  141.         sprintf (info, "h%s*", official);
  142.         break;
  143.     }
  144.     else if (tb_k2val (curchan -> ch_table, TRUE, TSname, tmpstr)==OK)
  145.     {
  146.         /* should check return value ?? */
  147.         dm_v2route (TSname, official, &route);
  148.         sprintf (info, "h%s*", official);
  149.         break;
  150.     }
  151.     }
  152.                 /* Strip "," and "*" from host name     */
  153.                 /* as it may be TS name with funnies    */
  154.                 /* we might as well munge this!!        */
  155.     if (official [0] == '\0')
  156.     {
  157.     ll_err (logptr, LLOGTMP, "qnrinit: Unknown source address '%s'",TSname);
  158.     return (RP_NDEL);
  159.     }
  160.  
  161. #ifdef DEBUG
  162.     ll_log (logptr, LLOGFTR, "We are channel '%s'", curchan -> ch_name);
  163. #endif
  164.     free (reverse);
  165.     ch_llinit(curchan);
  166.  
  167. #ifdef DEBUG
  168.     ll_log (logptr, LLOGFTR, "Info string is \"%s\"", info);
  169. #endif
  170.  
  171.                 /* Now open up the message file         */
  172.  
  173.     if ((qn_fp = fopen (fname, "r")) == NULL )
  174.     {
  175.     ll_err (logptr, LLOGTMP, "can't open file '%s'",
  176.                 fname);
  177.     return (RP_FIO);
  178.     }
  179.  
  180.                 /* Extract sender name from text        */
  181.                 /* This is pretty ugly, but the best    */
  182.                 /* That JNT mail can do                 */
  183.                 /* If there is no sender field valid    */
  184.                 /* dont worry about it                  */
  185.     sender [0] = '\0';
  186.     if (rp_isbad(hdr_sender (sender, &ack_adr, qn_fp, official)))
  187.     return (RP_NDEL);
  188.                 /* now return to the start of the file  */
  189.  
  190.     ll_log (logptr, LLOGFST, "sender: '%s'", sender);
  191.  
  192.     fseek (qn_fp, 0L, 0);
  193.     if (ferror (qn_fp))
  194.     {
  195.     ll_err (logptr, LLOGTMP, "Fail to seek on file '%s'", fname);
  196.     return (RP_FIO);
  197.     }
  198.     curpos = 0;                 /* mark postition                       */
  199.  
  200.     eoheader = FALSE;           /* ready to read JNT header             */
  201.  
  202.     return (RP_OK);
  203. }
  204. /*
  205. */
  206. extern char *rindex ();
  207.  
  208. qn_radr (host, adr)             /* extract next address from file       */
  209.                 /* might get confused by very badly     */
  210.                 /* damaged files                        */
  211. char    *host;
  212. char    *adr;
  213. {
  214.     char        *strptr;
  215.     char        *cp;
  216.     AP_ptr      local,          /* pointers for parse coponents         */
  217.         domain,
  218.         route;
  219.     AP_ptr      ptr;
  220.     AP_ptr      ap;
  221.  
  222. #ifdef DEBUG
  223.     ll_log (logptr, LLOGBTR, "qn_radr ()");
  224. #endif
  225.  
  226.     if ((ptr = ap_pinit (qn_rdchar)) == (AP_ptr) NOTOK)
  227.     {
  228.     ll_err (logptr, LLOGTMP, "Problem initialising for parse");
  229.     return (RP_LIO);
  230.     }
  231.  
  232. #ifdef DEBUG
  233.      ll_log (logptr, LLOGFTR, "Parse corectly initialised");
  234. #endif
  235.  
  236.     switch ( ap_1adr ())
  237.     {
  238.     case NOTOK:
  239.         ap_free (ptr);
  240.         ll_log (logptr, LLOGFAT, "Bad format address in JNT header");
  241.         return (RP_HUH);
  242.     case DONE:
  243.         ap_free (ptr);
  244.         return (RP_DONE);   /* end of address list                  */
  245.     }
  246.  
  247.                 /* Now analyse address                  */
  248.  
  249.     ap_t2parts (ptr, (AP_ptr *) 0, (AP_ptr *) 0, &local, &domain, &route);
  250.                 /* remove any trailing DLIT          */
  251.     if (route == (AP_ptr) 0)
  252.     {
  253.     if (domain ->  ap_obtype == APV_DLIT)
  254.     {
  255.         ap_free (domain);
  256.         domain = (AP_ptr) 0;
  257.     }
  258.     }
  259.     else
  260.     {
  261.     if (route -> ap_obtype == APV_DLIT)
  262.     {
  263.         ap = route;
  264.         route = ap -> ap_chain;
  265.         if (route -> ap_obtype != APV_DLIT ||
  266.         route ->  ap_obtype != APV_DOMN)
  267.         route = (AP_ptr) 0;
  268.         ap_free (ap);
  269.     }
  270.     }
  271.  
  272.     strptr = ap_p2s ((AP_ptr) 0, (AP_ptr) 0, local, domain, route);
  273.     if(strptr == (char *)MAYBE)
  274.     return(RP_NS);
  275.  
  276. #ifdef DEBUG
  277.     ll_log (logptr, LLOGBTR, "Full address is '%s'", strptr);
  278. #endif
  279.     strcpy (adr, strptr);
  280.     cp = rindex (adr, '@');
  281.     if (cp == (char *) 0)
  282.     host [0] = '\0';
  283.     else
  284.     {
  285.     *cp  = '\0';
  286.     strcpy (host, ++cp);
  287.     }
  288.     free (strptr);
  289.  
  290.     ll_log (logptr, LLOGFST, "JNT Address h='%s', a='%s'", host, adr);
  291.     return (RP_AOK);
  292. }
  293.  
  294.  
  295. /*
  296. */
  297. qn_raend ()                      /* Reached end of address list          */
  298.                 /* skip ofver any LWSP before 733 header*/
  299. {
  300.     int         c;
  301.  
  302. #ifdef DEBUG
  303.     ll_log (logptr, LLOGBTR, "qn_raend ()");
  304. #endif
  305.  
  306.     FOREVER
  307.     {
  308.     if ((c = getc (qn_fp)) == EOF)
  309.     {
  310.         ll_err (logptr, LLOGTMP, "JNT mail header with no body" );
  311.         return (RP_NO);
  312.     }
  313.     curpos++;
  314.     if (!isspace (c))       /* reached start of 733 header          */
  315.     {
  316.         fseek (qn_fp, --curpos, 0);
  317.                 /* set back one character               */
  318.         if (ferror (qn_fp))
  319.         return (RP_FIO);
  320.         return (RP_OK);
  321.     }
  322.     }
  323. }
  324. /*
  325. */
  326. qn_wrply (reply, adr, host)     /* Used to mark status of address       */
  327.                 /* If reply is bad, passed downwards    */
  328.                 /* to build up list of erroneous        */
  329.                 /* addresses to be passed back          */
  330. struct rp_bufstruct  *reply;
  331. char    *adr,
  332.     *host;
  333. {
  334.     char   line[LINESIZE];
  335. #ifdef DEBUG
  336.     ll_log (logptr, LLOGBTR, "qn_wrply ()");
  337. #endif
  338.  
  339.     if (rp_isgood (reply -> rp_val))
  340.     {
  341.     sprintf (line, "%s@%s", adr, host);
  342.     return (rtn_adr (line, TRUE));
  343.     }
  344.     else
  345.     {
  346.     strcpy (line, reply -> rp_line);
  347.     return (rtn_adr (line, FALSE));
  348.     }
  349.  
  350. }
  351. /*
  352. */
  353. qn_rtxt (buffer, len)             /* read buffered block of text        */
  354. char   *buffer;                   /* where to stuff next part of text   */
  355. int    *len;                      /* where to stuff length of part      */
  356. {
  357. #ifdef DEBUG
  358.     ll_log (logptr, LLOGBTR, "qn_rtxt ()");
  359. #endif
  360.  
  361.  
  362.     switch (*len = gcread (qn_fp, buffer, *len - 1, "\n\000\377"))
  363.     {                             /* raw read of the file               */
  364.     case NOTOK:
  365.         ll_err (logptr, LLOGFAT, "File read error");
  366.         return (RP_FIO);
  367.  
  368.     case OK:                  /* end of message; not treated as EOF */
  369. #ifdef DEBUG
  370.         ll_log (logptr, LLOGBTR, "qn_rtxt (DONE)");
  371. #endif
  372.         return (RP_DONE);
  373.     }
  374.     switch (*len)
  375.     {
  376.     case 0:
  377.         return (RP_DONE);
  378.  
  379.     case 1:
  380.         if (isnull (buffer[0]))
  381.         return (RP_DONE);
  382.     }
  383.     buffer[*len] = '\0';          /*   so it can be ll_loged as a string  */
  384. #ifdef DEBUG
  385.     ll_log (logptr, LLOGFTR, "\"%s\"", buffer);
  386. #endif
  387.     return (RP_OK);
  388. }
  389. /* */
  390. extern char *supportaddr;
  391.  
  392. qn_rtend (sender, fname, alright)
  393.                 /* finished reading text - close file      */
  394.                 /* send off error message                  */
  395. char    *sender;        /* sender of message                               */
  396. char    *fname;         /* full pathname of file                           */
  397. int     alright;
  398. {
  399.     int retval;
  400. #ifdef DEBUG
  401.     ll_log (logptr, LLOGBTR, "qn_rtend ()");
  402. #endif
  403.  
  404.     retval = RP_OK;
  405.     if (rp_isgood (alright))
  406.     {
  407.     if (ack_adr  != (char *) 0)
  408.     {
  409.         rtn_ack (ack_adr, qn_fp);
  410.                 /* don't care if this fails             */
  411.         free (ack_adr);
  412.     }
  413.  
  414.     if (rtn_errmsg (sender, qn_fp) == NOTOK)
  415.     {
  416.         ll_log (logptr,  LLOGTMP, "Failed to send error mesage to '%s'",
  417.                 sender);
  418.         if (rtn_errmsg (supportaddr, qn_fp) == NOTOK)
  419.         {
  420.         ll_log (logptr, LLOGTMP, "Failed to send error message to spport addr");
  421.         retval = RP_NO;
  422.         }
  423.     }
  424.                 /* fire off error message                  */
  425.                 /* pass error upwards if it fails          */
  426.     }
  427.  
  428.  
  429.     if ((qn_fp != NULL) && (fclose (qn_fp) == NOTOK)) /* close file */
  430.     {
  431.     ll_err (logptr, LLOGFAT, "Failure to close file '%s'", fname);
  432.     return (RP_FIO);
  433.     }
  434.  
  435.     if (rp_isgood (alright) && unlink (fname) == NOTOK)
  436.                 /* delete file                            */
  437.     {
  438.     ll_err (logptr, LLOGFAT, "Failure to unlink file '%s'", fname);
  439.     return (RP_FOPN);
  440.     }
  441.  
  442.     return (retval);
  443. }
  444. /* */
  445.  
  446. LOCFUN
  447. qn_rdchar ()                    /* read chars from jnt header           */
  448.                 /* stop when we reach blank line        */
  449. {
  450.     int         c;
  451.  
  452. #ifdef DEBUG
  453.    ll_log (logptr, LLOGMAX, "qn_rdchar ()");
  454. #endif
  455.  
  456.     if (eoheader)
  457.     return (EOF);
  458.  
  459.     if ((c = getc (qn_fp)) == EOF)
  460.     {
  461.     ll_err (logptr, LLOGTMP, "Premature end of JNT Mail Header");
  462.     return (EOF);
  463.     }
  464.     curpos++;
  465.  
  466.     if (c != '\n')
  467.     {
  468. #ifdef DEBUG
  469.     ll_log (logptr, LLOGMAX, "Returning (%c)", c);
  470. #endif
  471.     return (c);
  472.     }
  473.  
  474.     while (isspace (c = getc (qn_fp)) && c != '\n')
  475.     curpos++;
  476.  
  477.     curpos++;
  478.     if (c == '\n')              /* note NIFTP changes <CRLF> sequence */
  479.     {
  480. #ifdef DEBUG
  481.     ll_log (logptr, LLOGMAX, "Returning EOF");
  482. #endif
  483.     eoheader = TRUE;
  484.     return (EOF);
  485.     }
  486.                 /* end of JNT header                   */
  487.  
  488. #ifdef DEBUG
  489.     ll_log (logptr, LLOGMAX, "Returning (%c)", c);
  490. #endif
  491.  
  492.     return (c);                 /* Just a newline                       */
  493. }
  494.