home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / vsoup128.zip / reply.cc < prev    next >
C/C++ Source or Header  |  1997-01-20  |  10KB  |  413 lines

  1. //  $Id: reply.cc 1.17 1997/01/20 16:29:40 hardy Exp $
  2. //
  3. //  This progam/module was written by Hardy Griech based on ideas and
  4. //  pieces of code from Chin Huang (cthuang@io.org).  Bug reports should
  5. //  be submitted to rgriech@ibm.net.
  6. //
  7. //  This file is part of soup++ for OS/2.  Soup++ including this file
  8. //  is freeware.  There is no warranty of any kind implied.  The terms
  9. //  of the GNU Gernal Public Licence are valid for this piece of software.
  10. //
  11. //  Send reply packet.
  12. //
  13.  
  14.  
  15. #include <fcntl.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #include "global.hh"
  20. #include "mts.hh"
  21. #include "reply.hh"
  22. #include "util.hh"
  23.  
  24. #include "nntpcl.hh"
  25. #include "smtp.hh"
  26. #include "socket.hh"
  27.  
  28. static TSocket smtpSock;
  29. static TNntp nntpReply;
  30. static char *mailer;
  31. static char *poster;
  32.  
  33.  
  34.  
  35. static int sendPipe( TFile &fd, size_t bytes, const char *agent )
  36. //
  37. //  Pipe a message to the specified delivery agent.
  38. //
  39. {
  40.     FILE *pfd;
  41.     char buff[4096];
  42.     int cnt;
  43.  
  44.     /* Open pipe to agent */
  45.     if ((pfd = popenT(agent, "wb")) == NULL) {
  46.     areas.mailPrintf1( 1,"%s: cannot open reply pipe %s\n", progname,agent );
  47.     while (bytes > 0) {
  48.         cnt = (bytes >= sizeof(buff)) ? sizeof(buff) : bytes;
  49.         fd.read( buff,cnt );
  50.         bytes -= cnt;
  51.     }
  52.     return 0;
  53.     }
  54.  
  55.     /* Send message to pipe */
  56.     while (bytes > 0) {
  57.     cnt = (bytes >= sizeof(buff)) ? sizeof(buff) : bytes;
  58.     if (fd.read(buff,cnt) != cnt) {
  59.         areas.mailPrintf1( 1,"%s: ill reply file: %s\n", progname,fd.getName() );
  60.         return 0;
  61.     }
  62.     fwriteT( buff,1,cnt,pfd );
  63.     bytes -= cnt;
  64.     }
  65.  
  66.     pcloseT(pfd);
  67.     return 1;
  68. }   // sendPipe
  69.  
  70.  
  71.  
  72. static int sendMail( TFile &inf, size_t bytes )
  73. {
  74.     int res = 1;
  75.     if (mailer) {
  76.     const char *to = getHeader(inf, "To");
  77.     areas.mailPrintf1(1,"%s: mailing to %s\n", progname, to);
  78. ////    delete to;
  79.  
  80.     /* Pipe message to delivery agent */
  81.     res = sendPipe(inf, bytes, mailer);
  82.     }
  83.     else {
  84.     if ( !smtpMail(smtpSock, inf, bytes)) {
  85.         areas.mailPrintf1( 1,"%s: cannot deliver mail\n",progname );
  86.         res = 0;
  87.     }
  88.     }
  89.     return res;
  90. }   // sendMail
  91.  
  92.  
  93.  
  94. static int sendNews( TFile &inf, size_t bytes )
  95. {
  96.     int res = 1;
  97.     const char *grp;
  98.  
  99.     grp = getHeader( inf, "Newsgroups" );
  100.     areas.mailPrintf1(1,"%s: posting article to %s\n", progname, grp);
  101. ////    delete grp;
  102.  
  103.     if (poster) {
  104.     /* Pipe message to delivery agent */
  105.     res = sendPipe(inf, bytes, poster);
  106.     } else {
  107.     if (nntpReply.postArticle( inf,bytes ) != TNntp::ok) {
  108.         areas.mailPrintf1( 1,"%s: cannot post article: %s\n",
  109.                    progname,nntpReply.getLastErrMsg());
  110.         res = 0;
  111.     }
  112.     }
  113.     return res;
  114. }   // sendNews
  115.  
  116.  
  117.  
  118. static int sendMailu (const char *fn)
  119. //
  120. //  Process a mail reply file, usenet type (is that one really correct???)
  121. //
  122. {
  123.     char buf[BUFSIZ];
  124.     TFile fd;
  125.     int bytes;
  126.     int res = 1;
  127.  
  128.     //
  129.     //  Open the reply file
  130.     //  problem here is non-fatal!
  131.     //
  132.     if ( !fd.open(fn,TFile::mread,TFile::obinary)) {
  133.     areas.mailPrintf1( 1,"%s: cannot open file %s\n", progname,fn );
  134.     return 1;
  135.     }
  136.  
  137.     /* Read through it */
  138.     while (fd.fgets(buf,sizeof(buf),1)) {
  139.     if (strncmp (buf, "#! rnews ", 9)) {
  140.         areas.mailPrintf1( 1,"%s: malformed reply file\n", progname);
  141.         res = 0;
  142.         break;
  143.     }
  144.  
  145.     /* Get byte count */
  146.     sscanfT(buf+9, "%d", &bytes);
  147.  
  148.     if ( !sendMail(fd, bytes)) {
  149.         res = 0;
  150.         break;
  151.     }
  152.     }
  153.     fd.close();
  154.     return res;
  155. }   // sendMailu
  156.  
  157.  
  158.  
  159. static int sendNewsu (const char *fn)
  160. //
  161. //  Process a news reply file, usenet type
  162. //
  163. {
  164.     char buf[BUFSIZ];
  165.     TFile fd;
  166.     int bytes;
  167.     int res = 1;
  168.  
  169.     //
  170.     //  Open the reply file
  171.     //  problem here is non-fatal!
  172.     //
  173.     if ( !fd.open(fn,TFile::mread,TFile::obinary)) {
  174.     areas.mailPrintf1( 1,"%s: cannot open file %s\n", progname,fn );
  175.     return 1;
  176.     }
  177.  
  178.     /* Read through it */
  179.     while (fd.fgets(buf,sizeof(buf),1)) {
  180.     if (strncmp (buf, "#! rnews ", 9)) {
  181.         areas.mailPrintf1( 1,"%s: malformed reply file\n", progname);
  182.         res = 0;
  183.         break;
  184.     }
  185.  
  186.     sscanfT(buf+9, "%d", &bytes);
  187.     if ( !sendNews(fd, bytes)) {
  188.         res = 0;
  189.         break;
  190.     }
  191.     }
  192.     fd.close();
  193.     return res;
  194. }   // sendNewsu
  195.  
  196.  
  197.  
  198. static int sendMailb (const char *fn)
  199. //
  200. //  Process a mail reply file, binary type
  201. //  The binary type is handled transparent, i.e. CRLF are two characters!
  202. //
  203. {
  204.     unsigned char count[4];
  205.     TFile fd;
  206.     int bytes;
  207.     int res = 1;
  208.  
  209.     //
  210.     //  Open the reply file
  211.     //  problem here is non-fatal!
  212.     //
  213.     if ( !fd.open(fn,TFile::mread,TFile::obinary)) {
  214.     areas.mailPrintf1( 1,"%s: cannot open file %s\n", progname,fn );
  215.     return 1;
  216.     }
  217.  
  218.     /* Read through it */
  219.     while (fd.read(count,4) == 4) {
  220.     /* Get byte count */
  221.     bytes = ((count[0]*256 + count[1])*256 + count[2])*256 + count[3];
  222.     if ( !sendMail(fd, bytes)) {
  223.         res = 0;
  224.         break;
  225.     }
  226.     }
  227.  
  228.     fd.close();
  229.     return res;
  230. }   // sendMailb
  231.  
  232.  
  233.  
  234. static int sendNewsb (const char *fn)
  235. //
  236. //  Process a news reply file, binary type
  237. //  The binary type is handled transparent, i.e. CRLF are two characters!
  238. //
  239. {
  240.     unsigned char count[4];
  241.     TFile fd;
  242.     int bytes;
  243.     int res = 1;
  244.  
  245.     //
  246.     //  Open the reply file
  247.     //  problem here is non-fatal!
  248.     //
  249.     if ( !fd.open(fn,TFile::mread,TFile::obinary)) {
  250.     areas.mailPrintf1( 1,"%s: cannot open file %s\n", progname,fn );
  251.     return 1;
  252.     }
  253.  
  254.     /* Read through it */
  255.     while (fd.read(count, 4) == 4) {
  256.     bytes = ((count[0]*256 + count[1])*256 + count[2])*256 + count[3];
  257.     if ( !sendNews(fd, bytes)) {
  258.         res = 0;
  259.         break;
  260.     }
  261.     }
  262.     fd.close();
  263.     return res;
  264. }   // sendNewsb
  265.  
  266.  
  267.  
  268. int sendReply (void)
  269. //
  270. //  Process a reply packet.
  271. //
  272. {
  273.     TFile rep_fd;
  274.     char buf[BUFSIZ];
  275.     char fname[FILENAME_MAX], kind[FILENAME_MAX], type[FILENAME_MAX];
  276.     int mailError = 0;
  277.     int nntpError = 0;
  278.  
  279.     mailer = getenv("MAILER");
  280.     poster = getenv("POSTER");
  281.     
  282.     //
  283.     //  Open the packet
  284.     //  if none exists -> non-fatal
  285.     //
  286.     if ( !rep_fd.open(FN_REPLIES,TFile::mread,TFile::otext)) {
  287.     areas.mailPrintf1( 1,"%s: can't open file %s\n", progname, FN_REPLIES);
  288.     return 0;
  289.     }
  290.  
  291.     /* Look through lines in REPLIES file */
  292.     while (rep_fd.fgets(buf, sizeof(buf), 1)) {
  293.     if (sscanfT(buf, "%s %s %s", fname, kind, type) != 3) {
  294.         areas.mailPrintf1( 1,"%s: malformed REPLIES line: %s\n", progname,buf);
  295.         return 0;
  296.     }
  297.  
  298.     /* Check reply type */
  299.     if (type[0] != 'u' && type[0] != 'b' && type[0] != 'B') {
  300.         areas.mailPrintf1( 1,"%s: reply type %c not supported\n", progname,
  301.                    type[0]);
  302.         areas.forceMail();            // indicates corrupt replies file
  303.         continue;
  304.     }
  305.  
  306.     //
  307.     //  Look for mail or news
  308.     //  and first try to connect
  309.     //
  310.     if (type[0] == 'b'  ||  (type[0] == 'u'  &&  strcmp(kind, "mail") == 0)) {
  311.         if (mailError)
  312.         continue;
  313.         if ( !mailer  &&  smtpSock.state() != TSocket::connected) {
  314.         if (smtpInfo.host == NULL) {
  315.             areas.mailPrintf1( 1,"%s: no smtp gateway defined\n", progname );
  316.             mailError = 1;
  317.             continue;
  318.         }
  319.         else if ( !smtpConnect(smtpSock)) {
  320.             areas.mailPrintf1( 1,"%s: cannot connect to smtp gateway %s\n",
  321.                        progname, smtpInfo.host );
  322.             mailError = 1;
  323.             continue;
  324.         }
  325.         else
  326.             areas.mailPrintf1( 1,"%s: connected to smtp gateway %s\n",
  327.                        progname, smtpInfo.host );
  328.         }
  329.     } else if (type[0] == 'B'  ||  (type[0] == 'u'  &&  strcmp(kind, "news") == 0)) {
  330.         if (nntpError)
  331.         continue;
  332.         if ( !poster) {
  333.         if (nntpInfo.host == NULL) {
  334.             areas.mailPrintf1( 1,"%s: no news server defined\n", progname );
  335.             nntpError = 1;
  336.             continue;
  337.         }
  338.         else if (nntpReply.open(nntpInfo.host,nntpInfo.user,nntpInfo.passwd,nntpInfo.port) != TNntp::ok) {
  339.             areas.mailPrintf1( 1,"%s: cannot connect to news server %s (post):\n\t%s\n",
  340.                        progname, (nntpInfo.host != NULL) ? nntpInfo.host : "\b",
  341.                        nntpReply.getLastErrMsg() );
  342.             nntpError = 1;
  343.             continue;
  344.         }
  345.         else
  346.             areas.mailPrintf1( 1,"%s: connected to news server %s (post)\n",
  347.                        progname, nntpInfo.host );
  348.         }
  349.     }
  350.     else {
  351.         areas.mailPrintf1( 1,"%s: bad reply kind: %s\n", progname, kind);
  352.         areas.forceMail();     // indicates corrupt replies file
  353.         continue;
  354.     }
  355.  
  356.     /* Make file name */
  357.     strcat(fname, ".MSG");
  358.  
  359.     /*
  360.     **  Wenn Datei nicht existiert heißt das, daß sie schon
  361.     **  versendet wurde (und dies sozusagen ein RETRY ist)
  362.     */
  363.  
  364.     /* Process it */
  365.     switch (type[0]) {
  366.         case 'u':
  367.         if (strcmp(kind, "mail") == 0) {
  368.             if ( !sendMailu(fname)) {
  369.             mailError = 1;
  370.             continue;
  371.             }
  372.         }
  373.         else if (strcmp(kind, "news") == 0) {
  374.             if ( !sendNewsu(fname)) {
  375.             nntpError = 1;
  376.             continue;
  377.             }
  378.         }
  379.         break;
  380.         case 'b':
  381.         if ( !sendMailb(fname)) {
  382.             mailError = 1;
  383.             continue;
  384.         }
  385.         break;
  386.         case 'B':
  387.         if ( !sendNewsb(fname)) {
  388.             nntpError = 1;
  389.             continue;
  390.         }
  391.         break;
  392.     }
  393.  
  394.     /* Delete it */
  395.     if ( !readOnly)
  396.         removeT(fname);
  397.     }
  398.  
  399.     if (smtpSock.state() == TSocket::connected)
  400.     smtpClose( smtpSock );
  401.     nntpReply.close( 1 );
  402.  
  403.     //
  404.     //  remove REPLIES only, if successfull
  405.     //
  406.     if ( !readOnly  &&  !mailError  &&  !nntpError)
  407.     rep_fd.remove();
  408.     else
  409.     rep_fd.close();
  410.  
  411.     return !mailError  &&  !nntpError;
  412. }   // sendReply
  413.