Lee,

I decided it was high time that I get familiar with emailing under Synapse,
so I took a look at what's available (in demo code) for binary
attachments---for those of us not really wanting (or able) to slug through
the SMTP RFCs just now... (someone's just gonna hafta tell me to go RTFM!
<g>) --- and found some helpful and some not-so-helpful things.

Since no one else answered the main "email with binary attachment" question
yet... Here's a very slightly modified simplistic demo routine I found at
http://www.delphil.szm.sk/prispevky/Call%20Stack%20v%20Runtime%20106398.htm

It would need some significant modifications for a number of things, like
sending multiple attachments, but it seems to nicely demonstrate the basic
requirements.

///////////////////
function SendEmail2(Afrom, Ato, Asubject, ASMTPHost, AUserName, APassWord,
                    AFileName: string; Atext: TStringList): boolean;
var
  m : TMimemess;
  MimeBody : TMimePart;
begin
  m := TMimemess.create;
  try
    if AFileName <> '' then begin
      MimeBody := M.AddPartMultiPart('mixed', nil);
      m.AddPartText(AText, MimeBody);
      m.AddPartBinaryFromFile(AFileName, MimeBody);
    end
    else m.AddPartText(AText, nil);
    m.header.from := AFrom; //'"Jan ?izek" <[EMAIL PROTECTED]>';
    m.header.tolist.add(ATo); //'[EMAIL PROTECTED]');
    m.header.subject := Asubject; // 'sislat zlu?oueky kuo Z?S Ii';
    m.EncodeMessage;
    Result := SendToRaw(AFrom, ATo, ASMTPhost, m.lines, AUserName,
APassWord);
  finally
    m.free;
  end;
end;
///////////////////

The first VERY INTERESTING thing about this AND all the other test routines
I created, is that they *always* fail UNLESS I make some call to
TTCPBlockSocket.ResolveNameToIP() before... and then it always succeeds.
I've spent some time looking for initialization code that I should be
calling elsewhere (???) but I can't find any.

I'd be quite grateful for any pointers on what I'm missing, or if it's a
library bug... I've come across initialization issues before, but was able
to resolve them. I'm not sure what's going on here. The call to
GetHostByName() in synsock.ResolveNameToIP fails with error 1060 unless
TTCPBlockSocket.ResolveNameToIP() was previously called...  Interesting...

-----------------------

While looking through some of the code I also notice some very strange
things in the MIMEPART unit in the following routine:

function GenerateBoundary: string;
var
  x, y: Integer;
begin
  y := GetTick;
  x := y;
  while TickDelta(y, x) = 0 do
  begin
    Sleep(1);
    x := GetTick;
  end;
  Randomize;
  y := Random(MaxInt);
  Result := IntToHex(x, 8) + '_' + IntToHex(y, 8) + '_Synapse_boundary';
end;

Maybe this is a secret weapon to slow down spammers' output... <g>, but it's
really a very improper use of Randomize (that can affect the main/calling
program's use of random numbers...), and then the whole GetTick and sleep()
loop is trying to reduce the problems introduced by calling Randomize.
Randomize is supposed to bring entropy into the pseudo random number
generator, but the Delphi/Borland one (like lots of others) uses the system
clock which is a VERY poor source of entropy to begin with, and worse if
called repeatedly. If a developer is aware of these issues, this will become
immediately obvious; if not, it will require some research and study. You
could also trust the advice of the Delphi Help entry where it says: "Do not
combine the call to Randomize in a loop with calls to the Random function.
Typically, Randomize is called only once, before all calls to Random."  In
fact, as with quite a few other libraries, there are several (few) calls to
Randomize in Synapse. They should all be removed; this should really only be
under the calling program's control--- or, at most, called once in a unit's
initialization section.

Repeatedly calling randomize actually REDUCES the randomness of random()
output. (That's part of one way that some online gambling houses were hacked
a few years ago.) And the other code in this routine dramatically slows
everything down. 5000 calls to the GenerateBoundary() routine alone (never
mind other email/mimemess... code) will take about 50 seconds!  (I was
guesstimating it would take 5 seconds with the 1 ms. sleep; haven't figured
out why it's taking 50.)

The following one-line replacement routine doubles the effective random
number range output. [The internals of the random functions actually treat
the seed and "integer" parameters as LongWord/DWORDs. So submitting -1 (or
an appropriately cast DWORD...) is like submitting 4,294,967,296, which is 2
* maxint.]

It's also likely to execute 5000 times on your computer in less than 10
milliseconds <g>...

function xGenerateBoundary: string;
begin
  Result := IntToHex(Random(-1), 8) + '_' + IntToHex(Random(-1), 8) +
'_Synapse_boundary';
end;



-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
synalist-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/synalist-public

Reply via email to