home *** CD-ROM | disk | FTP | other *** search
/ Collection of Internet / Collection of Internet.iso / msdos / lynx / source / doslynx / src / tdosly15.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-25  |  11.3 KB  |  404 lines

  1. //    Copyright (c) 1994, University of Kansas, All Rights Reserved
  2. //
  3. //    Class:        TDosLynx
  4. //    Include File:    tdoslynx.h
  5. //    Purpose:    Application for WWW client
  6. //    Remarks/Portability/Dependencies/Restrictions:
  7. //    Revision History:
  8. //        04-04-94    created
  9. #define Uses_TRect
  10. #define Uses_TDialog
  11. #define Uses_TStaticText
  12. #define Uses_TInputLine
  13. #define Uses_TLabel
  14. #define Uses_TMemo
  15. #define Uses_TButton
  16. #define Uses_TProgram
  17. #define Uses_TDeskTop
  18. #include"tdoslynx.h"
  19. #include"globals.h"
  20. #include"trace.h"
  21. extern "C"    {
  22. #include"msdostcp.h"
  23. };
  24. #include<string.h>
  25.  
  26. //    The port number of the SMTP service on a networked macine.
  27. const int i_SMTPPort = 25;
  28.  
  29. //    CR/LF sequence used over the net.
  30. char *cp_crlf = "\r\n";
  31.  
  32. void TDosLynx::mailDeveloper()    {
  33. //    Purpose:    Allow user to send a mail message to whoever is
  34. //            ill fated enough to have to maintain this code!
  35. //    Arguments:    void
  36. //    Return Value:    void
  37. //    Remarks/Portability/Dependencies/Restrictions:
  38. //        Based on RFC 821, SMTP
  39. //    Revision History:
  40. //        04-04-94    created
  41.  
  42.     //    General use rectangle.
  43.     auto TRect TR;
  44.  
  45.     //    Create a good sized dialog.
  46.     TR = TRect(0, 0, 74, 22);
  47.     auto TDialog *TDp_mail = new TDialog(TR, "Mail Developer");
  48.  
  49.     //    Set some dialog options.
  50.     TDp_mail->options |= ofCentered;
  51.  
  52.     //    General use buffer.
  53.     auto char *cp_buffer = new char[4096];
  54.  
  55.     //    Create some static text to show what is happening.
  56.     TR = TRect(2, 1, 72, 2);
  57.     strcpy(cp_buffer, "To:        doslynx@falcon.cc.ukans.edu");
  58.     auto TStaticText *TSTp_rcpt = new TStaticText(TR, cp_buffer);
  59.     TDp_mail->insert(TSTp_rcpt);
  60.  
  61.     TR = TRect(2, 2, 72, 3);
  62.     strcpy(cp_buffer, "From:      doslynxuser@");
  63.     extern unsigned long my_ip_addr;
  64.     inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
  65.     auto TStaticText *TSTp_from = new TStaticText(TR, cp_buffer);
  66.     TDp_mail->insert(TSTp_from);
  67.  
  68.     //    Create the reply to input line.
  69.     TR = TRect(12, 3, 72, 4);
  70.     auto TInputLine *TILp_reply = new TInputLine(TR, usi_TILURLSize - 1);
  71.     if(::cp_ReplyTo != NULL)    {
  72.         TILp_reply->setData((void *)::cp_ReplyTo);
  73.     }
  74.     TDp_mail->insert(TILp_reply);
  75.  
  76.     TR = TRect(1, 3, 11, 4);
  77.     auto TLabel *TLp_reply = new TLabel(TR, "~R~eply-To:", TILp_reply);
  78.     TDp_mail->insert(TLp_reply);
  79.  
  80.     //    Create the subject to input line.
  81.     TR = TRect(12, 4, 72, 5);
  82.     auto TInputLine *TILp_subject = new TInputLine(TR, usi_TILURLSize - 1);
  83.     TILp_subject->setData((void *)"DosLynx v0.71a");
  84.     TDp_mail->insert(TILp_subject);
  85.  
  86.     TR = TRect(1, 4, 11, 5);
  87.     auto TLabel *TLp_subject = new TLabel(TR, "S~u~bject:", TILp_subject);
  88.     TDp_mail->insert(TLp_subject);
  89.  
  90.     //    Create the user editable area for the message.
  91.     TR = TRect(2, 7, 72, 18);
  92.     auto TMemo *TMp_message = new TMemo(TR, NULL, NULL, NULL, 4096 -
  93.         sizeof(unsigned short int));
  94.     TDp_mail->insert(TMp_message);
  95.  
  96.     TR = TRect(1, 6, 72, 7);
  97.     auto TLabel *TLp_message = new TLabel(TR, "~M~essage:", TMp_message);
  98.     TDp_mail->insert(TLp_message);
  99.  
  100.     //    Create the Send and Cancel buttons.
  101.     TR = TRect(15, 19, 27, 21);
  102.     auto TButton *TBp_send = new TButton(TR, "~S~end", cmOK, bfDefault);
  103.     TDp_mail->insert(TBp_send);
  104.  
  105.     TR = TRect(47, 19, 59, 21);
  106.     auto TButton *TBp_cancel = new TButton(TR, "~C~ancel", cmCancel,
  107.         bfNormal);
  108.     TDp_mail->insert(TBp_cancel);
  109.  
  110.     //    Done with the dialog.
  111.     //    Stay in reply field.
  112.     TDp_mail->selectNext(False);
  113.  
  114.     //    Draw it.
  115.     TDp_mail->drawView();
  116.  
  117.     //    Execute.  Code does nothing if user cancels.
  118.     if(TProgram::deskTop->execView(TDp_mail) != cmCancel)    {
  119.         //    Time to send the mail.
  120.  
  121.         //    Obtain a socket.
  122. #ifndef RELEASE
  123.         trace("getting socket.");
  124. #endif // RELEASE
  125.         auto int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  126.         if(sockfd == -1)    {
  127.             destroy(TDp_mail);
  128.             doslynxmessage("Unable to obtain a socket.  No mail "
  129.                 "sent.");
  130.             delete(cp_buffer);
  131.             return;
  132.         }
  133.  
  134.         //    Resolve address.
  135. #ifndef RELEASE
  136.         trace("resolving address.");
  137. #endif // RELEASE
  138.         auto struct sockaddr_in sin;
  139.         sin.sin_family = AF_INET;
  140.         sin.sin_port = ntohs(i_SMTPPort);
  141.         sin.sin_addr.s_addr = resolve("falcon.cc.ukans.edu");
  142.         if(sin.sin_addr.s_addr == 0UL)    {
  143.             destroy(TDp_mail);
  144.             s_close(sockfd);
  145.             doslynxmessage("DNSLookup failed for SMTP host. "
  146.                 "No mail sent.");
  147.             delete(cp_buffer);
  148.             return;
  149.         }
  150.  
  151.         //    Connect to SMTP host
  152. #ifndef RELEASE
  153.         trace("connecting to SMTP host.");
  154. #endif // RELEASE
  155.         if(connect(sockfd, (sockaddr *)(&sin),
  156.             sizeof(struct sockaddr_in)) < 0)    {
  157.             destroy(TDp_mail);
  158.             s_close(sockfd);
  159.             doslynxmessage("Unable to connect to SMTP host.  "
  160.                 "No mail sent.");
  161.             delete(cp_buffer);
  162.             return;
  163.         }
  164.  
  165.         //    Since we are connected, start doing the SMTP thing.
  166.  
  167.         //    Check for 220 response.
  168.         cp_buffer[0] = '\0';
  169.         s_read(sockfd, cp_buffer, 4095);
  170.         if(strstr(cp_buffer, "220") == NULL)    {
  171.             destroy(TDp_mail);
  172.             s_close(sockfd);
  173.             doslynxmessage("SMTP host not responding.  "
  174.                 "No mail sent.");
  175.             delete(cp_buffer);
  176.             return;
  177.         }
  178.  
  179.         //    Send HELO
  180.         sprintf(cp_buffer, "HELO %s.%s%s", gethostname(NULL, 0) ==
  181.             NULL ? "doslynx" : gethostname(NULL, 0),
  182.             getdomainname(NULL, 0) == NULL ? "i.dont.know" :
  183.             getdomainname(NULL, 0), cp_crlf);
  184.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  185.  
  186.         //    Check for 250 response.
  187.         cp_buffer[0] = '\0';
  188.         s_read(sockfd, cp_buffer, 4095);
  189.         if(strstr(cp_buffer, "250") == NULL)    {
  190.             destroy(TDp_mail);
  191.             s_close(sockfd);
  192.             doslynxmessage("SMTP host not responding.  "
  193.                 "No mail sent.");
  194.             delete(cp_buffer);
  195.             return;
  196.         }
  197.  
  198.         //    Send MAIL FROM
  199.         sprintf(cp_buffer, "MAIL FROM:<doslynxuser@");
  200.         inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
  201.         strcat(cp_buffer, ">");
  202.         strcat(cp_buffer, cp_crlf);
  203.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  204.  
  205.         //    Check for 250 response.
  206.         cp_buffer[0] = '\0';
  207.         s_read(sockfd, cp_buffer, 4095);
  208.         if(strstr(cp_buffer, "250") == NULL)    {
  209.             destroy(TDp_mail);
  210.             s_close(sockfd);
  211.             doslynxmessage("SMTP host refusing to accept.  "
  212.                 "No mail sent.");
  213.             delete(cp_buffer);
  214.             return;
  215.         }
  216.  
  217.         //    Send RCPT TO
  218.         sprintf(cp_buffer, "RCPT TO:<doslynx@falcon.cc.ukans.edu>%s",
  219.             cp_crlf);
  220.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  221.  
  222.         //    Check for 250 or 251 response.
  223.         cp_buffer[0] = '\0';
  224.         s_read(sockfd, cp_buffer, 4095);
  225.         if(strstr(cp_buffer, "250") == NULL && strstr(cp_buffer,
  226.             "251") == NULL)    {
  227.             destroy(TDp_mail);
  228.             s_close(sockfd);
  229.             doslynxmessage("SMTP host refusing to accept.  "
  230.                 "No mail sent.");
  231.             delete(cp_buffer);
  232.             return;
  233.         }
  234.  
  235.         //    Send DATA
  236.         sprintf(cp_buffer, "DATA%s", cp_crlf);
  237.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  238.  
  239.         //    Check for 354 response.
  240.         cp_buffer[0] = '\0';
  241.         s_read(sockfd, cp_buffer, 4095);
  242.         if(strstr(cp_buffer, "354") == NULL)    {
  243.             destroy(TDp_mail);
  244.             s_close(sockfd);
  245.             doslynxmessage("SMTP host refusing to accept.  "
  246.                 "No mail sent.");
  247.             delete(cp_buffer);
  248.             return;
  249.         }
  250.  
  251.         //    Send some normal mail header stuff.
  252. #ifndef RELEASE
  253.         trace("writing message header.");
  254. #endif // RELEASE
  255.         auto time_t tt_time = time(NULL);
  256.         sprintf(cp_buffer, "Date:      %s", ctime(&tt_time));
  257.         strcpy(cp_buffer + strlen(cp_buffer) - 1, cp_crlf);
  258.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  259.  
  260.         sprintf(cp_buffer, "To:        DosLynx Developer <doslynx@"
  261.             "falcon.cc.ukans.edu>%s", cp_crlf);
  262.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  263.  
  264.         strcpy(cp_buffer, "From:      \"");
  265.         inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
  266.         strcat(cp_buffer, "\" <doslynxuser@");
  267.         if(gethostname(NULL, 0) != NULL)    {
  268.             strcat(cp_buffer, gethostname(NULL, 0));
  269.             if(getdomainname(NULL, 0) != NULL)    {
  270.                 strcat(cp_buffer, ".");
  271.                 strcat(cp_buffer, getdomainname(NULL, 0));
  272.             }
  273.         }
  274.         else    {
  275.             inet_ntoa(cp_buffer + strlen(cp_buffer), my_ip_addr);
  276.         }
  277.         strcat(cp_buffer, ">");
  278.         strcat(cp_buffer, cp_crlf);
  279.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  280.  
  281.         TILp_reply->getData((void *)cp_buffer);
  282.         if(cp_buffer[0] != '\0')    {
  283.             s_write(sockfd, "Reply-To:  ", 11);
  284.             s_write(sockfd, cp_buffer, strlen(cp_buffer));
  285.             s_write(sockfd, cp_crlf, strlen(cp_crlf));
  286.         }
  287.  
  288.         TILp_subject->getData((void *)cp_buffer);
  289.         if(cp_buffer[0] != '\0')    {
  290.             s_write(sockfd, "Subject:   ", 11);
  291.             s_write(sockfd, cp_buffer, strlen(cp_buffer));
  292.             s_write(sockfd, cp_crlf, strlen(cp_crlf));
  293.         }
  294.         else    {
  295.             sprintf(cp_buffer, "Subject:   (none)%s", cp_crlf);
  296.             s_write(sockfd, cp_buffer, strlen(cp_buffer));
  297.         }
  298.  
  299.         //    Start sending the body of the message.
  300.         //    Use the scheme stated in rfc 821.
  301.         //    We will skip the first sizeof(unsigned short int)
  302.         //    bytes because they are meaningless.
  303. #ifndef RELEASE
  304.         trace("writing message body.");
  305. #endif // RELEASE
  306.         TMp_message->getData((void *)cp_buffer);
  307.         auto char *cp_convert = cp_buffer + sizeof(unsigned short int);
  308.  
  309.         //    Convert buffer into the rfc821 compliant message.
  310.         for(;cp_convert != '\0'; cp_convert++)    {
  311.             //    Do nothing unless a newline or a '.'
  312.  
  313.             //    Here, we will have to add stuff to the
  314.             //    buffer if it is a newline or a '.' at the
  315.             //    start of a line.
  316.             if(*cp_convert == '.')    {
  317.                 //    To be at the start of a line, the
  318.                 //    '.' is either the very first line
  319.                 //    or is preceded by a newline.
  320.                 if(cp_convert == cp_buffer + sizeof(unsigned
  321.                     short int) || *(cp_convert - 1) ==
  322.                     '\n')    {
  323.                     //    First, move so that there is
  324.                     //    enough space in the buffer.
  325.                     //    Start from the end.
  326.                     for(auto char *cp_double = cp_convert
  327.                         + strlen(cp_convert);
  328.                         cp_double >= cp_convert;
  329.                         cp_double--)    {
  330.                         *(cp_double + 1) = *cp_double;
  331.                     }
  332.  
  333.                     //    Increment cp_convert by one
  334.                     //    since added a character.
  335.                     cp_convert++;
  336.                 }
  337.             }
  338.             else if(*cp_convert == '\n')    {
  339.                 //    Turn this into a cp_crlf.
  340.                 //    First, move so that there is
  341.                 //    enough space in the buffer.
  342.                 //    Start from the end.
  343.                 for(auto char *cp_double = cp_convert
  344.                     + strlen(cp_convert);
  345.                     cp_double >= cp_convert;
  346.                     cp_double--)    {
  347.                     *(cp_double + 1) = *cp_double;
  348.                 }
  349.  
  350.                 //    Increment cp_convert by one
  351.                 //    since added a character.
  352.                 //    Convert the \n now pointed at to a
  353.                 //    \r
  354.                 *cp_convert = '\r';
  355.                 cp_convert++;
  356.             }
  357.         }
  358.  
  359.         //    Write the message body.
  360.         s_write(sockfd, cp_buffer + sizeof(unsigned short int),
  361.             strlen(cp_buffer + sizeof(unsigned short int)));
  362.  
  363.         //    Done.  Write the ending of the message and close the
  364.         //    socket.
  365.         sprintf(cp_buffer, "%s%c%s", cp_crlf, '.', cp_crlf);
  366.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  367.  
  368.         //    Check for 250 response
  369.         cp_buffer[0] = '\0';
  370.         s_read(sockfd, cp_buffer, 4095);
  371.         if(strstr(cp_buffer, "250") == NULL)    {
  372.             destroy(TDp_mail);
  373.             s_close(sockfd);
  374.             doslynxmessage("SMTP host did not accept message.");
  375.             delete(cp_buffer);
  376.             return;
  377.         }
  378.  
  379.         //    Send QUIT
  380.         sprintf(cp_buffer, "QUIT%s", cp_crlf);
  381.         s_write(sockfd, cp_buffer, strlen(cp_buffer));
  382.  
  383.         //    Check for 221 response.
  384.         cp_buffer[0] = '\0';
  385.         s_read(sockfd, cp_buffer, 4095);
  386.         if(strstr(cp_buffer, "221") == NULL)    {
  387.             destroy(TDp_mail);
  388.             s_close(sockfd);
  389.             doslynxmessage("SMTP host wouldn't end session.");
  390.             delete(cp_buffer);
  391.             return;
  392.         }
  393.  
  394.         //    Close the socket.  We're done.
  395.         s_close(sockfd);
  396.         doslynxmessage("Mail message was sent.");
  397.     }
  398.  
  399.     //    Destroy the dialog.
  400.     destroy(TDp_mail);
  401.  
  402.     //    Get rid of our buffer.
  403.     delete(cp_buffer);
  404. }