comp.lang.ada
 help / color / mirror / Atom feed
* GNAT.Sockets writing data to nowhere...
@ 2009-03-01  1:32 xorquewasp
  2009-03-01  3:36 ` xorquewasp
  0 siblings, 1 reply; 3+ messages in thread
From: xorquewasp @ 2009-03-01  1:32 UTC (permalink / raw)


I've been trying, for a couple of frustrating hours now, to write a
very
simple Ada TCP/IP client that connects to an SMTP server and
delivers a message.

Apparently, data I'm writing to the socket is disappearing into a
void.

I can connect to localhost:25 and conduct an SMTP session using
netcat, so the problem isn't one of configuration.

Here's what I have right now:

-- smtp.ads

package SMTP is

  procedure Send_Mail
    (Server_Address : in String;
     Server_Port    : in Natural;
     Server_User    : in String;
     Server_Pass    : in String;
     Sender         : in String;
     Recipient      : in String;
     Data           : in String);

end SMTP;

-- smtp.adb

with GNAT.Sockets;
with Ada.Streams;
with Ada.Unchecked_Conversion;
with Ada.Strings.Unbounded;
with Ada.Text_IO;

package body SMTP is
  package Sockets renames GNAT.Sockets;
  package UB_Strings renames Ada.Strings.Unbounded;
  package Streams renames Ada.Streams;
  package Text_IO renames Ada.Text_IO;

  use type Streams.Stream_Element_Offset;

  --
  -- Write Data to Socket.
  --

  procedure Socket_Write
    (Socket  : Sockets.Socket_Type;
     Data    : in String)
  is
    subtype Source is String (Data'First .. Data'Last);
    subtype Target is Streams.Stream_Element_Array
      (Streams.Stream_Element_Offset (Data'First) ..
       Streams.Stream_Element_Offset (Data'Last));
    function Convert is new Ada.Unchecked_Conversion (Source, Target);

    Buffer : constant Streams.Stream_Element_Array := Convert (Data);
    Wrote  : Streams.Stream_Element_Offset;
  begin
    Sockets.Send_Socket
     (Socket => Socket,
      Item   => Buffer,
      Last   => Wrote);
    pragma Assert (Wrote = Buffer'Last);
  end Socket_Write;

  --
  -- Read data from Socket, return in Data
  --

  procedure Socket_Read
    (Socket : Sockets.Socket_Type;
     Data   : out UB_Strings.Unbounded_String)
  is
    Temp_Buffer : Streams.Stream_Element_Array (1 .. 256);
    Temp_Last   : Streams.Stream_Element_Offset;
  begin
    loop
      Sockets.Receive_Socket (Socket, Temp_Buffer, Temp_Last);
      declare
        subtype Source is Streams.Stream_Element_Array
          (Streams.Stream_Element_Offset (Temp_Buffer'First) ..
Temp_Last);
        subtype Target is String
          (Natural (Temp_Buffer'First) .. Natural (Temp_Last));
        function Convert is new Ada.Unchecked_Conversion (Source,
Target);
      begin
        UB_Strings.Append (Data,
          Convert (Temp_Buffer (Temp_Buffer'First .. Temp_Last)));
      end;
      exit when Temp_Last < Temp_Buffer'Last;
    end loop;
  end Socket_Read;

  --
  -- Connect to server at Server_Address:Server_Port, return
connection in Socket.
  --

  procedure Connect_To_Server
    (Server_Address : in String;
     Server_Port    : in Natural;
     Socket         : out Sockets.Socket_Type)
  is
    Address : Sockets.Sock_Addr_Type;
  begin
    Address.Port := Sockets.Port_Type (Server_Port);
    Address.Addr := Sockets.Addresses
      (Sockets.Get_Host_By_Name (Server_Address), 1);

    Sockets.Create_Socket (Socket);
    Sockets.Connect_Socket (Socket, Address);
  end Connect_To_Server;

  --
  -- Send mail Data to Recipient, from Sender, via
Server_Address:Server_Port,
  -- authenticating as Server_User with Server_Pass.
  --

  procedure Send_Mail
    (Server_Address : in String;
     Server_Port    : in Natural;
     Server_User    : in String;
     Server_Pass    : in String;
     Sender         : in String;
     Recipient      : in String;
     Data           : in String)
  is
    Socket       : Sockets.Socket_Type;
    Input_Buffer : UB_Strings.Unbounded_String;
  begin
    pragma Assert (Server_User /= "");
    pragma Assert (Server_Pass /= "");
    pragma Assert (Sender      /= "");
    pragma Assert (Recipient   /= "");
    pragma Assert (Data        /= "");

    Connect_To_Server (Server_Address, Server_Port, Socket);

    Socket_Read  (Socket, Input_Buffer);
    Text_IO.Put_Line ("-- read " & UB_Strings.To_String
(Input_Buffer));

    Socket_Write (Socket, "HELO " & Sockets.Host_Name);
    Text_IO.Put_Line ("-- wrote");

    Socket_Read  (Socket, Input_Buffer);
    Text_IO.Put_Line ("-- read " & UB_Strings.To_String
(Input_Buffer));
  end Send_Mail;

end SMTP;

-- smtp_client.adb

with SMTP;

procedure smtp_client is
begin
  SMTP.Send_Mail
    (Server_Address => "127.0.0.1",
     Server_Port    => 25,
     Server_User    => "me",
     Server_Pass    => "mypass",
     Sender         => "me@localhost",
     Recipient      => "me@localhost",
     Data           => "hello");
end smtp_client;

Here's a trace of the system calls:

 22630 smtp_client CALL  socket(0x2,0x1,0)
 22630 smtp_client RET   socket 3
 22630 smtp_client CALL  setsockopt(0x3,0xffff,0x800,0xbfbfe7d0,0x4)
 22630 smtp_client RET   setsockopt 0
 22630 smtp_client CALL  connect(0x3,0xbfbfe800,0x10)
 22630 smtp_client RET   connect 0
 22630 smtp_client CALL  recvfrom(0x3,0xbfbfe710,0x100,0,0,0)
 22630 smtp_client GIO   fd 3 read 34 bytes
       "220 pxrma.lambda78.c7.info ESMTP\r
       "
 22630 smtp_client RET   recvfrom 34/0x22
 22630 smtp_client CALL  write(0x1,0xbfbfe790,0x2b)
 22630 smtp_client GIO   fd 1 wrote 43 bytes
       "-- read 220 pxrma.lambda78.c7.info ESMTP\r

       "
 22630 smtp_client RET   write 43/0x2b
 22630 smtp_client CALL  __sysctl
(0xbfbfe7b8,0x2,0xbfbfe7e4,0xbfbfe7d4,0,0)
 22630 smtp_client RET   __sysctl 0
 22630 smtp_client CALL  sendto(0x3,0xbfbfe7b0,0x1b,0,0,0)
 22630 smtp_client GIO   fd 3 wrote 27 bytes
       "HELO pxrma.lambda78.c7.info"
 22630 smtp_client RET   sendto 27/0x1b
 22630 smtp_client CALL  write(0x1,0xbfbfe7b0,0x9)
 22630 smtp_client GIO   fd 1 wrote 9 bytes
       "-- wrote
       "
 22630 smtp_client RET   write 9
 22630 smtp_client CALL  recvfrom(0x3,0xbfbfe710,0x100,0,0,0)
 22630 smtp_client RET   recvfrom -1 errno 4 Interrupted system call
 22630 smtp_client PSIG  SIGINT SIG_DFL

Note that Ada believes it has written data (the sendto() call returns
27 bytes written). The server (Postfix, configured to dump the entire
conversation to the log) never sees the HELO message.
The response never comes (obviously) and I interrupt the recvfrom()
call with ^C.

Platform is FreeBSD 6.4, x86. GNAT FSF 4.3.2.

Any ideas what I'm doing wrong?



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: GNAT.Sockets writing data to nowhere...
  2009-03-01  1:32 GNAT.Sockets writing data to nowhere xorquewasp
@ 2009-03-01  3:36 ` xorquewasp
  2009-03-01  9:09   ` Pascal Obry
  0 siblings, 1 reply; 3+ messages in thread
From: xorquewasp @ 2009-03-01  3:36 UTC (permalink / raw)


On Mar 1, 1:32 am, xorquew...@googlemail.com wrote:
> I've been trying, for a couple of frustrating hours now, to write a
> very
> simple Ada TCP/IP client that connects to an SMTP server and
> delivers a message.

Solved.

Combination of misleading log messages from Postfix (saying that no
data had been received when in fact it just hadn't finished reading
a full message) and sending bare line feeds instead of <CR> <LF>.



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: GNAT.Sockets writing data to nowhere...
  2009-03-01  3:36 ` xorquewasp
@ 2009-03-01  9:09   ` Pascal Obry
  0 siblings, 0 replies; 3+ messages in thread
From: Pascal Obry @ 2009-03-01  9:09 UTC (permalink / raw)
  To: xorquewasp

xorquewasp@googlemail.com a �crit :
> Solved.

Another option is to use AWS which support SMTP and also POP.

Pascal.

-- 

--|------------------------------------------------------
--| Pascal Obry                           Team-Ada Member
--| 45, rue Gabriel Peri - 78114 Magny Les Hameaux FRANCE
--|------------------------------------------------------
--|    http://www.obry.net  -  http://v2p.fr.eu.org
--| "The best way to travel is by means of imagination"
--|
--| gpg --keyserver keys.gnupg.net --recv-key F949BD3B



^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-03-01  9:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-03-01  1:32 GNAT.Sockets writing data to nowhere xorquewasp
2009-03-01  3:36 ` xorquewasp
2009-03-01  9:09   ` Pascal Obry

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox