Recent

Author Topic: sending email not working  (Read 2556 times)

Awesome Programmer

  • Sr. Member
  • ****
  • Posts: 459
  • Programming is FUN only when it works :)
    • Cool Technology
sending email not working
« on: June 12, 2024, 08:21:04 pm »
my Lazarus compiler 2.0.0. Yes, Yes... I know it is sooooo old that I shouldn't use this version at all... lol... but it is working and compiling my code with NO ISSUES whatsoever. If I were to upgrade, it will break over 50% of all my components and LIBRARIES that means many of my codes/program will seize to compile forever. Just thought I'd let you all know, before you all jump on me for this... lol...  :D

Anyways, I am trying to use the msmtp terminal command to send email messages. I have searched online for this command and found a lot of good information and samples. So, I was able to come up with a  command line that works flawlessly. It sends email and I can even send SMS text message to smartphone. ONLY through TERMINAL or CONSOLE.

Code: Pascal  [Select][+][-]
  1. echo "Hello world" | msmtp --from=James@James.com 1234567899@tmomail.net

However, this same commandline code WILL NOT execute from within Lazarus. No message box pops up or gives any hints or errors. I don't get SMS or EMAIL message either. The function is below.

Code: Pascal  [Select][+][-]
  1. function SendMail:Boolean;
  2. var
  3.  sp:TProcess;
  4.  L:Tstringlist;
  5. begin
  6.   l:=tstringlist.create;
  7.     sp:= Tprocess.Create(nil);
  8.     try
  9.       sp.options:=[poUsePipes];
  10.       sp.executable := 'echo';
  11.       sp.Parameters.Add('"Hello World"');
  12.       sp.Parameters.Add('|');
  13.       sp.Parameters.Add('msmpt --from=james@james.com 1234567899@tmomail.net');
  14.       sp.execute;
  15.       l.SaveToStream(sp.Input);
  16.       l.clear;
  17.       l.LoadfromStream(sp.output);
  18.       writeln(l.text);
  19.     finally
  20.       sp.free;
  21.       l.free;
  22.     end;
  23.     result:=true;
  24. end;

Can someone tell me what is wrong with the above PASCAL CODE?

TRon

  • Hero Member
  • *****
  • Posts: 2915
Re: sending email not working
« Reply #1 on: June 12, 2024, 08:24:51 pm »
Can someone tell me what is wrong with the above PASCAL CODE?
TProcess is not a shell replacement.

Fibonacci

  • Sr. Member
  • ****
  • Posts: 453
  • Internal Error Hunter
Re: sending email not working
« Reply #2 on: June 12, 2024, 08:30:30 pm »
I guess you should run "msmtp", not "echo", and then send there your text with pipes

MarkMLl

  • Hero Member
  • *****
  • Posts: 7118
Re: sending email not working
« Reply #3 on: June 12, 2024, 08:58:17 pm »
Can someone tell me what is wrong with the above PASCAL CODE?

Yes, RTFM:

Quote
TProcess ... does not support complex pipelines as in Unix. If this behaviour is desired, the shell can be executed with the pipeline as the command it should execute.

https://www.freepascal.org/docs-html/current/fcl/process/index.html

Oh, and it's Pascal, not PASCAL.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Awesome Programmer

  • Sr. Member
  • ****
  • Posts: 459
  • Programming is FUN only when it works :)
    • Cool Technology
Re: sending email not working
« Reply #4 on: June 12, 2024, 10:08:27 pm »
Yes, RTFM:

LOL... for your information, I always do my best to read and re-read TFM. Sometimes, things don't always work like they say in the BOOK... I learned this after coding for over 20 years.

I came up with a workaround and it works; created a shell script file and then execute the script file from my Lazarus program.

 :D :D :D :D

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1355
    • Lebeau Software
Re: sending email not working
« Reply #5 on: June 12, 2024, 10:10:58 pm »
Can someone tell me what is wrong with the above PASCAL CODE?

echo is not an executable that you can run directly.  It is a built-in command of the terminal itself.  You are using the terminal's pipe operator to send the output of echo to the STDIN stream of the msmpt executable.  So you need to do the same thing with TProcess, eg:

Code: Pascal  [Select][+][-]
  1. function SendMail:Boolean;
  2. var
  3.   sp: TProcess;
  4.   L: TStringList;
  5. begin
  6.   L := TStringList.Create;
  7.   sp := TProcess.Create(nil);
  8.   try
  9.     sp.Options := [poUsePipes];
  10.     sp.Executable := 'msmtp';
  11.     sp.Parameters.Add('--from=james@james.com');
  12.     sp.Parameters.Add('1234567899@tmomail.net');
  13.     sp.Execute;
  14.     L.Text := 'Hello World';
  15.     L.SaveToStream(sp.Input);
  16.     L.Clear;
  17.     L.LoadFromStream(sp.Output);
  18.     WriteLn(L.Text);
  19.   finally
  20.     sp.free;
  21.     L.free;
  22.   end;
  23.   Result := true;
  24. end;
« Last Edit: June 14, 2024, 05:53:39 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

MarkMLl

  • Hero Member
  • *****
  • Posts: 7118
Re: sending email not working
« Reply #6 on: June 12, 2024, 10:28:43 pm »
Yes, RTFM:

LOL... for your information, I always do my best to read and re-read TFM. Sometimes, things don't always work like they say in the BOOK... I learned this after coding for over 20 years.

I came up with a workaround and it works; created a shell script file and then execute the script file from my Lazarus program.

 :D :D :D :D

Sorry :-) A shell script will work, but I've also used pipelines etc. to good effect by specifying the shell (sh, bash or WHY) explicitly.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

rvk

  • Hero Member
  • *****
  • Posts: 6276
Re: sending email not working
« Reply #7 on: June 12, 2024, 11:41:08 pm »
Can someone tell me what is wrong with the above PASCAL CODE?

echo is not an executable that you can run directly.  It is a built-in command of the terminal itself. 
Not an executable???

Code: Bash  [Select][+][-]
  1. pi@space01:~ $ whereis echo
  2. echo: /usr/bin/echo /usr/share/man/man1/echo.1.gz
  3. pi@space01:~ $ ls /usr/bin/echo -ltr
  4. -rwxr-xr-x 1 root root 35632 Sep 22  2020 /usr/bin/echo*
  5. pi@space01:~ $ file /usr/bin/echo
  6. /usr/bin/echo: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=bbd46f97ea84f6e4971a0cff6a54ffa85435f1a4, for GNU/Linux 3.7.0, stripped
  7.  

msmtp is a Linux command so I assume this is Linux and not Windows.

You are using the terminal's pipe operator to send the output of echo to the STDIN stream of the msmpt executable.
Yes, the problem in the original post is that the pipe and second command were given as parameter to the echo command. That doesn't work. You need a shell (bash, sh) to be able to use pipe like that. Or handle the input/output streams yourself.

Running this complete line as parameter itself with bash as command might be easier.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1355
    • Lebeau Software
Re: sending email not working
« Reply #8 on: June 13, 2024, 12:01:56 am »
echo is not an executable that you can run directly.  It is a built-in command of the terminal itself. 
Not an executable???

Code: Bash  [Select][+][-]
  1. pi@space01:~ $ whereis echo
  2. echo: /usr/bin/echo /usr/share/man/man1/echo.1.gz
  3. pi@space01:~ $ ls /usr/bin/echo -ltr
  4. -rwxr-xr-x 1 root root 35632 Sep 22  2020 /usr/bin/echo*
  5. pi@space01:~ $ file /usr/bin/echo
  6. /usr/bin/echo: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=bbd46f97ea84f6e4971a0cff6a54ffa85435f1a4, for GNU/Linux 3.7.0, stripped
  7.  

OK. It is an executable on some platforms, but not on others.  Doesn't change the rest of my earlier reply.  The code should not be executing echo but rather executing msmtp instead.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

MarkMLl

  • Hero Member
  • *****
  • Posts: 7118
Re: sending email not working
« Reply #9 on: June 13, 2024, 09:06:18 am »
OK. It is an executable on some platforms, but not on others.  Doesn't change the rest of my earlier reply.  The code should not be executing echo but rather executing msmtp instead.

Like time, echo exists as both a shell internal command and a binary.

So you're both right, stop snarling at each other :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Awesome Programmer

  • Sr. Member
  • ****
  • Posts: 459
  • Programming is FUN only when it works :)
    • Cool Technology
Re: sending email not working
« Reply #10 on: June 13, 2024, 05:16:11 pm »
Can someone tell me what is wrong with the above PASCAL CODE?

echo is not an executable that you can run directly.  It is a built-in command of the terminal itself.  You are using the terminal's pipe operator to send the output of echo to the STDIN stream of the msmpt executable.  So you need to do the same thing with TProcess, eg:

Code: Pascal  [Select][+][-]
  1. function SendMail:Boolean;
  2. var
  3.   sp: TProcess;
  4.   L: TStringList;
  5. begin
  6.   L := TStringList.Create;
  7.   sp := TProcess.Create(nil);
  8.   try
  9.     sp.Options := [poUsePipes];
  10.     sp.Executable := 'msmpt';
  11.     sp.Parameters.Add('--from=james@james.com');
  12.     sp.Parameters.Add('1234567899@tmomail.net');
  13.     sp.Execute;
  14.     L.Text := 'Hello World';
  15.     L.SaveToStream(sp.Input);
  16.     L.Clear;
  17.     L.LoadFromStream(sp.Output);
  18.     WriteLn(L.Text);
  19.   finally
  20.     sp.free;
  21.     L.free;
  22.   end;
  23.   Result := true;
  24. end;

Thanks Remy for your reply.

When I run your code, it hangs up on L.LoadFromStream(sp.Output);. The program doesn't freeze or crash. It is just sitting at that line for an output from the command, but there is NO output from the command. Command executes and exits without no output. So, I not sure why this is.

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1355
    • Lebeau Software
Re: sending email not working
« Reply #11 on: June 13, 2024, 06:52:32 pm »
When I run your code, it hangs up on L.LoadFromStream(sp.Output);. The program doesn't freeze or crash. It is just sitting at that line for an output from the command, but there is NO output from the command. Command executes and exits without no output. So, I not sure why this is.

Does the original command line output anything to begin with?

Try adding the poStdErrToOutPut flag in the Options. Maybe the send is failing and outputting an error that you are not receiving yet.
« Last Edit: June 13, 2024, 06:57:35 pm by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

rvk

  • Hero Member
  • *****
  • Posts: 6276
Re: sending email not working
« Reply #12 on: June 13, 2024, 07:20:06 pm »
I'm not familiar with TProcess.Option poUsePipes but shouldn't you first write the TProcess.Input to the stream before you do TProcess.Execute?

(I don't think msmpt will wait for inout but just ends if the input is empty.)


MarkMLl

  • Hero Member
  • *****
  • Posts: 7118
Re: sending email not working
« Reply #13 on: June 13, 2024, 07:33:40 pm »
I did this a few days ago, and have put a few Gb of text lines through the resulting streams:

Code: Pascal  [Select][+][-]
  1.     processObject := TProcess.Create(nil);
  2.     processObject.Executable := binPath + binName;
  3.     processObject.Options := [poUsePipes];
  4.     processObject.Execute;
  5.     Sleep(100);
  6.     if processObject.Running then begin
  7.       StatusBar := 'Starting...';
  8.       idleTimer1.Enabled := true
  9.     end else
  10.       FreeAndNil(processObject);        
  11. ...
  12.       FilterStreamToLines(ProcessObject.StdErr, lineStdErr, @stdErrLineCallback, true        , 0              );
  13.       FilterStreamToLines(ProcessObject.Output, lineOutput, @outputLineCallback, false        , 0              )
  14.  

and

Code: Pascal  [Select][+][-]
  1. procedure FilterStreamToLines(const inputStream: TInputPipeStream; var line: ansistring;
  2.                         callback: PerLineCallback; timestamp: boolean= false; device: integer= -1);
  3. var
  4.   ch: ansichar;
  5.  
  6. begin
  7. { TODO : Read more than one character per loop. }
  8.    while inputStream.NumBytesAvailable > 0 do begin
  9.     inputStream.Read(ch, 1);
  10.     case ch of
  11. ...
  12.  

So it does work reliably.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

rvk

  • Hero Member
  • *****
  • Posts: 6276
Re: sending email not working
« Reply #14 on: June 13, 2024, 07:49:55 pm »
But isn't that for output streams.

Here the "hello world" is the inputstream filled AFTER Execute.
And if the command sees there is no bytes in the inputstream it could quit directly.
So my guess was that you first need to begin filling the inputstream before you do Execute.

Unless the command really waits before any input (which isn't certain).
« Last Edit: June 13, 2024, 07:51:35 pm by rvk »

 

TinyPortal © 2005-2018