smtp - 2

Emma

Member
I have removed all references i can see from the code in relation to attachment formats, attachment names and mimeheader - all messages will be plain text. i have also removed all precedures including the one that was giving me the "invalid character in integer format c" error. i have recompiled both the .p and the .w that calls it. It is STILL giving me the error message above, even though there is no mention in the program of the variable "c".

the email log shows the following:

************** ****** New Group ******* ************
Socket email started
Input Parameters
EmailFrom = Emma.McDonald@capita.co.uk
EmailTo = Emma.McDonald@capita.co.uk,Laura.McDonald@capita.co.uk
EmailCC = Emma.McDonald@capita.co.uk
Subject = Testing from smtp
Body = Does this smtp stuff work? looks like it doesn't it! Hurray
01/18/02 16:17:02 opening socket
01/18/02 16:17:02 Socket Connection Established.
01/18/02 16:17:02 vstate 1
str 220-capitahrtnt01 Microsoft SMTP MAIL ready at Fri, 18 Jan 2002 16:18:57 +0000 Version: 5.5.1877.197.19

220 ESMTP spoken here


01/18/02 16:18:02 End SMTP Session
01/18/02 16:26:13
************** ****** New Group ******* ************
Socket email started
Input Parameters
EmailFrom = Emma.McDonald@capita.co.uk
EmailTo = Emma.McDonald@capita.co.uk,Laura.McDonald@capita.co.uk
EmailCC = Emma.McDonald@capita.co.uk
Subject = Testing from smtp
Body = Does this smtp stuff work? looks like it doesn't it! Hurray
01/18/02 16:26:13 opening socket
01/18/02 16:26:13 Socket Connection Established.
01/18/02 16:26:13 vstate 1
str 220-capitahrtnt01 Microsoft SMTP MAIL ready at Fri, 18 Jan 2002 16:28:08 +0000 Version: 5.5.1877.197.19

220 ESMTP spoken here


01/18/02 16:36:15
************** ****** New Group ******* ************
Socket email started
Input Parameters
EmailFrom = Emma.McDonald@capita.co.uk
EmailTo = Emma.McDonald@capita.co.uk,Laura.McDonald@capita.co.uk
EmailCC = Emma.McDonald@capita.co.uk
Subject = Testing from smtp
Body = Does this smtp stuff work? looks like it doesn't it! Hurray
01/18/02 16:36:15 opening socket
01/18/02 16:36:15 Socket Connection Established.
01/18/02 16:36:15 vstate 1
str 220-capitahrtnt01 Microsoft SMTP MAIL ready at Fri, 18 Jan 2002 16:38:10 +0000 Version: 5.5.1877.197.19

220 ESMTP spoken here


Does anyone know why it cannot carry on, or what ESMPT spoken here means?

i have attached the full procedure without the attachment code.

Can anyone work out why the email is not being sent ?

TIA,

Emma. :dead:
 

Attachments

  • smtpmail.p
    29.5 KB · Views: 41

swilson

New Member
We have tried using progress sockets as well for smtp communication. In the end we found an ActiveX smtp object that is easier to use and less confusing.

Cost around $300 but it was royalty free.
 
U

Unregistered

Guest
Progress sockets are simple and work well.

The following code is the code sample Progress have but I have changed it slightly, so that it can handle attachments. It works if the OS is windows or linux.

Put the following code in an include file. I called it sendmailvp.i

/* path to DOS program used for uuencoding the attachments.
As fcode is a DOS program, all file names should be 8 characters or less */
&SCOPED-DEFINE uuencode "c:\fcode -ue "

DEFINE VARIABLE vSMTP AS CHARACTER NO-UNDO.
DEFINE VARIABLE vTo AS CHARACTER NO-UNDO.
DEFINE VARIABLE vFrom AS CHARACTER NO-UNDO.
DEFINE VARIABLE vSubject AS CHARACTER NO-UNDO.
DEFINE VARIABLE vBody AS CHARACTER NO-UNDO.
DEFINE VARIABLE vFiles AS CHARACTER NO-UNDO.
DEFINE VARIABLE vBodyFile AS CHARACTER NO-UNDO.
DEFINE VARIABLE vChar AS CHARACTER NO-UNDO.
DEFINE VARIABLE hSocket AS HANDLE NO-UNDO.
DEFINE VARIABLE vBuffer AS MEMPTR NO-UNDO.
DEFINE VARIABLE vStatus AS LOGICAL NO-UNDO.
DEFINE VARIABLE vState AS INTEGER NO-UNDO.
DEFINE VARIABLE X AS INTEGER NO-UNDO.

PROCEDURE SendMail:

vstatus = hSocket:CONNECT("-S 25 -H " + vSMTP) NO-ERROR.
IF NOT vstatus THEN
vState = 99.
ELSE
vstate = 1.

REPEAT ON STOP UNDO, LEAVE ON QUIT UNDO, LEAVE:
IF vState < 0 OR vState = 7 OR vState = 99 THEN LEAVE.
WAIT-FOR READ-RESPONSE OF hSocket.
END.

END PROCEDURE.

PROCEDURE NewState:

DEFINE INPUT PARAMETER newState AS INTEGER.
DEFINE INPUT PARAMETER pstring AS CHARACTER.

vState = newState.
IF pstring = "" THEN
RETURN.

SET-SIZE(vBuffer) = LENGTH(pstring) + 1.
PUT-STRING(vBuffer,1) = pstring.
hSocket:WRITE(vBuffer, 1, LENGTH(pstring)).
SET-SIZE(vbuffer) = 0.

END PROCEDURE.

PROCEDURE ReadHandler:

DEFINE VARIABLE vlength AS INTEGER NO-UNDO.
DEFINE VARIABLE str AS CHARACTER NO-UNDO.
DEFINE VARIABLE v AS INTEGER NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.

vlength = hSocket:GET-BYTES-AVAILABLE().
IF vlength > 0 THEN
DO:
SET-SIZE(vBuffer) = vlength + 1.
hSocket:READ(vBuffer, 1, vlength, 1).
str = GET-STRING(vBuffer,1).
SET-SIZE(vBuffer) = 0.

v = INTEGER(ENTRY(1, str," ")).
CASE vState:
WHEN 1 THEN
IF v = 220 THEN
RUN newState(2, "HELO how are you? ~n").
ELSE
vState = -1.

WHEN 2 THEN
IF v = 250 THEN
RUN newState(3, "MAIL From: <" + vFrom + "> ~n").
ELSE
vState = -1.

WHEN 3 THEN
IF v = 250 THEN
DO i = 1 TO NUM-ENTRIES(vTo, ";"):
RUN newState(4, "RCPT TO: <" + ENTRY(i, vTo, ";") + "> ~n").
END.
ELSE
vState = -1.

WHEN 4 THEN
IF v = 250 THEN
RUN newState(5, "DATA" + "~n").
ELSE
vState = -1.

WHEN 5 THEN
IF v = 354 THEN
DO:
RUN newState(6, "From: " + vFrom + " ~n" + "To: " + vTo + " ~n" + "Subject: " + vSubject + " ~n~n"+ vBody + "~n").

DO X = 1 TO NUM-ENTRIES(vFiles,";"):
IF SEARCH(ENTRY(X, vFiles,";")) <> ? THEN
DO:
IF OPSYS = "win32" THEN
DOS SILENT VALUE({&uuencode} + ENTRY(X, vFiles,";")).
ELSE
UNIX SILENT VALUE("uuencode " + ENTRY(X, vFiles, ";")
+ " "
+ SUBSTRING(ENTRY(X, vFiles, ";"), R-INDEX(ENTRY(X, vFiles, ";"),"/") + 1)
+ " > "
+ SUBSTRING(ENTRY(X, vFiles, ";"), 1, R-INDEX(ENTRY(X, vFiles,";"),"."))
+ "uue").

vBodyFile = SUBSTRING(ENTRY(X, vFiles,";"), 1, R-INDEX(ENTRY(X, vFiles,";"),".")) + "uue".

INPUT FROM VALUE(vBodyFile).

REPEAT:
IMPORT UNFORMATTED vChar.
RUN newState(6, vChar + "~n").
END.

INPUT CLOSE.

IF OPSYS = "win32" THEN
DOS SILENT DEL VALUE(vBodyFile).
ELSE
UNIX SILENT rm VALUE(vBodyFile).
END.
END.

RUN newState(6, " ~n~n.~n").

END.
ELSE
vState = -1.

WHEN 6 THEN
IF v = 250 THEN
RUN newState(7,"QUIT~n").
ELSE
vState = -1.
END CASE.
END.

END PROCEDURE.


Then create a simple procedure like the one below:

{sendmailvp.i}

/* setup connection */
CREATE SOCKET hSocket.
hSocket:SET-READ-RESPONSE-PROCEDURE ("ReadHandler",THIS-PROCEDURE).


/* put code here to assign the following variables and send the mail*/
ASSIGN vSMTP = "10.10.10.10" /* ip address of mail server */
vTo = "you@you.com"
vFrom = "me@me.com"
vSubject = "this is the subject"
vBody = "this is the body"
vFiles = "c:\config.sys;c:\autoexec.bat". /* if linux then this will be "/home/example.exe;/home/data/test.sys" for example


/* send mail */
RUN SendMail.

IF vState = 7 THEN
/* message accepted */

IF vState < 0 THEN
/* message aborted */

IF vState = 99 THEN
/* server unavailable */


/* run cleanup */
hSocket:DISCONNECT() NO-ERROR.
DELETE OBJECT hSocket NO-ERROR.


This code has been tried and tested and works perfectly. If you have problems with it, let me know.
 
U

Unregistered

Guest
If you don't want to use Sockects to send mail and Outlook is installed on the PC, then you can use COM-HANDLES to connect to Outlook and send email via Outlook as well.
 

Emma

Member
Unregistered :

I have got the code working for single recipients and no attachments, which is brilliant. The thing is, i need to send them to multiple recipients, and cc. it's not vital to send file attachments at this time. is there any easy way to modify the code to do this. i also need to time stamp them.

Also, i don't understand about the &SCOPED-DEFINE uuencode "c:\fcode -ue " it complains about the file name *.uue not being found. What am i doing wrong?
Thanks again,

Emma.
 
U

Unregistered

Guest
First up the uue problem.

The reason why it can't find the uue file is because it has not created one. To send attachments using sockets, the file needs to be uuencoded and included in the body of the email. The email package that receives the email should then automatically decode the file as an attachment. Outlook and Outlook Express work fine.

The &SCOPED-DEFINE uuencode "c:\fcode -ue " is the part of the program that encodes the file. I'm assuming you are running on a Windows platform as Linux/Unix platform should use own uuencode command.

The c:\fcode -ue part, points to the file I use to encode the attachments. The program fcode is some freeware program I grabbed from the net to test my program as I am running on Linux, so don't need a DOS program for it to work.

What you need to do is find a uuencode program and then change the command "c:\fcode -ue " to the correct command to encode a file for the program you acquire. The problem with the fcode program is that it is a DOS program and does not support long file names.

So for example, if you manage to find a uuencode program called EncodeIt.exe and save it to your c: drive, the scoped-define would look like this:

&SCOPED-DEFINE uuencode "c:\EncodeIt.exe -encoptions "

-encoptions would be any of the required options that the program requires.

Your only problem now is to find a uuencode program that supports long file name.


Secondly, multiple recipients.

There is a problem with the code in that if you do:
ASSIGN vTo = "you@you.com;me@me.com"

it will only send to the first recipient or none at all, I can't remember which, as it was some time ago that I did the code.

The problem is still there because I have not got round to looking into it. However, the solution to send to multiple people is very simple in that you run the SendMail procedure for each recipient instead of just once for all recipients.

The updated code should look like this:

DEFINE VARIABLE vCount AS INTEGER NO-UNDO.
DEFINE VARIABLE vWhoTo AS STRING NO-UNDO.

{sendmailvp.i}

/* setup connection */
CREATE SOCKET hSocket.
hSocket:SET-READ-RESPONSE-PROCEDURE ("ReadHandler",THIS-PROCEDURE).


/* put code here to assign the following variables and send the mail*/
ASSIGN vSMTP = "10.10.10.10" /* ip address of mail server */
vWhoTo = "you@you.com;him@there.com"
vFrom = "me@me.com"
vSubject = "this is the subject"
vBody = "this is the body"
vFiles = "c:\config.sys;c:\autoexec.bat". /* if linux then this will be "/home/example.exe;/home/data/test.sys" for example


/* send mail */

DO vCount = 1 TO NUM-ENTRIES(vWhoTo, ";"):
vTo = ENTRY(vCount, vWhoTo, ";").
RUN SendMail.

IF vState = 7 THEN
/* message accepted */

IF vState < 0 THEN
/* message aborted */

IF vState = 99 THEN
/* server unavailable */

END.

/* run cleanup */
hSocketISCONNECT() NO-ERROR.
DELETE OBJECT hSocket NO-ERROR.


The code should work, however, I haven't tested it. I'll leave the hard work to you.


Thirdly, the CC issue.

I haven't looked into this yet but I can only assume that the code would need to be amended to include something similar to the section

WHEN 3 THEN
IF v = 250 THEN
DO i = 1 TO NUM-ENTRIES(vTo, ";"):
RUN newState(4, "RCPT TO: <" + ENTRY(i, vTo, ";") + "> ~n").
END.
ELSE
vState = -1.


I'm guessing, but it would probably be something like this:

WHEN 3.5 THEN
IF v = 250 THEN
DO i = 1 TO NUM-ENTRIES(vCC, ";"):
RUN newState(4.5, "RCPT CC: <" + ENTRY(i, vCC, ";") + "> ~n").
END.
ELSE
vState = -1.

Obviously, you wouldn't use 3.5 or 4.5, I was just trying to demonstrate that it would need to follow in a similar order to the current code.

I hope I have answered your questions.

If you still have problems, let me know.

Good Luck.
 
U

Unregistered

Guest
One final thing.

If you use COM-HANDLES to connect to Outlook, you won't have to worry about uuencoding the attachments. You would also be able to easily CC people as well.

The only downside is that you have to use Outlook.
 

Emma

Member
i have tried using mapi with outlook, and didn't manage to get this to work. is this what you are talking about when you say that i could use com-handles? i will keep you posted as to how i get on with the new info.

Thanks.
 
U

Unregistered

Guest
Here is the code I have used to send email and attachments using Outlook.

PROCEDURE SendMail :
/*------------------------------------------------------------------------------
Purpose:
Parameters: <none>
Notes:
------------------------------------------------------------------------------*/
DEFINE INPUT PARAMETER vAddress AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER vSubject AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER vBody AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER vAttach AS CHARACTER NO-UNDO.

DEFINE VARIABLE hNameSpace AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE hFolder AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE hOutlook AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE hOutlookMsg AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE hOutlookRecip AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE hOutlookAttach AS COM-HANDLE NO-UNDO.
DEFINE VARIABLE vShow AS LOGICAL NO-UNDO.
DEFINE VARIABLE X AS INTEGER NO-UNDO.

CREATE "Outlook.Application" hOutlook CONNECT NO-ERROR.

IF hOutlook = ? THEN
DO:
CREATE "Outlook.Application" hOutlook.
ASSIGN vShow = TRUE.
END.
ELSE
ASSIGN vShow = FALSE.

houtlookMsg = hOutlook:CreateItem(0).
hOutlookRecip = hOutlookMsg:Recipients:ADD(vAddress).
hOutlookRecip:TYPE = 1.

DO X = 1 TO NUM-ENTRIES(vAttach):
hOutlookAttach = hOutlookMsg:Attachments:ADD(ENTRY(X, vAttach)).
END.

hOutlookMsg:Subject = vSubject.
hOutlookMsg:Body = vBody.
/* hOutlookRecip:Resolve. */
hNameSpace = hOutlook:GetNamespace("MAPI").
/* 3 deleted items, 4 outbox, 5 sent items, 6 inbox */
hFolder = hNameSpace:GetDefaultFolder(4).

IF vShow THEN
hFolder:DISPLAY.

hOutlookMsg:DISPLAY.

/* hOutlookMsg:SEND. */ /* sends the email message */


RELEASE OBJECT hOutlookAttach NO-ERROR.
RELEASE OBJECT hOutlookRecip NO-ERROR.
RELEASE OBJECT hOutlookMsg NO-ERROR.
RELEASE OBJECT hFolder NO-ERROR.
RELEASE OBJECT hNameSpace NO-ERROR.
RELEASE OBJECT hOutlook NO-ERROR.

END PROCEDURE.


RUN "SendMail" (INPUT "me@address.com", INPUT "The Subject", INPUT "The body", INPUT "c:\config.sys,c:\autoexec.bat").


If you copy this code into the procedure window and run it, it should start up outlook and insert the email address, subject, body and any attachments. Clicking send in outlook will then send the email.

You can automatically send the email without any user intervention and outlook displaying, however, if you are sending large emails and attachments, Outlook closes before the email can be sent so it stays in the outbox until outlook is opened again and has a chance to send the email.

I did add some code to allow me to check the outbox for any files and only close outlook once all the files have been sent.
 

Emma

Member
i can't believe how uncomplicated it is, and how little code there is compared to some of the other stuff i have been looking at. I have got it working using mulitple recipients, of various classes. The problem i still have though is the address book feature. Is it possible to call this in a similar way?

Thanks again. You're a :star:

Emma.

:biggrin: :yippee: :wavey:
 
U

Unregistered

Guest
When you say the address book feature, I can only assume you are talking about Outlook's personal address book.

If you use the progress com object viewer and open the file Msoutl8.olb, you will see all the available methods & properties. There is a property in here called DContactItem. You should be able to use this to grab contact info from your Contacts folder.

You should also be able to find a property which will allow you to access your personal address book as well.
 
Top