//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::btMailClick(TObject *Sender) { // on entering this handler you should have previously provided the following global strings: // // SMTP_SERVER (example: "mail.hotmail.com") // MAILADDRESS (example: "joe@hotmail.com", this is the address of the sender) // RECIPIENT (example: "mary@hotmail.com", this is the address of the recipient) // SUBJECT (example: "A mail for you") // MESSAGE_BODY (example: "Dear Mary, please receive this attachment. Bye. Joe" // ATTACH_FILENAME (example: "C:\DOCUMENTS\FOO.BIN") // ATTACH_LEN (the length in bytes of the file to attach) // login is not requred by SMTP servers; it is required by ESMTP servers that // support AUTH=LOGIN type of authentication (the most common) if ( ) { // please prepare the string USERNAME (i.e. the user account) // please prepare the string PASSWORD } // send a message if the attachment is too long int iActualLen = ( ( ATTACH_LEN * 4 ) / 3 ) / 1024; // this takes into account the 4/3 expansion caused by BASE64 encoding if ( iActualLen > 500 ) { char szActualLen [ 16 ]; itoa ( iActualLen, szActualLen, 10 ); char szMsg [ 128 ]; strcpy ( szMsg, "Attachment is " ); strcat ( szMsg, szActualLen ); strcat ( szMsg, "kBytes long. Send it anyway ?" ); rc = MessageBox ( NULL, szMsg, "Warning:", MB_OKCANCEL || MB_ICONQUESTION || MB_SYSTEMMODAL ); if ( rc != IDOK ) return; } // send a message to let the user connect to his/her ISP if ( ) { strcpy ( szMsg, "Press OK only when you are connected to the Internet." ); rc = MessageBox ( NULL, szMsg, "Are you connected to the Internet ?", MB_OKCANCEL || MB_ICONQUESTION || MB_SYSTEMMODAL ); if ( rc != IDOK ) return; } // connect the SMPT server Screen -> Cursor = crHourGlass; currentProgramStatus = "connecting"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); ClientSocket1 -> Host = SMTP_SERVER; ClientSocket1 -> Port = 25; ClientSocket1 -> Open ( ); // end buttonclick handler return; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket) { // the SMTP server accepted our connection currentProgramStatus = "connected"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket) { char szMessage [ 516 ]; char szTemp [ 516 ]; AnsiString Response = ClientSocket1 -> Socket -> ReceiveText ( ); // only the three leading ciphers are meaningful AnsiString respCode = Response . SubString ( 1, 3 ); Sleep ( 500 ); // 220 if ( respCode == "220" ) { if ( currentProgramStatus == "connected" ) { // simple SMTP server if ( ) { currentProgramStatus = "HELO"; strcpy ( szMessage, "HELO FOOBAR automatic mail sender\r\n" ); } // more sophisticated ESMTP server if ( ) { currentProgramStatus = "EHLO"; strcpy ( szMessage, "EHLO FOOBAR automatic mail sender\r\n" ); } stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } } // 221 if ( respCode == "221" ) { if ( currentProgramStatus == "QUIT" ) { currentProgramStatus = "disconnecting"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); Sleep ( 30 ); ClientSocket1 -> Close ( ); stStatus -> Caption = ""; stStatus -> Update ( ); ProgressBar1 -> Position = 0; Screen -> Cursor = crDefault; return; } } // 235 if ( respCode == "235" ) { if ( currentProgramStatus == "PASSWORD" ) { currentProgramStatus = "MAIL"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "MAIL From:<" ); strcat ( szMessage, MAILADDRESS ); strcat ( szMessage, ">\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } } // 250 if ( respCode == "250" ) { if ( currentProgramStatus == "HELO" ) { currentProgramStatus = "MAIL"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "MAIL From:<" ); strcat ( szMessage, MAILADDRESS ); strcat ( szMessage, ">\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } if ( currentProgramStatus == "EHLO" ) { currentProgramStatus = "AUTH LOGIN"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "AUTH LOGIN\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } if ( currentProgramStatus == "MAIL" ) { currentProgramStatus = "RCPT"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "RCPT To:<" ); strcat ( szMessage, RECIPIENT ); strcat ( szMessage, ">\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } if ( currentProgramStatus == "RCPT" ) { currentProgramStatus = "DATA"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "DATA\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } if ( currentProgramStatus == "sending mail" ) { currentProgramStatus = "QUIT"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "QUIT\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } } // 334 if ( respCode == "334" ) { if ( currentProgramStatus == "AUTH LOGIN" ) { currentProgramStatus = "USERNAME"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, ENCODEDUSERNAME ); // Base-64 encoded, thanks Oliver ! strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } if ( currentProgramStatus == "USERNAME" ) { currentProgramStatus = "PASSWORD"; // Base-64 encoded, too stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, PASSWORD ); strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } } // 354 if ( respCode == "354" ) { if ( currentProgramStatus == "DATA" ) { currentProgramStatus = "sending mail"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); Sleep ( 30 ); strcpy ( szMessage, "From: " ); strcat ( szMessage, MAILADDRESS ); strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "To: " ); strcat ( szMessage, RECIPIENT ); strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "Subject: " ); strcat ( szMessage, SUBJECT ); strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "MIME-Version: 1.0\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "Content-Type: multipart/mixed;\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); char lf [ 2 ]; lf [ 0 ] = 34; lf [ 1 ] = 0; strcpy ( szMessage, " boundary=" ); strcat ( szMessage, lf ); strcat ( szMessage, "KkK170891tpbkKk__FV_KKKkkkjjwq" ); strcat ( szMessage, lf ); strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); //----------- MAIL PART ONE: THE BODY strcpy ( szMessage, "--KkK170891tpbkKk__FV_KKKkkkjjwq\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "Content-Type: text/plain; charset=US-ASCII\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, MESSAGE_BODY ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "\r\n\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "*** sent by: foobar mail sender ***" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "\r\n\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); //----------- MAIL PART TWO: THE ATTACHMENT stStatus -> Caption = "sending attachment"; stStatus -> Update ( ); strcpy ( szMessage, "--KkK170891tpbkKk__FV_KKKkkkjjwq\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "Content-Type: application/octet-stream\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "Content-Transfer-Encoding: base64\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "Content-Disposition: attachment;" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, " filename=" ); strcat ( szMessage, lf ); char attachFileNameWithoutPath [ 64 ]; int lun = strlen ( ATTACH_FILENAME ); int x, y, z; for ( x = lun; x > 0; x-- ) { char c = ATTACH_FILENAME [ x ]; if ( c == '\\' ) break; } x = x + 1; z = 0; for ( y = x; y < lun; y++ ) { char c = ATTACH_FILENAME [ y ]; attachFileNameWithoutPath [ z ] = c; z++; } attachFileNameWithoutPath [ z ] = 0; strcat ( szMessage, attachFileNameWithoutPath ); strcat ( szMessage, lf ); strcat ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); bool rc = false; ProgressBar1 -> Position = 0; ProgressBar1 -> Max = ( ATTACH_LEN * 4 ) / 3; rc = pfnFFBase64Open ( ATTACH_FILENAME ); int in_len, out_len; while ( rc ) // this is the heart cycle in sending the attachment { in_len = pfnFFBase64Get512Bytes ( szMessage ); if ( in_len == 0 ) break; // end of attachment strcat ( szMessage, "\r\n" ); // using SendBuf instead of SendText it is in_len += 2; // necessary to put cr+lf by hand !!! while ( true ) { out_len = ClientSocket1 -> Socket -> SendBuf ( szMessage, in_len ); if ( out_len != -1 ) break; Sleep ( 30 ); } ProgressBar1 -> Position += out_len; } pfnFFBase64Close ( ); strcpy ( szMessage, "\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); strcpy ( szMessage, "--KkK170891tpbkKk__FV_KKKkkkjjwq--\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); //----------- strcpy ( szMessage, "\r\n.\r\n" ); // FINAL DOT ClientSocket1 -> Socket -> SendText ( szMessage ); Sleep ( 30 ); return; } } // 535 if ( respCode == "535" ) { if ( currentProgramStatus == "PASSWORD" ) { currentProgramStatus = "QUIT"; stStatus -> Caption = currentProgramStatus; stStatus -> Update ( ); strcpy ( szMessage, "QUIT\r\n" ); ClientSocket1 -> Socket -> SendText ( szMessage ); MessageBox ( NULL, "Username and/or password wrong.", "Cannoth authenticate:", MB_SYSTEMMODAL ); return; } } // any othe code stStatus -> Caption = "conversation error"; stStatus -> Update ( ); ClientSocket1 -> Close ( ); stStatus -> Caption = ""; stStatus -> Update ( ); Screen -> Cursor = crDefault; strcpy ( szMessage, "SMTP return code: " ); strcat ( szMessage, respCode . c_str ( ) ); strcat ( szMessage, "\r\n" ); strcat ( szMessage, "last status: " ); strcat ( szMessage, currentProgramStatus . c_str ( ) ); MessageBox ( NULL, szMessage, "Conversation error:", MB_SYSTEMMODAL ); return; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode) { int errore = ErrorCode; ErrorCode = 0; stStatus -> Caption = ""; stStatus -> Update ( ); Screen -> Cursor = crDefault; char string [ 32 ]; itoa ( errore, string, 10 ); MessageBox ( 0, string, "onError", MB_OK ); } //--------------------------------------------------------------------------- //---------------------------------------------------------------------------