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