Page 1 of 1

Tip: MailSend procedure

Posted: Wed Sep 11, 2002 7:15 am
by BackupUser
Code updated For 5.20+

Restored from previous forum. Originally posted by PB.

Here's some old code I found that I cleaned up a bit and tested. Seems
to work fine with no problems, but doesn't support attachments. :cry:

Don't forget to change the settings at the end of the code to your own
ISP's server details! :)

Code: Select all

; MailSend procedure by PB -- do whatever you want with it.
; Stolen from an existing example but cleaned up by me a bit.
; Does not handle attachments because I don't know how.  :(
;
Global MailID.l,MailResponse.s
;
Procedure MailDataSend(msg.s)
  SendNetworkData(MailID,@msg,Len(msg))
EndProcedure
;
Procedure.s MailResponse()
  MailResponse=Space(9999)
  ReceiveNetworkData(MailID,@MailResponse,9999)
  MailResponse=Left(MailResponse,3)
  ProcedureReturn MailResponse
EndProcedure
;
Procedure MailSend(recipient$,subject$,body$,server$,from$)
  If InitNetwork()
    MailID=OpenNetworkConnection(server$,25)
    If MailID0
      MailResponse()
      If MailResponse="220"
        MailDataSend("HELO CGIapp"+Chr(13)+Chr(10))
        MailResponse()   
        If MailResponse="250"
          Sleep_(125)
          MailDataSend("MAIL FROM: "+Chr(13)+Chr(10))
          MailResponse()
          If MailResponse="250"
            MailDataSend("RCPT TO: "+Chr(13)+Chr(10))
            MailResponse()
            If MailResponse="250"
              MailDataSend("DATA"+Chr(13)+Chr(10))
              MailResponse()
              If MailResponse="354"
                Sleep_(125)
                MailDataSend("Date: "+Chr(13)+Chr(10))
                MailDataSend("From: "+from$+Chr(13)+Chr(10))
                MailDataSend("To: "+recipient$+Chr(13)+Chr(10))
                MailDataSend("Subject: "+subject$+Chr(13)+Chr(10))
                Sleep_(125)
                MailDataSend(body$)
                Sleep_(125)
                MailDataSend(""+Chr(13)+Chr(10))
                MailDataSend("."+Chr(13)+Chr(10))
                MailResponse()
                If MailResponse="250"
                  Sleep_(125)
                  MailDataSend("QUIT"+Chr(13)+Chr(10))
                  MailResponse()
                  ProcedureReturn 1
                EndIf
              EndIf
            EndIf
          EndIf
        EndIf
      EndIf
      CloseNetworkConnection(MailID)
    EndIf
  EndIf 
EndProcedure
;
If MailSend("to@someone.com","Test","Did this work?","smtp.YOURISP.com.au","from@someone.com")
  Debug "Mail sent successfully!"
Else
  Debug "Error sending mail..."
EndIf


PB - Registered PureBasic Coder

Posted: Wed Sep 11, 2002 7:39 am
by BackupUser
Restored from previous forum. Originally posted by fweil.

PB,

This code is clean. If I can find one or two days in the near future, I will enhance it with some more features for attachments ... ring me back in 2 or 3 weeks if I miss. I have some pieces of it ready.

Rgrds

Francois Weil
14, rue Douer
F64100 Bayonne

Posted: Wed Sep 11, 2002 12:32 pm
by BackupUser
Restored from previous forum. Originally posted by tranquil.

Sorry PB, but receiving Datas through network like this:

Procedure.s MailResponse()
MailResponse=Space(9999)
ReceiveNetworkData(MailID,@MailResponse,9999)
MailResponse=Left(MailResponse,3)
ProcedureReturn MailResponse
EndProcedure

is not correctly!! You may loose Datas.
Sure, it works - but sometimes surely not!

If you send_() a datapacket through the network its possible more then one call of recv_() to receive it completely or you receive at least more then only the one packet couse the second one is addapted to the first packet. You know what I mean?

You have to check how many Bytes received from the network. ReceiveNetworkData returns the amount of received bytes.
If your Datapacket is not complete yet you have to wait for the next #FD_Read event from this socket and addapt the "possible" rest of the datas to the buffer you allocated for it. Importend is to set the awaited Packetsize to the ReceiveNetworkData() and not only 9999, this may couse that more then one datapacket is read into.

In your actual code you receive the datas everytime at @MailResponse which will be overwritten by every call. Now suggest the following circumstances:

You receive two Datapackets in your Buffer (eg 12 Bytes), you read the first three, process them, loop again. Possible the next Bytes are in the TCP/IP queue and the next event is in message-queue too, you receive the event, reads its datas to the beginning, you may overwrite your old datas now, they are lost.

Nearly every ppl in this forum made this mistake. I will code a little example how to send and receive datas correctly without loosing it. (espacially strings)

Receiving a File is much more then simple. Just call recv_() or receivenetworkdata() as long as the file is completed and attach the datas to the file. Here everything goes fine couse you did not have to interprate the received datas.

Hope this made networking a littlebit clear. Also your sleep_(xxx) are not needed - also hope you all understand my fuxxing english. :)

Cheers
Mike

Tranquilizer/ Secretly!
http://www.secretly.de
Registred PureBasic User

Posted: Wed Sep 11, 2002 2:34 pm
by BackupUser
Restored from previous forum. Originally posted by PB.

> Sure, it works - but sometimes surely not!

Hi Tranquil! The code was not my own, I just cleaned it up, so I had
no idea that it wasn't 100% safe to use. Thanks for telling me, and
for the lengthy explanation about it. :)

> Also your sleep_(xxx) are not needed

As above... I didn't put them there.

> hope you all understand my fuxxing english. :)

Yes, it made sense. Thanks!


PB - Registered PureBasic Coder

Posted: Sun Dec 18, 2005 8:06 am
by PB
Anyone know how to modify the above code to allow a login and password to
send mail? And attachments too would be nice. :) I've been trying with no luck.

Posted: Sun Dec 18, 2005 8:21 pm
by utopiomania
You can use Blat for sending email's with attachments. Don't know about the login/passwords.

Posted: Sun Dec 18, 2005 10:29 pm
by PB
> You can use Blat

I know. :) But I wanted to know how to modify the above to do it, as it seems
99% of the functionality is there, so adding a login and password shouldn't be
much harder.

(Besides, launching Blat will mean people will freak out when Kerio Personal
Firewall says: "MyApp.exe is launching Blat.exe" -- which I don't want).

Posted: Mon Dec 19, 2005 2:32 am
by okasvi
there is userlibs for that i guess...

and try sniffing the convo with ethereal while logging in with outlook or something... and RTFM! rfc***...