home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / defdata / smtpwict.src < prev    next >
Encoding:
Text File  |  1988-05-03  |  75.2 KB  |  2,240 lines

  1. --::::::::::::::
  2. --cycle.txt
  3. --::::::::::::::
  4. -----------------------------------------------------------------------
  5. --
  6. --         DoD Protocols    NA-00010-200       80-01217-100(-)
  7. --         E-Systems, Inc.  August 07, 1985
  8. --
  9. --         cycle.txt       Author : Paul Higgins
  10. --
  11. -----------------------------------------------------------------------
  12. with subnet_controller_task ;    use subnet_controller_task ;
  13. with internet_protocol_control_and_send_processing ;
  14. use internet_protocol_control_and_send_processing ;
  15. with tcp_controller_task ;    use tcp_controller_task ;
  16. package  cycle  is
  17.   procedure tcp_ip_subnet ;
  18. end cycle ;
  19. package body  cycle  is
  20.   procedure tcp_ip_subnet is
  21.   begin
  22.     -- first, go for data coming into the node from Ethernet
  23.     subnet_controller ;
  24.     ip_controller ;
  25.     subnet_controller ;
  26.     tcp_controller ;
  27.     subnet_controller ;
  28.   end tcp_ip_subnet ;
  29. end cycle ;
  30. --::::::::::::::
  31. --sconn.txt
  32. --::::::::::::::
  33. -----------------------------------------------------------------------
  34. --
  35. --         DoD Protocols    NA-00010-200       80-01218-100(-)
  36. --         E-Systems, Inc.  August 07, 1985
  37. --
  38. --         sconn.txt       Author : Paul Higgins
  39. --
  40. -----------------------------------------------------------------------
  41. package ssmtp_connections is
  42. --
  43. -- This package contains support for establishing the connection
  44. --  between the ssmtp and a usmtp.
  45. --
  46. procedure establish_transport_connection ;
  47. --
  48. -- This procedure sets up the transport connection between the
  49. -- ssmtp and a usmtp. It waits for a usmtp to call it, performs
  50. -- any handshaking required, and sends the ssmtp greeting reply.
  51. --
  52. procedure establish_sender ;
  53. --
  54. -- this procedure gets the helo command from the usmtp and saves the
  55. -- usmtp host string. Currently does not verify the host name string.
  56. --
  57. end ssmtp_connections ;
  58. with ssmtp_transport ;    use ssmtp_transport ;
  59. with ssmtp_globals ;      use ssmtp_globals ;
  60. with ssmtp_replies ;      use ssmtp_replies ;
  61. with text_io ;            use text_io ;
  62. with ssmtp_logger ;       use ssmtp_logger ;
  63. package body ssmtp_connections is
  64. --
  65. --   Implementation for :  Labtek WICAT
  66. --                         TeleSoft/Ada (Version 1.3)
  67. --                         tcp transport service
  68. --
  69. procedure establish_transport_connection is
  70. done : boolean := false;    --&KJW 16-jul85
  71. begin
  72. if not transport_connection_open then
  73.   send_passive_open ;
  74.   wait_for_open ;
  75.   end if ;
  76. --&KJW 16-jul-85 loop
  77. while NOT done loop    --&KJW 16-jul85
  78.   begin
  79.     send_ready_message ;
  80.     reset_receive_buffers ;
  81.     get_command ;
  82.     if command = "helo" then
  83.       source_host := command_parms ; -- save the "from" address as is
  84.       send_helo_ok ;
  85.       --&KJW 16-jul-85 exit ;
  86.       done := true;    --&KJW 16-jul85
  87.     else
  88.         bad_command ;
  89.     end if ;
  90.   exception
  91.     when ssmtp_reset =>
  92.       put_line("RSET received") ;
  93.     when others =>
  94.       error_log ("Exception in ssmtp connection") ;
  95.       raise ;
  96.   end ;
  97. end loop ;
  98. end ;
  99. procedure establish_sender is
  100. begin
  101.   get_command ;
  102.   if command = "mail" then
  103.     source_name := command_parms ;
  104.     send_mail_ok ;
  105.   else
  106.     bad_command ;
  107.   end if ;
  108.   exception
  109.     when ssmtp_reset =>
  110.       put_line("RSET received") ;
  111.     when others =>
  112.       error_log ("Exception in establish sender") ;
  113.       raise ;
  114.   end establish_sender ;
  115. end ssmtp_connections ;
  116. --::::::::::::::
  117. --sdel.txt
  118. --::::::::::::::
  119. -----------------------------------------------------------------------
  120. --
  121. --         DoD Protocols    NA-00010-200       80-01219-100(-)
  122. --         E-Systems, Inc.  August 07, 1985
  123. --
  124. --         sdel.txt       Author : Paul Higgins
  125. --
  126. -----------------------------------------------------------------------
  127. package ssmtp_deliver is
  128. procedure deliver_mail ;
  129. end ssmtp_deliver ;
  130. with ssmtp_globals ;   use ssmtp_globals ;
  131. with ssmtp_logger ;    use ssmtp_logger ;
  132. with ssmtp_replies ;   use ssmtp_replies ;
  133. with text_io ;         use text_io ;
  134. with system;           use system ;
  135. package body ssmtp_deliver is
  136. procedure copy_mail(user_name : user_name_type; ok : out boolean ) is
  137. --&KJW 16-jul-85 smtp_mail : file_type ;
  138. begin
  139.   --&KJW 16-jul-85 put("deliver mail to...") ;
  140.   text_io.put("deliver mail to...") ;    --&KJW 16-jul-85
  141.   --&KJW 16-jul-85 put_line(user_name) ;
  142.   text_io.put_line(user_name) ;        --&KJW 16-jul-85
  143.   ok := true ;
  144.   --&KJW 16-jul-85 create(smtp_mail,out_file,"smtp_mail.txt") ;
  145.   for i in 1..message_length loop
  146.     --&KJW 16-jul-85 put_line(smtp_mail,message(i).message_line(1..message(i).line_length)) ;
  147.     --&KJW 16-jul-85 put_line(message(i).message_line(1..message(i).line_length)) ;
  148.     text_io.put_line(message(i).message_line(1..message(i).line_length)) ;--&KJW 16-jul-85
  149.   end loop ;
  150.   --&KJW 16-jul-85 close(smtp_mail) ;
  151.   exception
  152.     when others => 
  153.       error_log("Exception in copy mail");
  154.   end ;
  155. procedure deliver_mail is
  156. all_ok, delivered_ok : boolean := true ;
  157. --&KJW 16-jul-85 rcpt_file : file_type ;
  158. begin
  159.   --&KJW 16-jul-85 create(rcpt_file,out_file,"rcpt_list.txt") ;
  160.   for i in 1..number_of_rcpt loop
  161.     --&KJW 16-jul-85 put_line(rcpt_file,rcpt_list(i)) ;
  162.     copy_mail(rcpt_list(i),delivered_ok);
  163.     all_ok := delivered_ok and all_ok ;
  164.   end loop ;
  165.   if all_ok then
  166.     send_completed_ok ;
  167.   else
  168.     send_completed_not_ok ;
  169.   end if ;
  170.   exception
  171.     when others => 
  172.       error_log("Exception in copy mail");
  173. end ;
  174. end ssmtp_deliver ;
  175. --::::::::::::::
  176. --sglobs.txt
  177. --::::::::::::::
  178. -----------------------------------------------------------------------
  179. --
  180. --         DoD Protocols    NA-00010-200       80-01220-100(-)
  181. --         E-Systems, Inc.  August 07, 1985
  182. --
  183. --         sglobs.txt       Author : Paul Higgins
  184. --
  185. -----------------------------------------------------------------------
  186. package ssmtp_globals is
  187. -- here are the conditions which interrupt 
  188. --  normal flow of control:
  189. sudden_connection_close : exception ;
  190.  -- connection closed or connection aborted
  191. transport_error         : exception ;
  192.  -- unexpected message from transport 
  193. ssmtp_reset             : exception ;
  194.  -- reset command received
  195. ssmtp_quit              : exception ;
  196.  -- quit command received 
  197. --&KJW 21-jul-85 transport_connection_open : boolean ;
  198. transport_connection_open : boolean := false ;  --&KJW 21-jul-85 
  199.  -- state of the transport connection
  200. --
  201. -- this is to support the list of local receivers
  202. -- smtp_rcpt creates this list
  203. -- smtp_deliver uses it 
  204. --
  205. subtype user_name_type is string (1..80) ;
  206. subtype host_name_type is string (1..80) ;
  207. max_rcpt           : constant integer := 80 ;
  208. rcpt_list          : array (1..max_rcpt) of user_name_type ;
  209. number_of_rcpt     : integer range 0..max_rcpt ;
  210. source_host        : host_name_type ;
  211. source_host_length : integer range 0..80 ;
  212. source_name        : user_name_type ;
  213. source_name_length : integer range 0..80 ;
  214. --
  215. -- used to parse the smtp commands
  216. --
  217. max_command_length : constant integer := 80 ;
  218. command            : string (1..4) ;
  219.   -- 4 letter smtp command, lower case
  220. command_parms      : string (1..max_command_length) ;
  221.   -- the rest of the received command
  222. parm_length        : integer range 0..max_command_length ;
  223. --
  224. -- where the mail message is saved 
  225. --
  226. type lines is record
  227.   message_line : string(1..512) ;
  228.   line_length  : integer ;
  229.   end record ;
  230. max_message_length : constant integer := 2048 ;
  231. message            : array (1..max_message_length) of lines ;
  232. message_length     : integer ;
  233. procedure reset_receive_buffers ;
  234.   -- prepare to receive a new message
  235. end ssmtp_globals ;
  236. package body ssmtp_globals is
  237. procedure reset_receive_buffers is
  238.   begin
  239.   number_of_rcpt := 0 ;
  240.   message_length := 0 ;
  241. end reset_receive_buffers ;
  242. end ssmtp_globals ;
  243. --::::::::::::::
  244. --slog.txt
  245. --::::::::::::::
  246. -----------------------------------------------------------------------
  247. --
  248. --         DoD Protocols    NA-00010-200       80-01221-100(-)
  249. --         E-Systems, Inc.  August 07, 1985
  250. --
  251. --         slog.txt       Author : Paul Higgins
  252. --
  253. -----------------------------------------------------------------------
  254. package ssmtp_logger is
  255. procedure error_log (msg : string) ;
  256. end ssmtp_logger ;
  257. -- debug version
  258. with text_io ; use text_io ;
  259. package body ssmtp_logger is
  260. procedure error_log (msg : string) is
  261. begin
  262. --- may also record connection info, such as usmtp host, usmtp name, etc
  263. put_line(msg) ;
  264. end error_log ;
  265. end ssmtp_logger ;
  266. --::::::::::::::
  267. --srcpt.txt
  268. --::::::::::::::
  269. -----------------------------------------------------------------------
  270. --
  271. --         DoD Protocols    NA-00010-200       80-01222-100(-)
  272. --         E-Systems, Inc.  August 07, 1985
  273. --
  274. --         srcpt.txt       Author : Paul Higgins
  275. --
  276. -----------------------------------------------------------------------
  277. package ssmtp_rcpt is
  278.   procedure expect_rcpt_list ;
  279. end ssmtp_rcpt ;
  280. with ssmtp_transport ;    use ssmtp_transport ;
  281. with ssmtp_globals ;      use ssmtp_globals ;
  282. with ssmtp_replies ;      use ssmtp_replies ;
  283. with text_io ;            use text_io ;
  284. with ssmtp_logger ;       use ssmtp_logger ;
  285. package body ssmtp_rcpt is
  286. -- this table is system dependent, not really the best method
  287. done : boolean := false;    --KJW 16-jul-85
  288. blank_name : user_name_type ;    --KJW 16-jul-85
  289. max_users : integer := 100 ;
  290. user_name_table : array (1..max_users) of user_name_type ;
  291. number_of_users : integer ;
  292. procedure lookup_user_name(name       : in  user_name_type ;
  293.                            user_local : out boolean) is
  294. --- look up user in list 
  295. --- could make system call if available
  296. begin
  297. --&KJW 23-jul-85 put("looking up ") ;
  298. --&KJW 23-jul-85 put_line(name) ;
  299. user_local := false ;
  300. for i in 1..number_of_users loop
  301.   if user_name_table(i) = name then
  302.     user_local := true ;
  303.     exit ;
  304.   end if ;
  305. end loop ;
  306. exception 
  307. when others =>
  308.   error_log("exception in lookup_user_name") ;
  309.   raise ;
  310. end lookup_user_name ;
  311. procedure parse_user_name(user_local : out boolean;
  312.                           user_name  : out user_name_type) is
  313. ptr : integer := 0 ;
  314. name : user_name_type := blank_name ;    --&KJW 16-jul-85
  315. begin
  316. user_name := blank_name ;        --&KJW 16-jul-85
  317. user_local := false ;
  318. for i in 1..parm_length loop
  319.   if command_parms(i) /= ' ' then
  320.     ptr := i ;
  321.     exit ;
  322.   end if ;
  323. end loop ;
  324. if ((ptr /= 0) and (ptr <= parm_length+3)) and then
  325.     command_parms(ptr..ptr+2) = "to:" then
  326.   for i in 1..(parm_length-(ptr+3)) loop 
  327.     name(i) := command_parms(i+ptr+3) ;
  328.   end loop ;
  329.   lookup_user_name(name,user_local) ; 
  330.   user_name := name ;
  331. else 
  332.   put("bad format rcpt: ") ;
  333.   put_line(command_parms) ;
  334. end if ;
  335. exception 
  336. when others =>
  337.   error_log("exception in parse_user_name") ;
  338.   raise ;
  339. end parse_user_name ;
  340. procedure expect_rcpt_list is
  341.   user_local : boolean ;
  342.   user_name  : user_name_type ;
  343.   begin
  344.   loop
  345.     get_command ;
  346.     if command = "rcpt" then
  347.       parse_user_name(user_local,user_name) ;
  348.       if not user_local then
  349.         send_rcpt_not_ok  ;
  350.       else
  351.         if number_of_rcpt < max_rcpt then
  352.           number_of_rcpt := number_of_rcpt + 1 ;
  353.           --&KJW 16-jul-85 rcpt_list(number_of_rcpt) := (others => ' ') ;
  354.           rcpt_list(number_of_rcpt) := blank_name ;    --&KJW 16-jul-85
  355.           rcpt_list(number_of_rcpt) := user_name ;
  356.           send_rcpt_ok ;
  357.         else
  358.           send_no_room ;
  359.         end if ;
  360.       end if ;
  361.     elsif command = "data" then
  362.       exit ;
  363.     else
  364.       bad_command ;
  365.     end if ;
  366.     end loop ;
  367.   exception
  368.     when ssmtp_reset =>
  369.       put_line("Reset in establish_rcpt");
  370.       raise ssmtp_reset ;
  371.     when ssmtp_quit =>
  372.       put_line("Reset in establish_rcpt");
  373.       raise ssmtp_quit ;
  374.     when others =>
  375.       error_log("exception in establish_rcpt");
  376.       raise ;
  377. end expect_rcpt_list ;
  378. begin
  379. --&KJW 11-jul-85 user_name_table(1)       := (others => ' ') ;
  380. --&KJW 11-jul-85 user_name_table(1)(1..7) := "higgins" ;
  381. --&KJW 11-jul-85 user_name_table(2)       := (others => ' ') ;
  382. --&KJW 11-jul-85 user_name_table(2)(1..6) := "thomas" ;
  383. --&KJW 11-jul-85 user_name_table(3)       := (others => ' ') ;
  384. --&KJW 11-jul-85 user_name_table(3)(1..5) := "baldo" ;
  385. --&KJW 11-jul-85 user_name_table(3)       := (others => ' ') ;
  386. --&KJW 11-jul-85 user_name_table(3)(1..7) := "noscada" ;
  387. --&KJW 11-jul-85 number_of_users := 4 ;
  388. -- Read user names into user_name_table from file "usernames.lcl".
  389. -- Each installation can configure allowable user identifiers via this file.
  390. -- If the open for the file fails, then it is either in use (i.e. being editted)
  391. -- or does not exist.  This version of the SMTP server cannot continue if there 
  392. -- are no local users since it does not forward mail to another node.
  393. for char in 1..80 loop        --&KJW 16-jul-85
  394.   blank_name(char) := ' ';    --&KJW 16-jul-85
  395. end loop;            --&KJW 16-jul-85
  396. while not done            --&KJW 16-jul-85
  397. loop
  398.   declare
  399.     name_file : file_type ;
  400.     last,index : natural ;
  401.   begin
  402.     open(name_file,in_file,"usernames.lcl") ;
  403.     number_of_users := 0 ;
  404.     while not end_of_file(name_file) loop
  405.       index := number_of_users + 1;
  406.       get_line (name_file, user_name_table(index), last) ;
  407.       -- user names can be in any form; but they must NOT be preceeded by any
  408.       -- "white space" (this implementation won't look for it or discard it).
  409.       -- the length of a user name must NOT exceed the space reserved for it in
  410.       -- the user_name_table (regardless of the unused space in other names).
  411.       -- comments in the name table are introduced as Ada-style comments; how-
  412.       -- ever, the two hyphens must be the first two characters in the line.
  413.       if user_name_table(index)(1..2) /= "--" then
  414.         --KJW 16-jul-85 user_name_table(index)(last+1 .. user_name_table(index)'Last) 
  415.         --KJW 16-jul-85     := (others => ' ') ;
  416.         for char in last+1..80 loop        --KJW 16-jul-85
  417.           user_name_table(index)(char) := ' ';    --KJW 16-jul-85
  418.         end loop;                --KJW 16-jul-85
  419.         number_of_users := index ;
  420.       end if ;
  421.       exit when number_of_users >= max_users ;
  422.     end loop ;
  423.     close(name_file) ;
  424.     --&KJW 16-jul-85 exit ;
  425.     done := true;        --&KJW 16-jul-85
  426.   exception
  427.     when status_error =>    -- file is open; try again later
  428.       --&KJW 16-jul-85 delay 30.0;
  429.       put_line("status_error in package body ssmtp_rcpt elaboration.") ;        --&KJW 16-jul-85
  430.       raise;            --&KJW 16-jul-85
  431.     when name_error =>        -- file does not exist
  432.       put_line("could not find file 'usernames.lcl'" & 
  433.                " in package body ssmtp_rcpt") ;
  434.       raise ;
  435.     when others =>        -- ???
  436.       put_line("unknown exception in package body ssmtp_rcpt elaboration.") ;
  437.       close(name_file) ;    -- just in case it was open
  438.       raise;
  439.   end ;
  440. end loop ;
  441. end ssmtp_rcpt;
  442. --::::::::::::::
  443. --sreps.txt
  444. --::::::::::::::
  445. -----------------------------------------------------------------------
  446. --
  447. --         DoD Protocols    NA-00010-200       80-01223-100(-)
  448. --         E-Systems, Inc.  August 07, 1985
  449. --
  450. --         sreps.txt       Author : Paul Higgins
  451. --
  452. -----------------------------------------------------------------------
  453. package ssmtp_replies is
  454. procedure send_ready_message ;
  455. procedure send_helo_ok ;
  456. procedure send_mail_ok ;
  457. procedure send_rcpt_ok ;
  458. procedure send_rcpt_not_ok ;
  459. procedure send_no_room ;
  460. procedure send_data_ok ;
  461. procedure send_completed_ok ;
  462. procedure send_completed_not_ok ;
  463. procedure send_quit_ok ;
  464. procedure bad_command ;
  465. end ssmtp_replies ;
  466. with ssmtp_transport ; use ssmtp_transport ;
  467. with text_io ;         use text_io ;
  468. with ssmtp_logger ;    use ssmtp_logger ;
  469. with ssmtp_globals ;   use ssmtp_globals ;
  470. package body ssmtp_replies is
  471. procedure send_ready_message is
  472.   begin
  473.   send_string("220  SMTP mail service ready") ;
  474.   exception
  475.     when others =>
  476.       error_log ("Exception in send_ready_message") ;
  477.   end send_ready_message ;
  478. procedure send_helo_ok is
  479.   begin
  480.   send_string("250 Helo ok") ;
  481.   exception
  482.     when others =>
  483.     error_log  ("Exception in send_helo_ok") ;
  484.   end send_helo_ok ;
  485. procedure send_mail_ok is
  486.   begin
  487.   send_string("250 mail ok") ;
  488.   exception
  489.     when others =>
  490.     error_log  ("Exception in send_mail_ok") ;
  491.   end send_mail_ok ;
  492. procedure send_rcpt_ok is
  493.   begin
  494.   send_string("250 rcpt ok") ;
  495.   exception
  496.     when others =>
  497.       error_log  ("Exception in send_rcpt_ok") ;
  498.   end send_rcpt_ok ;
  499. procedure send_rcpt_not_ok is
  500.   begin
  501.   send_string("550 User not local, cannot forward") ;
  502.   exception
  503.     when others =>
  504.       error_log  ("Exception in send_rcpt_not_ok") ;
  505.   end send_rcpt_not_ok ;
  506. procedure send_no_room is
  507.   begin
  508.   send_string("501 out of resources") ;
  509.   error_log("Ran out of resources") ;
  510.   exception
  511.     when others =>
  512.       error_log  ("Exception in send_no_room ") ;
  513.   end send_no_room ;
  514. procedure send_data_ok is
  515.   begin
  516.   send_string("354 begin data... ") ;
  517.   exception
  518.     when others =>
  519.       error_log  ("Exception in send_data_ok") ;
  520.   end send_data_ok ;
  521. procedure send_completed_ok is
  522.   begin
  523.   send_string("250 mail sent") ;
  524.   exception
  525.     when others =>
  526.       error_log  ("Exception in send_completed_ok") ;
  527.   end send_completed_ok ;
  528. procedure send_completed_not_ok is
  529.   begin
  530.   send_string("250 mail not sent to some recipients ") ;
  531.   exception
  532.     when others =>
  533.       error_log  ("Exception in send_completed_not_ok") ;
  534.   end send_completed_not_ok ;
  535. procedure send_quit_ok is
  536.   begin
  537.   send_string("221 SMTP closing connection") ;
  538.   exception
  539.     when others =>
  540.       error_log  ("Exception in send_quit_ok") ;
  541.   end send_quit_ok ;
  542. procedure bad_command is
  543.   begin
  544.   if command = "rset" then
  545.     raise ssmtp_reset ;
  546.   elsif command = "quit" then
  547.     raise ssmtp_quit ;
  548.   else
  549.     send_string("451 Unexpected or unimplemented command") ;
  550.   end if ;
  551.   exception
  552.     when ssmtp_reset | ssmtp_quit =>
  553.       raise ;
  554.     when others =>
  555.       error_log ("Exception in bad_command") ;
  556.       raise ;
  557.   end bad_command ;
  558.   
  559. end ssmtp_replies ;
  560. --::::::::::::::
  561. --ssmtp.txt
  562. --::::::::::::::
  563. -----------------------------------------------------------------------
  564. --
  565. --         DoD Protocols    NA-00010-200       80-01224-100(-)
  566. --         E-Systems, Inc.  August 07, 1985
  567. --
  568. --         ssmtp.txt       Author : Paul Higgins
  569. --
  570. -----------------------------------------------------------------------
  571. with real_time_clock_and_date;
  572. use real_time_clock_and_date;
  573. with text_io;            use text_io ;
  574. with ssmtp_globals ;     use ssmtp_globals ;
  575. with ssmtp_replies ;     use ssmtp_replies ;
  576. with ssmtp_connections ; use ssmtp_connections ;
  577. with ssmtp_transport ;   use ssmtp_transport ;
  578. with ssmtp_rcpt ;        use ssmtp_rcpt ;
  579. with ssmtp_text ;        use ssmtp_text ;
  580. with ssmtp_deliver ;     use ssmtp_deliver ;
  581. with ssmtp_logger ;      use ssmtp_logger ;
  582. with buffer_data ;       use buffer_data ;
  583. procedure ssmtp is
  584. begin
  585.   start_local_clock;
  586.   buffer_data.init ;
  587.   loop
  588.     begin
  589.     establish_transport_connection ;
  590.     establish_sender ;
  591.     loop
  592.       begin
  593.       reset_receive_buffers ;
  594.       expect_rcpt_list ;
  595.       expect_text ;
  596.       deliver_mail ;
  597.       exception
  598.         when ssmtp_reset =>
  599.           put_line("reset received") ;
  600.           --send_reset_ok ;
  601.       end ;
  602.       end loop ;
  603.   exception
  604.     when ssmtp_quit =>
  605.       put_line("quit received") ;
  606.       send_quit_ok ;
  607.       close_connection ;
  608.       -- EXIT ;    -- for VAX/VMS  O N L Y !!! (let command file distribute mail)
  609.     when ssmtp_reset =>
  610.       put_line("reset received") ;
  611.       --send_reset_ok ;
  612.     when sudden_connection_close =>
  613.       put_line("Transport connection closed") ;
  614.     when transport_error =>
  615.       put_line("Transport error ") ;
  616.     when others =>
  617.       error_log ("Unknown exception in server smtp... exiting") ;
  618.       raise ;
  619.    end ;
  620.   end loop ;
  621. end ssmtp ;
  622. --::::::::::::::
  623. --stext.txt
  624. --::::::::::::::
  625. -----------------------------------------------------------------------
  626. --
  627. --         DoD Protocols    NA-00010-200       80-01225-100(-)
  628. --         E-Systems, Inc.  August 07, 1985
  629. --
  630. --         stext.txt       Author : Paul Higgins
  631. --
  632. -----------------------------------------------------------------------
  633. package ssmtp_text is
  634. procedure expect_text ;
  635. -- this program reads in mail from the transport layer and stores them
  636. --  into ssmtp_globals.text as characters
  637. --  exits upon end-of-mail indicator (i.e.  <crlf>.<crlf>)
  638. --  may also exit with a raised exception:
  639. --    ssmtp_quit :
  640. --       if a quit command is received
  641. --    ssmtp_reset :
  642. --       if a reset is received
  643. --    transport_close: 
  644. --       if a transport connection_aborted or connection_closed is found
  645. --    transport_error :
  646. --       if an unknown transport condition is found
  647. --
  648. end ssmtp_text ;
  649. with text_io;            use text_io ;
  650. with ssmtp_transport ;   use ssmtp_transport ;
  651. with ssmtp_logger ;      use ssmtp_logger ;
  652. with ssmtp_globals ;     use ssmtp_globals;
  653. package body ssmtp_text is
  654. procedure expect_text is
  655. line : string (1..256) ;
  656. len : integer ;
  657.   begin
  658.   send_string ("354 Start Mail Input") ;
  659.   loop
  660.     get_a_line(line,len) ;
  661.     if line(1) = '.' then
  662.       exit when len = 1 ;
  663.       message_length := message_length + 1 ;
  664.       message(message_length).message_line(1..len-1) := line(2..len) ;
  665.       message(message_length).line_length := len-1 ;
  666.     else
  667.       message_length := message_length + 1 ;
  668.       message(message_length).message_line(1..len) := line(1..len) ;
  669.       message(message_length).line_length := len ;
  670.     end if ;
  671.     --&KJW 21-jul-85 message_length := message_length + 1 ;
  672.     --&KJW 21-jul-85 message(message_length).message_line(1..len) := line(1..len) ;
  673.     --&KJW 21-jul-85 message(message_length).line_length := len ;
  674.     --&KJW 21-jul-85 exit when line(1) = '.' ;
  675.     end loop ;
  676.   exception
  677.     when others =>
  678.       error_log ("Exception in ssmtp.expect_text") ;
  679.   end expect_text ;
  680. end ssmtp_text ;
  681. --::::::::::::::
  682. --strans.txt
  683. --::::::::::::::
  684. -----------------------------------------------------------------------
  685. --
  686. --         DoD Protocols    NA-00010-200       80-01226-100(-)
  687. --         E-Systems, Inc.  August 07, 1985
  688. --
  689. --         strans.txt       Author : Paul Higgins
  690. --
  691. -----------------------------------------------------------------------
  692. package ssmtp_transport is
  693. --
  694. -- all the procedures required to interface to the transport service
  695. --
  696. procedure send_passive_open ;
  697. -- send a listen on the well-known smtp socket
  698. procedure wait_for_open  ;
  699. -- wait for the open ok message
  700. procedure close_connection ;
  701. -- send a close to transport layer, wait for close ok message
  702. procedure send_string (str : in string) ;
  703. -- send a character string via the transport protocol
  704. procedure get_command ;
  705. -- this procedure gets an entire command from the transport layer
  706. -- puts the first four letters, in lower case, in ssmtp_globals.command
  707. -- and leaves the rest in ssmtp_globals.command_line 
  708. -- may raise the following exceptions:
  709. --   sudden_connection_close
  710. --   transport_error
  711. procedure get_a_line( str : out string;
  712.                       len : out integer ) ;
  713. -- this procedure gets an entire line from the transport layer
  714. -- may raise the following exceptions:
  715. --   sudden_connection_close
  716. --   transport_error
  717. end ssmtp_transport ;
  718. with cycle ;                            use cycle ;
  719. with ssmtp_globals ;                 use ssmtp_globals ;
  720. with text_io ;                       use text_io ;
  721. with ssmtp_logger ;                  use ssmtp_logger ;
  722. with with_ulp_communicate ;          use with_ulp_communicate ;
  723. with with_tcp_communicate ;          use with_tcp_communicate ;
  724. with t_tcp_globals_data_structures;    use t_tcp_globals_data_structures;
  725. with buffer_data;                    use buffer_data ;
  726. package body ssmtp_transport is
  727. --&KJW 16-jul-1985 package int_io_16 is new integer_io(sixteen_bits) ;
  728. package int_io_16 renames integer_io;
  729. --------------------------------------------------------------------------------
  730. --&KJW 16-jul-1985 current_lcn : lcn_ptr_type ;
  731. current_lcn : tcb_ptr ;
  732. --------------------------------------------------------------------------------
  733. --
  734. -- This is a local procedure to send a receive request to tcp
  735. -- We should always have a few outstanding receives for tcp to put data into
  736. --
  737. procedure send_a_receive is
  738. request_ok : boolean := true ;
  739. --tcp_params : with_ulp_communicate.message(receive) ;   --&KJW 16-jul-85
  740. tcp_params : with_tcp_communicate.message(receive) ;     --&KJW 16-jul-85
  741. a_buf      : packed_buffer_ptr ;
  742. begin
  743. --&KJW 23-jul-85 put_line("Send a receive ") ;
  744. buffget(a_buf,1) ;
  745. if a_buf = null then
  746.     error_log("ssmtp_transport.send_a_receive:  Could not get a buffer") ;
  747.     raise constraint_error ;   -- crash the connection
  748. else                                        --&KJW 22-jul-85
  749.     a_buf.in_use := true ;                  --&KJW 22-jul-85
  750.     a_buf.status := owner_tcp ;             --&KJW 22-jul-85
  751. end if ;
  752. tcp_params.receive_parameters.lcn := current_lcn ;
  753. tcp_params.receive_parameters.bufptr := a_buf ;
  754. tcp_params.receive_parameters.byte_count := 190 ;
  755. message_for_tcp(tcp_params) ;
  756. if not request_ok then
  757.    raise transport_error ;
  758. end if ;
  759. for count in 1..4 loop        --&KJW 19-jul-85 
  760.   cycle.tcp_ip_subnet;        --&KJW 19-jul-85 
  761. end loop;            --&KJW 19-jul-85 
  762. exception
  763.   when others => 
  764.     error_log("Exception in send_a_receive") ;
  765.     raise ;
  766. end send_a_receive ;
  767. ----------------------------------------------------------------------
  768. ----------------------------------------------------------------------
  769. procedure send_passive_open is
  770. request_ok : boolean := true ;
  771. --tcp_params : with_ulp_communicate.message(open) ;    --&KJW 16-jul-85
  772. tcp_params : with_tcp_communicate.message ;        --&KJW 16-jul-85
  773. open_parameters : open_params;                --&KJW 16-jul-85
  774. begin
  775. -- do a listen on the tcp port for smtp mail service.
  776. --&KJW 23-jul-85 put_line("Send passive open ") ;
  777. open_parameters.lcn := current_lcn ;        --&KJW 16-jul-85
  778. open_parameters.local_port := 25 ;        --&KJW 16-jul-85
  779. open_parameters.foreign_port := 0 ;        --&KJW 16-jul-85
  780. open_parameters.foreign_net_host := 0 ;        --&KJW 16-jul-85
  781. open_parameters.active_passive := passive ;    --&KJW 16-jul-85
  782. open_parameters.buffer_size := 0 ;        --&KJW 16-jul-85
  783. open_parameters.timeout := 2000 ;        --&KJW 16-jul-85
  784. open_parameters.security := 0 ;            --&KJW 16-jul-85
  785. open_parameters.precedence := 0 ;        --&KJW 16-jul-85
  786. open_parameters.options := (1..50 => 0) ;    --&KJW 16-jul-85
  787. tcp_params := ( with_tcp_communicate.open,    --&KJW 16-jul-85
  788.             open_parameters );    --&KJW 16-jul-85
  789. message_for_tcp(tcp_params) ;
  790. if not request_ok then
  791.    raise transport_error ;
  792. end if ;
  793. for count in 1..4 loop        --&KJW 19-jul-85 
  794.   cycle.tcp_ip_subnet;        --&KJW 19-jul-85 
  795. end loop;            --&KJW 19-jul-85 
  796. --&KJW 21-jul-85 current.lcn := tcp_params.open_parameters.lcn ;
  797. exception
  798.   when others => 
  799.     error_log("Exception in send_passive_open") ;
  800.     raise ;
  801. end ;
  802. --------------------------------------------------------------------------------
  803. --------------------------------------------------------------------------------
  804. procedure wait_for_open is
  805. reply : user_message ;
  806. begin
  807. --&KJW 23-jul-85 put_line("wait for open from transport") ;
  808. loop 
  809.   --&KJW 21-jul-85 reply.lcn := current_lcn ;
  810.   for count in 1..4 loop    --&KJW 19-jul-85 
  811.     cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  812.   end loop;            --&KJW 19-jul-85 
  813.   wait_for_tcp_message (reply) ;
  814.   for count in 1..4 loop    --&KJW 19-jul-85 
  815.     cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  816.   end loop;            --&KJW 19-jul-85 
  817.   case reply.message_number is
  818.     when -1 =>            --&KJW 19-jul-85
  819.       null ;            --&KJW 19-jul-85
  820.     when 23 =>
  821.       --&KJW 23-jul-85 put_line("connection open") ;
  822.       send_a_receive ; -- leave a receive pending
  823.       transport_connection_open := true ;       --&KJW 21-jul-85
  824.       exit ;
  825.     when 14 =>
  826.       current_lcn := reply.lcn ;
  827.       --&KJW 23-jul-85 put_line("lcn saved") ;
  828.     when 2 | 5 | 9 | 11 | 20 =>
  829.       put("could not open, reason code = ") ;
  830.       int_io_16.put(reply.message_number) ;
  831.       put_line (" ." ) ;
  832.     when 8 | 16 =>
  833.       put_line("connection aborted") ;
  834.       raise transport_error ;
  835.     when others =>
  836.       put("connection message ") ;
  837.       int_io_16.put(reply.message_number) ;
  838.       new_line ;
  839.     end case ;
  840. end loop ;
  841. exception
  842.   when others => 
  843.     error_log("Exception in wait_for_open") ;
  844.     raise ;
  845. end wait_for_open ;
  846. --------------------------------------------------------------------------------
  847. --------------------------------------------------------------------------------
  848. procedure close_connection is
  849. --
  850. -- Send a close command to tcp and wait for a connection_closed response.
  851. --
  852. --tcp_params : with_ulp_communicate.message(close) ;    --&KJW 16-jul-85
  853. tcp_params : with_tcp_communicate.message ;        --&KJW 16-jul-85
  854. ab_cls_parameters : abort_close_params;            --&KJW 16-jul-85
  855. reply : user_message ;
  856. request_ok : boolean := true ;
  857. begin
  858. --&KJW 23-jul-85 put_line("waiting for close ok...") ;
  859. loop 
  860. reply.lcn := current_lcn ;
  861. for count in 1..4 loop        --&KJW 19-jul-85 
  862.   cycle.tcp_ip_subnet;        --&KJW 19-jul-85 
  863. end loop;            --&KJW 19-jul-85 
  864. wait_for_tcp_message (reply) ;
  865. for count in 1..4 loop        --&KJW 19-jul-85 
  866.   cycle.tcp_ip_subnet;        --&KJW 19-jul-85 
  867. end loop;            --&KJW 19-jul-85 
  868. case reply.message_number is
  869.   when -1 =>            --&KJW 19-jul85
  870.     null;            --&KJW 19-jul-85
  871.   when 8 | 16 =>
  872.     put_line("connection aborted") ;
  873.     transport_connection_open := false ;        --&KJW 21-jul-85
  874.     exit ;
  875.   when 6 =>
  876.     --&KJW 23-jul-85 put_line("closing transport connection") ;    --&KJW 11-jul-85
  877.     ab_cls_parameters.lcn := current_lcn;    --&KJW 16-jul-85
  878.     tcp_params := ( with_tcp_communicate.close, --&KJW 16-jul-85
  879.             ab_cls_parameters );    --&KJW 16-jul-85
  880.     message_for_tcp(tcp_params) ;        --&KJW 11-jul-85
  881.     if not request_ok then
  882.       raise transport_error ;
  883.     end if ;
  884.     reply.lcn := current_lcn ;            --&KJW 11-jul-85
  885.     loop            --&KJW 19-jul-85
  886.       for count in 1..4 loop    --&KJW 19-jul-85 
  887.         cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  888.       end loop;            --&KJW 19-jul-85 
  889.       wait_for_tcp_message (reply) ;        --&KJW 11-jul-85
  890.       for count in 1..4 loop    --&KJW 19-jul-85 
  891.         cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  892.       end loop;            --&KJW 19-jul-85 
  893.       case reply.message_number is        --&KJW 11-jul-85
  894.         when -1 =>        --&KJW 19-jul-85
  895.           null;            --&KJW 19-jul-85
  896.         when 8 | 16 =>                --&KJW 11-jul-85
  897.           put_line("connection aborted") ;    --&KJW 11-jul-85
  898.           transport_connection_open := false ;  --&KJW 21-jul-85
  899.           exit ;                --&KJW 11-jul-85
  900.         when 18 =>                --&KJW 11-jul-85
  901.           --&KJW 23-jul-85 put_line("connection closed") ;
  902.           transport_connection_open := false ;  --&KJW 21-jul-85
  903.           exit ;
  904.         when others =>                --&KJW 11-jul-85
  905.           put("connection message") ;        --&KJW 11-jul-85
  906.           int_io_16.put(reply.message_number) ;   --&KJW 11-jul-85
  907.           new_line ;                --&KJW 11-jul-85
  908.       end case ;                --&KJW 11-jul-85
  909.     end loop ;            --&KJW 19-jul-85
  910.     exit ;            --&KJW 19-jul-85
  911.   when others =>
  912.     put("connection message") ;
  913.     int_io_16.put(reply.message_number) ;
  914.     new_line ;
  915.   end case ;
  916. end loop ;
  917. --&KJW 23-jul-85 put_line("finished waiting") ;
  918. exception
  919.   when others => 
  920.     error_log("Exception in close_connection") ;
  921.     raise ;
  922. end close_connection ;
  923. --------------------------------------------------------------------------------
  924. --------------------------------------------------------------------------------
  925. procedure send_string (str : in string) is
  926. a_buffer : packed_buffer_ptr ;
  927. send_block : send_params ;
  928. --tcp_params : with_ulp_communicate.message(send) ;   --&KJW 16-jul-85
  929. tcp_params : with_tcp_communicate.message(send) ;     --&KJW 16-jul-85
  930. request_ok : boolean := true ;
  931. begin
  932. buffget(a_buffer,1) ;
  933. if a_buffer = null then
  934.     error_log("Could not get a buffer") ;
  935.     raise constraint_error ;   -- crash the connection
  936. else                                           --&KJW 22-jul-85
  937.     a_buffer.in_use := true ;                  --&KJW 22-jul-85
  938.     a_buffer.status := owner_tcp ;             --&KJW 22-jul-85
  939. end if ;
  940. ---a_buffer.tcp_ptr := maximum_datagram_size - sixteen_bits(str'length) ;
  941. -- patch for incorrect buffer spec
  942. a_buffer.tcp_ptr := 254 - sixteen_bits(str'length) ;
  943. --- a_buffer.size := str'length ;  --- patch for tcp error
  944. a_buffer.size := str'length + 1 ;  --- patch for tcp error
  945. -- put the string bytes into the end of the buffer
  946. for i in 1..str'length loop
  947.   a_buffer.byte(a_buffer.tcp_ptr + sixteen_bits(i))
  948.       := character'pos(str(i)) ;
  949. end loop ;
  950. send_block.lcn := current_lcn ;
  951. send_block.bufptr := a_buffer ;
  952. send_block.byte_count := a_buffer.size ;
  953. send_block.push_flag  := 0 ;
  954. send_block.urg_flag := 0 ;
  955. send_block.timeout  := 2000 ;
  956. tcp_params.send_parameters := send_block ;
  957. message_for_tcp(tcp_params) ;  
  958. if not request_ok then
  959.   raise transport_error ;
  960. end if ;
  961. for count in 1..4 loop        --&KJW 19-jul-85 
  962.   cycle.tcp_ip_subnet;        --&KJW 19-jul-85 
  963. end loop;            --&KJW 19-jul-85 
  964. put("S: ") ;
  965. put_line(str) ;
  966. exception
  967.   when others => 
  968.     error_log("Exception in send_string") ;
  969.     raise ;
  970.   end ;
  971. --------------------------------------------------------------------------------
  972. --------------------------------------------------------------------------------
  973. procedure process_data ( buf : packed_buffer_ptr;
  974.                          done : out boolean) is
  975. data_byte : integer ;
  976. len       : integer ;
  977. begin
  978. len := integer(buf.telnet_ptr - buf.tcp_ptr);
  979. if len < 4 then
  980.   command := "    " ;       --- blank it out
  981.   put_line (" Bad command...incomplete") ;
  982. else
  983.   for i in 1..4 loop
  984.     data_byte := integer(buf.byte(buf.tcp_ptr + sixteen_bits(i)-1)) ;
  985.     if ((data_byte >= character'pos('A')) 
  986.           and (data_byte <= character'pos('Z'))) then
  987.        command(i) := character'val( data_byte - character'pos('A') 
  988.                                 + character'pos('a')) ; -- make it lower case
  989.     else
  990.       command(i) := character'val(data_byte) ;
  991.     end if ;
  992.   end loop ;
  993. end if ;
  994. for char in 1..max_command_length loop    --&KJW 16-jul-85
  995.   command_parms(char) := ' ' ;        --&KJW 16-jul-85
  996. end loop;                    --&KJW 16-jul-85
  997. if len <= 4 then
  998.   -- command_parms := (others => ' ') ;        --&KJW 16-jul-85
  999.   parm_length   := 0 ;
  1000. else
  1001.   parm_length := len - 4 ;
  1002.   for i in 1..parm_length loop
  1003.     data_byte := integer(buf.byte(sixteen_bits(i)+buf.tcp_ptr+3))  ;
  1004.     --&KJW 21-jul-85 if ((data_byte >= character'pos('A')) and (data_byte <= character'pos('Z'))) then
  1005.     --&KJW 21-jul-85   command_parms(i) := character'val(data_byte - character'pos('A') 
  1006.     --&KJW 21-jul-85                       + character'pos('a')) ; -- make it lower case
  1007.     --&KJW 21-jul-85 else
  1008.     --&KJW 21-jul-85   command_parms(i) := character'val(data_byte) ;
  1009.     --&KJW 21-jul-85 end if ;
  1010.     command_parms(i) := character'val(data_byte) ;
  1011.   end loop ;
  1012. end if ;
  1013. put("R: ") ;
  1014. put(command) ;
  1015. put_line(command_parms) ;
  1016. done := true ;      -- single segment replies only for test
  1017. exception
  1018.   when others => 
  1019.     error_log("Exception in process_data") ;
  1020.     raise ;
  1021. end process_data ;
  1022. -------------------------------------------------------------------------------
  1023. procedure get_command is
  1024.   len : integer ;          -- test
  1025.   cmd : string (1..256) ;  -- test
  1026.   reply_done : boolean := false ;
  1027.   tcp_reply : with_ulp_communicate.user_message ;
  1028. begin
  1029. command := "    " ;
  1030. --&KJW 23-jul-85 put_line("waiting for command...") ;
  1031. while not reply_done loop 
  1032.   tcp_reply.lcn := current_lcn ;
  1033.   for count in 1..4 loop    --&KJW 19-jul-85 
  1034.     cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  1035.   end loop;            --&KJW 19-jul-85 
  1036.   wait_for_tcp_message (tcp_reply) ;
  1037.   for count in 1..4 loop    --&KJW 19-jul-85 
  1038.     cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  1039.   end loop;            --&KJW 19-jul-85 
  1040.   case tcp_reply.message_number is
  1041.     when -1 =>            --&KJW 19-jul-85 
  1042.       null;            --&KJW 19-jul-85 
  1043.     when 16 =>
  1044.       put_line("connection aborted") ;
  1045.       raise sudden_connection_close ;
  1046.     when 10 =>
  1047.       process_data (tcp_reply.data_buffer, reply_done) ;
  1048.       tcp_reply.data_buffer.in_use := false ;   --&KJW 22-jul-85
  1049.       tcp_reply.data_buffer.status := none ;    --&KJW 22-jul-85
  1050.       buffree(tcp_reply.data_buffer,0) ;        --&KJW 22-jul-85
  1051.       send_a_receive ;  -- replace the receive
  1052.     when others =>
  1053.       put("connection message") ;
  1054.       int_io_16.put(tcp_reply.message_number) ;
  1055.       new_line ;
  1056.   end case ;
  1057. end loop ;
  1058. --&KJW 23-jul-85 put_line("finished waiting") ;
  1059. exception
  1060.   when others =>
  1061.     put_line("exception in get_command") ;
  1062.     raise ;
  1063. end get_command ;
  1064. -------------------------------------------------------------------------------
  1065. -------------------------------------------------------------------------------
  1066. procedure process_str  ( buf  : packed_buffer_ptr;
  1067.                          done : out boolean;
  1068.                          str  : out string ;
  1069.                          len  : out integer ) is
  1070. str1      : string(1..255)  ;
  1071. len1      : integer ;
  1072. data_byte : integer ;
  1073. begin
  1074. len1 := integer(buf.telnet_ptr - buf.tcp_ptr);
  1075. for i in 1..len1 loop
  1076.   str1(i) := character'val(buf.byte(buf.tcp_ptr + sixteen_bits(i)-1)) ;
  1077.   end loop ;
  1078. put("R: ") ;
  1079. put_line(str1(1..len1)) ;
  1080. str(1..len1) := str1(1..len1) ;
  1081. len := len1 ;
  1082. done := true ;      -- single segment replies only for test
  1083. exception
  1084.   when others => 
  1085.     error_log("Exception in process_str") ;
  1086.     raise ;
  1087. end process_str ;
  1088. -------------------------------------------------------------------------------
  1089. procedure get_a_line( str : out string ;
  1090.                       len : out integer ) is
  1091. str_done : boolean := false ;
  1092. tcp_reply : with_ulp_communicate.user_message ;
  1093. begin
  1094. --&KJW 23-jul-85 put_line("waiting for string...") ;
  1095. while not str_done loop 
  1096.   tcp_reply.lcn := current_lcn ;
  1097.   for count in 1..4 loop    --&KJW 19-jul-85 
  1098.     cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  1099.   end loop;            --&KJW 19-jul-85 
  1100.   wait_for_tcp_message (tcp_reply) ;
  1101.   for count in 1..4 loop    --&KJW 19-jul-85 
  1102.     cycle.tcp_ip_subnet;    --&KJW 19-jul-85 
  1103.   end loop;            --&KJW 19-jul-85 
  1104.   case tcp_reply.message_number is
  1105.     when -1 =>            --&KJW 19-jul-85
  1106.       null;            --&KJW 19-jul-85 
  1107.     when 16 =>
  1108.       put_line("connection aborted") ;
  1109.       raise sudden_connection_close ;
  1110.     when 10 =>
  1111.       process_str (tcp_reply.data_buffer, str_done, str, len) ;
  1112.       tcp_reply.data_buffer.in_use := false ;   --&KJW 22-jul-85
  1113.       tcp_reply.data_buffer.status := none ;    --&KJW 22-jul-85
  1114.       buffree(tcp_reply.data_buffer,0) ;        --&KJW 22-jul-85
  1115.       send_a_receive ;  -- replace the receive
  1116.     when others =>
  1117.       put("connection message") ;
  1118.       int_io_16.put(tcp_reply.message_number) ;
  1119.       new_line ;
  1120.   end case ;
  1121. end loop ;
  1122. --&KJW 23-jul-85 put_line("finished waiting") ;
  1123. exception
  1124.   when others =>
  1125.     put_line("exception in get_a_line") ;
  1126.     raise ;
  1127. end get_a_line ;
  1128. end ssmtp_transport ;
  1129. --::::::::::::::
  1130. --ucomm.txt
  1131. --::::::::::::::
  1132. -----------------------------------------------------------------------
  1133. --
  1134. --         DoD Protocols    NA-00010-200       80-01227-100(-)
  1135. --         E-Systems, Inc.  August 07, 1985
  1136. --
  1137. --         ucomm.txt       Author : Paul Higgins
  1138. --
  1139. -----------------------------------------------------------------------
  1140. package usmtp_commands is
  1141. --
  1142. -- This package contains all the commands sent by the usmtp.
  1143. --
  1144. --
  1145. --
  1146. procedure send_data_to_server ;
  1147. --
  1148. -- Sends a DATA command to the ssmtp.
  1149. --
  1150. --
  1151. procedure send_rcpt_to_server(name : string) ;
  1152. --
  1153. -- Sends a RCPT command to the ssmtp.
  1154. --
  1155. --
  1156. procedure send_helo ;
  1157. --
  1158. -- Sends a HELO command to the ssmtp.
  1159. --
  1160. --  
  1161. procedure send_mail (name : string) ;
  1162. --
  1163. -- Sends a MAIL command to the ssmtp.
  1164. --
  1165. --
  1166. procedure send_quit ;
  1167. --
  1168. -- Sends a QUIT command to the ssmtp.
  1169. --
  1170. --
  1171. procedure send_reset ;
  1172. --
  1173. -- Sends a RSET command to the ssmtp.
  1174. --
  1175. --
  1176. end usmtp_commands ;
  1177. with usmtp_utils ;       use usmtp_utils ; 
  1178. with usmtp_network ;     use usmtp_network ;
  1179. with text_io ;           use text_io ;
  1180. package body usmtp_commands is
  1181. --
  1182. -- This package contains all the commands sent by the usmtp.
  1183. --
  1184. --
  1185. --
  1186. --
  1187. procedure send_data_to_server is
  1188. --
  1189. -- Send the DATA command to tcp.
  1190. --
  1191. begin
  1192. send_string("DATA") ;
  1193. exception
  1194.   when others =>
  1195.     put_line("exception in send_data_to_server") ;
  1196.     raise ;
  1197. end ;
  1198. --
  1199. --
  1200. --
  1201. procedure send_rcpt_to_server(name : string) is
  1202. --
  1203. -- Send the RCPT command to tcp. Formats the name into a proper command line
  1204. --  and calls send_string.
  1205. --
  1206. line : string (1..256) ;
  1207. len : integer ;
  1208. prep : string (1..9) := "RCPT to: " ;
  1209. begin
  1210.   len := name'length + prep'length ;
  1211.   line(1..len) := prep & name ;
  1212.   send_string(line (1..len));
  1213. exception
  1214.   when others =>
  1215.     put_line("exception in send_rcpt_to_server") ;
  1216.     raise ;
  1217. end send_rcpt_to_server ;
  1218. procedure  send_helo is
  1219. --
  1220. -- Send the HELO command to tcp. Formats the host name into a proper command 
  1221. --  line and calls send_string.
  1222. -- To rehost, change my_host_name and recompile.
  1223. --
  1224. line : string (1..256) ;
  1225. len : integer ;
  1226. my_host_name : constant string(1..13)  := "NOSCAda.WICAT" ;
  1227. begin
  1228. len := 5 + my_host_name'length ;
  1229. line(1..len) := "HELO " & my_host_name ;
  1230. send_string(line(1..len)) ;
  1231. exception
  1232.   when others =>
  1233.     put_line("exception in send_helo") ;
  1234.     raise ;
  1235. end send_helo ;
  1236. --
  1237. --
  1238. --  
  1239. procedure send_mail (name : string) is
  1240. line : string (1..256) ;
  1241. len : integer ;
  1242. begin
  1243. len := 11 + name'length ;
  1244. line(1..len) := "MAIL from: " & name ;
  1245. send_string(line(1..len)) ;
  1246. exception
  1247.   when others =>
  1248.     put_line("exception in send_mail") ;
  1249.     raise ;
  1250. end send_mail ;
  1251. --
  1252. --
  1253. --
  1254. procedure send_quit is
  1255. begin
  1256. send_string("QUIT") ;
  1257. exception
  1258.   when others =>
  1259.     put_line("exception in send_quit") ;
  1260.     raise ;
  1261. end ;
  1262. --
  1263. --
  1264. --
  1265. procedure send_reset is
  1266. begin
  1267. send_string("RSET") ;
  1268. exception
  1269.   when others =>
  1270.     put_line("exception in send_rset ") ;
  1271.     raise ;
  1272. end ;
  1273. --
  1274. --
  1275. --
  1276. end usmtp_commands ;
  1277. --::::::::::::::
  1278. --uconn.txt
  1279. --::::::::::::::
  1280. -----------------------------------------------------------------------
  1281. --
  1282. --         DoD Protocols    NA-00010-200       80-01228-100(-)
  1283. --         E-Systems, Inc.  August 07, 1985
  1284. --
  1285. --         uconn.txt       Author : Paul Higgins
  1286. --
  1287. -----------------------------------------------------------------------
  1288. package usmtp_connections is
  1289. --
  1290. -- This pacakge contains the connection related functions for the 
  1291. --   communications with the ssmtp.
  1292. -- Allows opening connections, sending data, closing connections,
  1293. --    and forcing resets on connections.
  1294. --
  1295. --
  1296. --
  1297. procedure establish_connection_and_send_helo ;
  1298. --
  1299. -- This procedure performs the follwing functions:
  1300. --   1. request a transport connection to the well-known ssmtp network address
  1301. --   2. wait for the connection to be successfully opened
  1302. --   3. wait for a greeting reply from the ssmtp and print it
  1303. --   4. send a helo to the ssmtp
  1304. --   5. wait for a helo_ok reply from the ssmtp
  1305. --
  1306. -- If proper handshaking fails (connection not opened, incorrect reply 
  1307. --   from ssmtp, etc.; this procedure queries the user for retries and loops
  1308. --   if requested. Exits with an excetpion if unsuccessful and no retry 
  1309. --   requested.
  1310. --
  1311. -- raises the following exceptions:
  1312. --   abort_ssmtp if connection fails and user does not request retry
  1313. --
  1314. --
  1315. --
  1316. procedure close_smtp_connection ;
  1317. --
  1318. -- Sends a QUIT command to the ssmtp, waits for a proper reply, and
  1319. --  sends a close command to the transport layer for a normal connection
  1320. --  close.
  1321. --
  1322. --
  1323. --
  1324. end usmtp_connections ;
  1325. with text_io;        use text_io ;
  1326. with usmtp_utils ;   use usmtp_utils ;
  1327. with usmtp_network;  use usmtp_network ;
  1328. with usmtp_commands; use usmtp_commands;
  1329. package body usmtp_connections is
  1330. --
  1331. -- Package implementation for :  Labtek WICAT
  1332. --                               tcp transport service (esystems version)
  1333. --                               TeleSoft/Ada (Version 1.3)
  1334. procedure establish_connection_and_send_helo is
  1335. --
  1336. -- This procedure performs the follwing functions:
  1337. --   1. request a tcp connection to the well-known ssmtp socket
  1338. --   2. wait for a greeting reply (220) from the ssmtp and print it
  1339. --   3. send a helo to the ssmtp
  1340. --   4. wait for a helo_ok reply from the ssmtp
  1341. --
  1342. -- If proper handshaking fails (connection not opened, incorrect reply 
  1343. --   from ssmtp, etc.; This procedure exits with an exception 
  1344. --   if unsuccessful. Connection is closed if this occurs.
  1345. --
  1346. -- raises or propagates the following exceptions:
  1347. --   unexpected_reply if bad reply from ssmtp
  1348. --   smtp_error       if 4xx or 5xx from ssmtp
  1349. --   tcp reset        if connection lost or could not open
  1350. --   
  1351. --
  1352.   host_name    : string (1..80) ;
  1353.   eol          : integer := 0 ;
  1354.   reply        : string (1..80) ;
  1355. begin
  1356.   put_line("Establish Connection to Remote Host ") ;
  1357.   put("enter remote host name -> ") ;
  1358.   get_line(host_name, eol) ;
  1359.   send_open_to_transport_layer(host_name(1..eol)) ;
  1360.   get_reply(reply) ;
  1361.   if reply(1..3) /= open_ok then
  1362.     put_line("Could not open...bad reply") ;
  1363.     put_line("Aborting connection") ;
  1364.     send_abort_to_transport ;
  1365.     raise tcp_reset ;
  1366.   else
  1367.     --&KJW 23-jul-85 put_line("Sending helo...") ;
  1368.     send_helo ;
  1369.     get_reply(reply) ;
  1370.     if reply(1..3) /= helo_ok then 
  1371.       put_line("server not responding");
  1372.       put_line("Aborting connection") ;
  1373.       send_aborT_to_transport ;
  1374.       raise smtp_error ;
  1375.     end if ;
  1376.   end if ;
  1377. exception
  1378.   when smtp_error | tcp_reset =>
  1379.     raise ;
  1380.   when others =>
  1381.     put_line("unexpected exception in establish_connection") ;
  1382.     raise ;
  1383. end establish_connection_and_send_helo;
  1384. procedure close_smtp_connection is
  1385.   reply : string(1..80) ;        --&KJW 11-jul-85;
  1386. begin
  1387. send_quit ;
  1388. get_reply(reply) ;            --&KJW 11-jul-85;
  1389. if reply(1..3) /= quit_ok then        --&KJW 11-jul-85;
  1390.   put_line("Quit reply not received") ;    --&KJW 11-jul-85;
  1391.   raise unexpected_reply ;        --&KJW 11-jul-85;
  1392. end if ;                --&KJW 11-jul-85;
  1393. send_close_to_transport_layer ;
  1394. exception
  1395.   when others =>
  1396.     put_line("exception in close_smtp_connection") ;
  1397.     raise ;
  1398. end close_smtp_connection ;
  1399. end usmtp_connections ;
  1400. --::::::::::::::
  1401. --unet.txt
  1402. --::::::::::::::
  1403. -----------------------------------------------------------------------
  1404. --
  1405. --         DoD Protocols    NA-00010-200       80-01229-100(-)
  1406. --         E-Systems, Inc.  August 07, 1985
  1407. --
  1408. --         unet.txt       Author : Paul Higgins
  1409. --
  1410. -----------------------------------------------------------------------
  1411. package usmtp_network is
  1412. --
  1413. -- This package contains the usmtp interfaecs to the network transport
  1414. --   protocol process and other network-related functions.
  1415. --
  1416. --
  1417. procedure send_open_to_transport_layer(host_id : string) ;
  1418. --
  1419. -- Sends an open connection request to the transport layer.
  1420. --
  1421. --
  1422. procedure send_abort_to_transport ;
  1423. --
  1424. -- Sends an abort command to the transport layer to force termination
  1425. --  of a connection.
  1426. --  
  1427. --
  1428. procedure send_string (str : in string) ;
  1429. --
  1430. -- formats an ascii string into the desired transport form and sends it
  1431. --   to the ssmtp
  1432. --
  1433. procedure send_close_to_transport_layer ;
  1434. --
  1435. -- Sends a close command to the transport layer to force a normal connection
  1436. --   close.
  1437. --
  1438. --
  1439. procedure get_reply (reply  : out string) ;
  1440. --
  1441. -- This procedure gets a reply string from the transport layer.
  1442. --  Converts transport layer format to string. Performs as many
  1443. --  transport layer reads as necessary until a complete response is found
  1444. --  (in case of multiline responses, etc.)
  1445. --
  1446. end usmtp_network ;
  1447. with cycle ;                            use cycle ;
  1448. with buffer_data ;                   use buffer_data ;
  1449. with with_ulp_communicate ;          use with_ulp_communicate ;
  1450. with with_tcp_communicate ;          use with_tcp_communicate ;
  1451. with t_tcp_globals_data_structures;    use t_tcp_globals_data_structures;
  1452. with text_io;                        use text_io ;
  1453. with usmtp_utils ;                   use usmtp_utils ;
  1454. with xhost ;                         use xhost ;
  1455. with system ;                        use system ;
  1456. --
  1457. package body usmtp_network is
  1458. --
  1459. -- Implementation for:    LabTek Wicat
  1460. --                        tcp transport layer (e-system version)
  1461. --                        TeleSoft Ada
  1462. --
  1463. --
  1464. --&KJW 16-jul-85 package int_io_32 is new integer_io(thirtytwo_bits) ;
  1465. --&KJW 16-jul-85 package int_io_16 is new integer_io(sixteen_bits) ;
  1466. package int_io_32 renames text_io.long_integer_io;    --&KJW 16-jul-85 
  1467. package int_io_16 renames text_io.     integer_io;    --&KJW 16-jul-85 
  1468. --
  1469. --
  1470. --&KJW 16-jul-85 current_lcn : lcn_ptr_type ;  -- the lcn for the current open connection
  1471. current_lcn : tcb_ptr ;  -- the lcn for the current open connection
  1472. --
  1473. --------------------------------------------------------------------------------
  1474. --------------------------------------------------------------------------------
  1475. --
  1476. ----
  1477. -- This is a local procedure to send a receive request to tcp
  1478. -- We should always have a few outstanding receives for tcp to text_io.put data into
  1479. --
  1480. procedure send_a_receive is
  1481. request_ok : boolean := true ;
  1482. --&KJW 16-jul-85 tcp_params : with_tcp_communicate.message(receive) ;
  1483. tcp_params : with_tcp_communicate.message ;    --&KJW 16-jul-85
  1484. receive_parameters : receive_params;        --&KJW 16-jul-85
  1485. a_buf      : packed_buffer_ptr ;
  1486. begin
  1487. --&KJW 23-jul-85 text_io.put_line("Send a receive ") ;
  1488. buffget(a_buf,1) ;
  1489. if a_buf = null then
  1490.     text_io.put_line("usmtp_network.send_a_receive:  Could not get a buffer") ;
  1491.     raise constraint_error ;   -- crash the connection
  1492. else
  1493.     a_buf.in_use := true ;                      --&KJW 22-jul-85
  1494.     a_buf.status := owner_tcp ;                 --&KJW 22-jul-85
  1495. end if ;
  1496. --&KJW 16-jul-85 tcp_params.receive_parameters.lcn := current_lcn ;
  1497. --&KJW 16-jul-85 tcp_params.receive_parameters.bufptr := a_buf ;
  1498. --&KJW 16-jul-85 tcp_params.receive_parameters.byte_count := 190 ;
  1499. receive_parameters.lcn := current_lcn ;        --&KJW 16-jul-85
  1500. receive_parameters.bufptr := a_buf ;        --&KJW 16-jul-85
  1501. receive_parameters.byte_count := 190 ;        --&KJW 16-jul-85
  1502. tcp_params := ( with_tcp_communicate.receive,    --&KJW 16-jul-85
  1503.                 receive_parameters );        --&KJW 16-jul-85
  1504. message_for_tcp(tcp_params) ;
  1505. if not request_ok then
  1506.    raise constraint_error ;  -- crash the connection
  1507. end if ;
  1508. for count in 1..4 loop            --&KJW 19-jul-85
  1509.   cycle.tcp_ip_subnet ;            --&KJW 19-jul-85
  1510. end loop ;                --&KJW 19-jul-85
  1511. exception
  1512.   when others => 
  1513.     text_io.put_line("Exception in send_a_receive") ;
  1514.     raise ;
  1515. end send_a_receive ;
  1516. --
  1517. procedure send_string(str : in string) is
  1518. --
  1519. -- Given an ascii string, this procedure converts it to the
  1520. --  tcp format (byte array), formats a tcp send call, and calls the
  1521. --  tcp interface.
  1522. --
  1523. a_buffer   : packed_buffer_ptr ;
  1524. tcp_params : message(send) ;
  1525. send_block : send_params ;
  1526. request_ok : boolean := true ;
  1527. begin
  1528.   for count in 1..10 loop        --&KJW 19-jul-85
  1529.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85  
  1530.   end loop ;                --&KJW 19-jul-85
  1531.   buffget(a_buffer, 0) ;
  1532.   -- patch for incorrect buffer spec
  1533.   --a_buffer.tcp_ptr := maximum_datagram_size - sixteen_bits(str'length) ;
  1534.   if a_buffer = null then
  1535.     text_io.put_line("usmtp_network:  Out of buffers.") ;
  1536.     raise constraint_error;
  1537.   else
  1538.     a_buffer.in_use := true ;
  1539.     a_buffer.status := owner_tcp ;
  1540.   end if ;
  1541.   a_buffer.tcp_ptr := 254 - sixteen_bits(str'length) ;
  1542.   text_io.put("TCP_PTR IS "); int_io_16.put(a_buffer.tcp_ptr,0); new_line;
  1543.   --- a_buffer.size := str'length ;  --- patch for tcp error :
  1544.   a_buffer.size := str'length + 1 ;  --- patch for tcp
  1545.   -- text_io.put the string bytes into the end of the buffer
  1546.   for i in 1..str'length loop
  1547.     a_buffer.byte(a_buffer.tcp_ptr + sixteen_bits(i))
  1548.         := character'pos(str(i)) ;
  1549.   end loop ;
  1550.   send_block.lcn := current_lcn ;
  1551.   send_block.bufptr := a_buffer ;
  1552.   send_block.byte_count := a_buffer.size ;
  1553.   send_block.push_flag  := 0 ;
  1554.   send_block.urg_flag := 0 ;
  1555.   send_block.timeout  := 2000 ;
  1556.   tcp_params.send_parameters := send_block ;
  1557.   message_for_tcp(tcp_params) ;  
  1558.   if not request_ok then
  1559.     raise tcp_reset ;
  1560.   end if ;
  1561.   for count in 1..10 loop        --&KJW 19-jul-85
  1562.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85  
  1563.   end loop ;                --&KJW 19-jul-85
  1564. text_io.put("S: ") ;
  1565.   text_io.put_line(str) ;
  1566. exception
  1567.   when tcp_reset => 
  1568.     text_io.put_line("TCP error in send_string") ;
  1569.     raise ;
  1570.   when others =>
  1571.     text_io.put_line("exception in send_string") ;
  1572.     raise ;
  1573.   end ;
  1574. --------------------------------------------------------------------------------
  1575. --------------------------------------------------------------------------------
  1576. procedure  send_abort_to_transport is
  1577. --
  1578. -- Format and send a tcp abort command to reset the connection.
  1579. -- May wait for connection_closed message from tcp.
  1580. --
  1581. --&KJW 16-jul-85 tcp_params : message(abor_t) ;
  1582. tcp_params : message ;    --&KJW 16-jul-85 
  1583. ab_cls_parameters : abort_close_params;        --&KJW 16-jul-85 
  1584. reply : user_message ;
  1585. request_ok : boolean := true ;
  1586. begin
  1587. --&KJW 23-jul-85 text_io.put_line("send_abort_to_transport") ;
  1588. ab_cls_parameters.lcn := current_lcn ;        --&KJW 16-jul-85 
  1589. tcp_params := ( with_tcp_communicate.abor_t,    --&KJW 16-jul-85 
  1590.                 ab_cls_parameters );        --&KJW 16-jul-85 
  1591. message_for_tcp(tcp_params) ;  
  1592. if not request_ok then
  1593.   raise tcp_reset ;
  1594. end if ;
  1595. --&KJW 23-jul-85 text_io.put_line("waiting for abort ok...") ;
  1596. loop 
  1597.   reply.lcn := current_lcn ;
  1598.   for count in 1..4 loop        --&KJW 19-jul-85
  1599.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1600.   end loop ;                --&KJW 19-jul-85
  1601.   wait_for_tcp_message (reply) ;
  1602.   for count in 1..4 loop        --&KJW 19-jul-85
  1603.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1604.   end loop ;                --&KJW 19-jul-85
  1605.   case reply.message_number is
  1606.     when -1 =>                --&KJW 19-jul-85
  1607.       null ;                --&KJW 19-jul-85
  1608.     when 8 | 16 =>
  1609.       text_io.put_line("connection aborted") ;
  1610.       exit ;
  1611.     when others =>
  1612.       text_io.put("connection message") ;
  1613.       int_io_16.put(reply.message_number) ;
  1614.       new_line ;
  1615.   end case ;
  1616. end loop ;
  1617. exception
  1618.   when tcp_reset => 
  1619.     text_io.put_line("TCP error in send_abort_to_transport") ;
  1620.     raise ;
  1621.   when others =>
  1622.     text_io.put_line("exception in send_abort_to_transport ") ;
  1623.     raise ;
  1624. end ;
  1625. --------------------------------------------------------------------------------
  1626. --------------------------------------------------------------------------------
  1627. procedure send_to_transport(data_line : in string ) is
  1628. --
  1629. -- Call send_string to send a string.
  1630. --
  1631. begin
  1632. send_string(data_line) ;
  1633. exception
  1634.   when others =>
  1635.     text_io.put_line("exception in send_to_transport") ;
  1636.     raise ;
  1637. end ;
  1638. --------------------------------------------------------------------------------
  1639. --------------------------------------------------------------------------------
  1640. procedure convert_to_lower_case (str : in out string) is
  1641. begin
  1642.  for i in 1..str'length loop
  1643.    if ( str(i) IN 'A'..'Z' ) then
  1644.      str(i) := character'val(character'pos(str(i)) + 32) ;
  1645.    end if ;
  1646.   end loop ;
  1647. end convert_to_lower_case ;
  1648. procedure send_open_to_transport_layer(host_id : string) is
  1649. --
  1650. -- Format a tcp_open and wait for connection_opened tcp response.
  1651. --
  1652. host_name_ok : boolean ;
  1653. host_addr    : buffer_data.thirtytwo_bits ;
  1654. --&KJW 16-jul-85 tcp_params   : message(open) ;
  1655. tcp_params   : message ;    --&KJW 16-jul-85 
  1656. open_parameters : open_params;    --&KJW 16-jul-85 
  1657. reply        : user_message ;
  1658. request_ok   : boolean := true ;
  1659. id           : string (1..host_id'length) ;
  1660. begin
  1661.   id := host_id ;
  1662.   convert_to_lower_case(id) ;
  1663.   translate_host_name_to_address(id, host_addr, host_name_ok) ;
  1664.   if not host_name_ok then
  1665.     text_io.put_line("Bad host name") ;
  1666.     raise tcp_reset ;
  1667.   end if ;
  1668.   --&KJW 23-jul-85 text_io.put("send_open_to_transport_layer, host= ");
  1669.   --&KJW 23-jul-85 text_io.put(id) ;
  1670.   --&KJW 23-jul-85 text_io.put(" = ") ;
  1671.   --&KJW 23-jul-85 int_io_32.put(host_addr) ;
  1672.   --&KJW 23-jul-85 new_line ;
  1673.   --&KJW 16-jul-85 tcp_params.open_parameters.lcn := current_lcn ;
  1674.   --&KJW 16-jul-85 tcp_params.open_parameters.local_port := 26 ;
  1675.   --&KJW 16-jul-85 tcp_params.open_parameters.foreign_net_host := host_addr ;
  1676.   --&KJW 16-jul-85 tcp_params.open_parameters.foreign_port := 25 ;
  1677.   --&KJW 16-jul-85 tcp_params.open_parameters.active_passive := active ;
  1678.   --&KJW 16-jul-85 tcp_params.open_parameters.buffer_size := 0 ;
  1679.   --&KJW 16-jul-85 tcp_params.open_parameters.timeout := 2000 ;
  1680.   --&KJW 16-jul-85 tcp_params.open_parameters.security := 0 ;
  1681.   --&KJW 16-jul-85 tcp_params.open_pa.ameters.precedence := 0 ;
  1682.   --&KJW 16-jul-85 tcp_params.open_parame0ers.options := (others => 0) ;
  1683.   open_parameters.lcn := current_lcn ;            --&KJW 16-jul-85 
  1684.   open_parameters.local_port := 26 ;            --&KJW 16-jul-85 
  1685.   open_parameters.foreign_net_host := host_addr ;    --&KJW 16-jul-85 
  1686.   open_parameters.foreign_port := 25 ;            --&KJW 16-jul-85 
  1687.   open_parameters.active_passive := active ;        --&KJW 16-jul-85 
  1688.   open_parameters.buffer_size := 0 ;            --&KJW 16-jul-85 
  1689.   open_parameters.timeout := 2000 ;            --&KJW 16-jul-85 
  1690.   open_parameters.security := 0 ;            --&KJW 16-jul-85 
  1691.   open_parameters.precedence := 0 ;            --&KJW 16-jul-85 
  1692.   open_parameters.options := (1..50 => 0) ;        --&KJW 16-jul-85 
  1693.   tcp_params := ( with_tcp_communicate.open,        --&KJW 16-jul-85
  1694.                   open_parameters ) ;            --&KJW 16-jul-85
  1695.   message_for_tcp(tcp_params) ;
  1696.   if not request_ok then
  1697.     raise tcp_reset ;
  1698.   end if ;
  1699.   current_lcn := tcp_params.open_parameters.lcn ;
  1700.   --&KJW 23-jul-85 text_io.put_line("wait for open from transport") ;
  1701.   loop 
  1702.     reply.lcn := current_lcn ;
  1703.     for count in 1..4 loop        --&KJW 19-jul-85
  1704.       cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1705.     end loop ;                --&KJW 19-jul-85
  1706.     wait_for_tcp_message (reply) ;
  1707.     for count in 1..4 loop        --&KJW 19-jul-85
  1708.       cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1709.     end loop ;                --&KJW 19-jul-85
  1710.     case reply.message_number is
  1711.       when -1 =>            --&KJW 19-jul-85
  1712.         null ;                --&KJW 19-jul-85
  1713.       when 23 =>
  1714.         --&KJW 23-jul-85 text_io.put_line("connection open") ;
  1715.         exit ;
  1716.       when 14 =>
  1717.         current_lcn := reply.lcn ;
  1718.         --&KJW 23-jul-85 text_io.put_line("lcn saved") ;
  1719.       when 2 | 5 | 9 | 11 | 20 =>
  1720.         text_io.put("could not open, reason code = ") ;
  1721.         int_io_16.put(reply.message_number) ;
  1722.         text_io.put_line (" ." ) ;
  1723.         raise tcp_reset ;
  1724.       when 8 | 16 =>
  1725.         text_io.put_line("connection aborted") ;
  1726.         raise tcp_reset ;
  1727.       when others =>
  1728.         text_io.put("connection message") ;
  1729.         int_io_16.put(reply.message_number) ;
  1730.         new_line ;
  1731.       end case ;
  1732.   end loop ;
  1733.   send_a_receive ; -- leave an outstanding receive
  1734. exception
  1735.   when tcp_reset =>
  1736.     raise ;
  1737.   when others =>
  1738.     text_io.put_line("exception in send_open_to_transport ") ;
  1739.     raise ;
  1740. end send_open_to_transport_layer ;
  1741. --------------------------------------------------------------------------------
  1742. --------------------------------------------------------------------------------
  1743. procedure send_close_to_transport_layer is
  1744. --
  1745. -- Send a close command to tcp and wait for a connection_closed response.
  1746. --
  1747. --&KJW 16-jul-85 tcp_params : message(close) ;
  1748. tcp_params : message ;                --&KJW 16-jul-85
  1749. ab_cls_parameters : abort_close_params ;    --&KJW 16-jul-85
  1750. reply : user_message ;
  1751. request_ok : boolean := true ;
  1752. begin
  1753. --&KJW 23-jul-85 text_io.put_line ("Close tcp connection") ;
  1754. --&KJW 16-jul-85 tcp_params.abort_close_parameters.lcn := current_lcn ;
  1755. ab_cls_parameters.lcn := current_lcn ;        --&KJW 16-jul-85
  1756. tcp_params := ( with_tcp_communicate.close,    --&KJW 16-jul-85
  1757.                 ab_cls_parameters ) ;        --&KJW 16-jul-85
  1758. message_for_tcp(tcp_params) ;
  1759. if not request_ok then
  1760.   raise tcp_reset ;
  1761. end if ;
  1762. for count in 1..4 loop            --&KJW 19-jul-85
  1763.   cycle.tcp_ip_subnet ;            --&KJW 19-jul-85
  1764. end loop ;                --&KJW 19-jul-85
  1765. --&KJW 23-jul-85 text_io.put_line("waiting for close ok...") ;
  1766. loop
  1767.   reply.lcn := current_lcn ;
  1768.   for count in 1..4 loop        --&KJW 19-jul-85
  1769.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1770.   end loop ;                --&KJW 19-jul-85
  1771.   wait_for_tcp_message (reply) ;
  1772.   for count in 1..4 loop        --&KJW 19-jul-85
  1773.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1774.   end loop ;                --&KJW 19-jul-85
  1775.   case reply.message_number is
  1776.     when -1 =>                --&KJW 19-jul-85
  1777.       null ;                --&KJW 19-jul-85
  1778.     when 8 | 16 =>
  1779.       text_io.put_line("connection aborted") ;
  1780.       exit ;
  1781.     when 6 | 18 =>    --&KJW 11-jul-85
  1782.       --&KJW 23-jul-85 text_io.put_line("connection closed") ;
  1783.       exit ;
  1784.     when others =>
  1785.       text_io.put("connection message") ;
  1786.       int_io_16.put(reply.message_number) ;
  1787.       new_line ;
  1788.   end case ;
  1789. end loop ;
  1790. exception
  1791.   when tcp_reset => 
  1792.     text_io.put_line("TCP error in send_close") ;
  1793.     raise ;
  1794.   when others =>
  1795.     text_io.put_line("exception in send_close ") ;
  1796.     raise ;
  1797. end ;
  1798. --------------------------------------------------------------------------------
  1799. --------------------------------------------------------------------------------
  1800. --
  1801. -- this procedure gets tcp data buffers until a reply  terminator is found
  1802. --
  1803. -- converts system.byte into ascii chars
  1804. -- keeps gathering characters until an end-of-reply (eor) is found.
  1805. -- an eor is indicated by a <crlf> if a single line reply or a
  1806. --  <crlf>.<crlf> if a multiline reply. 
  1807. -- also separates the received data into the reply and any excess found in the
  1808. --  segment after the <crlf>. Note that there should not be anything
  1809. --  after the <crlf> if the server_smtp is ok.
  1810. --
  1811. -- all this is necessary because we cannot rely on the entire
  1812. --  reply being in a single tcp segment.
  1813. --
  1814. --    <reply_format>        = NNN<multiline_indicator>reply_text<eor>
  1815. --    <multiline_indicator> = <space> | -
  1816. --    <eor>                 = <crlf> | <crlf>.<crlf>
  1817. --
  1818. -- accepts all tcp messages
  1819. --  if tcp resets or closes  it will raise tcp_reset
  1820. --  tosses all others away
  1821. --
  1822. procedure process_data ( buf : packed_buffer_ptr;
  1823.                          str : out string ) is
  1824. --&KJW 17-jul-85 str1 : string (1..str'length) := ( others => ' ') ;
  1825. str1 : string (1..str'length) ;        --&KJW 17-jul-85 
  1826. len : integer ;
  1827. begin
  1828. len := integer(buf.telnet_ptr-buf.tcp_ptr);
  1829. for i in 1..len loop
  1830.   str1(i) := character'val(buf.byte(buf.tcp_ptr+sixteen_bits(i)-1) ) ;
  1831. end loop ;
  1832. for i in len+1..str'length loop        --&KJW 17-jul-85 
  1833.   str1(i) := ' ';            --&KJW 17-jul-85 
  1834. end loop;                --&KJW 17-jul-85 
  1835. text_io.put("R: ") ;                        
  1836. text_io.put_line(str1(1..len)) ;
  1837. str(1..3) := str1(1..3) ;
  1838. --&KJW 17-jul-85 str(4..str'length) := (others => ' ') ;
  1839. for i in 4 .. str'length loop        --&KJW 17-jul-85 
  1840.   str(i) := ' ';            --&KJW 17-jul-85 
  1841. end loop;                --&KJW 17-jul-85 
  1842. end process_data ;
  1843. procedure get_reply (reply  : out string) is
  1844.   eor_found : boolean := false ;
  1845.   rep : string (1..80) ;           -- for debug
  1846.   erep : integer ;                 -- for debug
  1847.   reply_done : boolean := false ;
  1848.   tcp_reply : user_message ;
  1849. begin
  1850. reply(1..3) := "   " ;
  1851. --&KJW 23-jul-85 text_io.put_line("waiting for reply...") ;      --&KJW 20-jul-85
  1852. while not reply_done loop 
  1853.   tcp_reply.lcn := current_lcn ;
  1854.   for count in 1..4 loop        --&KJW 19-jul-85
  1855.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1856.   end loop ;                --&KJW 19-jul-85
  1857.   wait_for_tcp_message (tcp_reply) ;
  1858.   for count in 1..4 loop        --&KJW 19-jul-85
  1859.     cycle.tcp_ip_subnet ;        --&KJW 19-jul-85
  1860.   end loop ;                --&KJW 19-jul-85
  1861.   case tcp_reply.message_number is
  1862.     when -1 =>                --&KJW 19-jul-85
  1863.       null ;                --&KJW 19-jul-85
  1864.     when 16 =>
  1865.       text_io.put_line("connection aborted") ;
  1866.       raise tcp_reset ;
  1867.     when 10 =>
  1868.       process_data (tcp_reply.data_buffer, reply) ;
  1869.       tcp_reply.data_buffer.in_use := false ;
  1870.       tcp_reply.data_buffer.status := none ;
  1871.       buffree(tcp_reply.data_buffer,0) ;
  1872.       send_a_receive ;
  1873.       reply_done := true ;  -- single segment replies only!
  1874.     when others =>
  1875.       text_io.put("connection message") ;
  1876.       int_io_16.put(tcp_reply.message_number) ;
  1877.       new_line ;
  1878.   end case ;
  1879. end loop ;
  1880. --&KJW 23-jul-85 text_io.put_line("finished waiting") ;      --&KJW 20-jul-85
  1881. exception
  1882.   when others =>
  1883.     text_io.put_line("exception in get_reply") ;
  1884.     raise ;
  1885. end get_reply ;
  1886. end usmtp_network ;
  1887. --::::::::::::::
  1888. --urcpt.txt
  1889. --::::::::::::::
  1890. -----------------------------------------------------------------------
  1891. --
  1892. --         DoD Protocols    NA-00010-200       80-01230-100(-)
  1893. --         E-Systems, Inc.  August 07, 1985
  1894. --
  1895. --         urcpt.txt       Author : Paul Higgins
  1896. --
  1897. -----------------------------------------------------------------------
  1898. package usmtp_rcpt is
  1899. --
  1900. -- This package handles the recipient list mode.
  1901. --
  1902. procedure send_rcpt_list ;
  1903. --
  1904. -- Query the user for each recipient name in the list, send
  1905. --  the RCPT command, and wait for a response. Must receive
  1906. --  at least one rcpt_ok respone from the ssmtp before proceeding.
  1907. --
  1908. end usmtp_rcpt ;
  1909. with text_io;           use text_io ;
  1910. with usmtp_utils ;      use usmtp_utils ;
  1911. with usmtp_connections; use usmtp_connections ;
  1912. with usmtp_commands;    use usmtp_commands;    
  1913. with usmtp_network ;    use usmtp_network ;
  1914. package body usmtp_rcpt is
  1915. procedure send_rcpt_list is
  1916. --
  1917. -- For each recipient, query the user for the name and send it using
  1918. --   the send_rcpt procedure in usmtp_network.
  1919. -- Current limitations:
  1920. --   does not do any processing on user name strings
  1921. --   does not support local lists
  1922. --
  1923. --&KJW 21-jul-85 a_rcpt : boolean := false ;
  1924. rcpt_count : natural := 0 ;             --&KJW 21-jul-85 
  1925. user_name : string (1..80) ;
  1926. eol : integer := 0 ;
  1927. reply : string (1..80) ;
  1928. begin
  1929.   put_line("Enter rcpt list 1 at a time ... nul line to terminate list") ;
  1930.   loop
  1931.     put ("To: ") ;
  1932.     get_line(user_name,eol);
  1933.     if eol /= 0 then
  1934.       send_rcpt_to_server(user_name(1..eol)) ;
  1935.       get_reply(reply) ;
  1936.       if reply(1..3) = rcpt_ok then
  1937.         --&KJW 23-jul-85 put_line ("rcpt ok") ;
  1938.         --&KJW 21-jul-85 a_rcpt := true ;
  1939.         rcpt_count := rcpt_count + 1 ;  --&KJW 21-jul-85 
  1940.       --&KJW 23-jul-85 else
  1941.         --&KJW 23-jul-85 put_line("rcpt not ok") ;
  1942.       end if ;
  1943.     else
  1944.       --&KJW 21-jul-85 if not a_rcpt then
  1945.       if rcpt_count < 1 then            --&KJW 21-jul-85 
  1946.         put_line ("Must enter at least one rcpt") ;
  1947.       else
  1948.         exit ;
  1949.       end if ;
  1950.     end if ;
  1951.   end loop ;
  1952. exception
  1953.   when others =>
  1954.     put_line("exception in send_rcpt_list") ;
  1955.     raise ;
  1956. end send_rcpt_list ;
  1957. end usmtp_rcpt ;
  1958. --::::::::::::::
  1959. --usmtp.txt
  1960. --::::::::::::::
  1961. -----------------------------------------------------------------------
  1962. --
  1963. --         DoD Protocols    NA-00010-200       80-01231-100(-)
  1964. --         E-Systems, Inc.  August 07, 1985
  1965. --
  1966. --         usmtp.txt       Author : Paul Higgins
  1967. --
  1968. -----------------------------------------------------------------------
  1969. with real_time_clock_and_date;
  1970. use real_time_clock_and_date;
  1971. with text_io;             use text_io ;
  1972. with usmtp_utils ;        use usmtp_utils ;
  1973. with usmtp_connections;   use usmtp_connections ;
  1974. with usmtp_network ;      use usmtp_network ;
  1975. with usmtp_rcpt ;         use usmtp_rcpt ;
  1976. with usmtp_text ;         use usmtp_text ;
  1977. with usmtp_commands ;     use usmtp_commands ;
  1978. with buffer_data ;        use buffer_data ;
  1979. procedure usmtp is
  1980. name        : string (1..255) ;
  1981. name_length : integer ;
  1982. --&KJW 17-jul-85 continue    : string (1..255) := ('y', others => ' ') ;
  1983. continue    : string (1..255) ;        --&KJW 17-jul-85 
  1984. len         : integer ;
  1985. reply       : string(1..80) ;
  1986. begin
  1987. start_local_clock;
  1988. continue(1) := 'y';            --&KJW 17-jul-85 
  1989. for i in 2..continue'length loop    --&KJW 17-jul-85 
  1990.   continue(i) := ' ';            --&KJW 17-jul-85 
  1991. end loop;                --&KJW 17-jul-85 
  1992. put_line ("SMTP ver 1.0") ;
  1993. buffer_data.init ;
  1994. while continue(1) = 'y' loop
  1995.   begin
  1996.   establish_connection_and_send_helo ;
  1997.   put("Enter sender's name -> ");
  1998.   get_line(name,name_length) ;
  1999.   send_mail(name(1..name_length));
  2000.   get_reply(reply) ;
  2001.   if reply(1..3) /= helo_ok then
  2002.     put_line("Mail reply not received") ;
  2003.     raise unexpected_reply ;
  2004.   end if ;
  2005.   while continue(1) = 'y' loop
  2006.     send_rcpt_list ;
  2007.     send_text ;
  2008.     put_line("Any more mail for this host (y for yes)? " ) ;
  2009.     get_line(continue,len) ;
  2010.   end loop ;
  2011. --&KJW 11-jul-85 send_quit ;
  2012. --&KJW 11-jul-85 send_close_to_transport_layer ;
  2013. close_smtp_connection ;    --&KJW 11-jul-85 
  2014. exception
  2015.   when abort_usmtp =>
  2016.     put_line(" Exit SMTP ") ;
  2017.     raise ;
  2018.   when smtp_error =>
  2019.     put_line(" server replies error in transmission... connection aborted ") ;
  2020.   when unexpected_reply =>
  2021.     put_line(" error in server - unexpected reply... connection aborted ") ;
  2022.   when tcp_reset =>
  2023.     put_line(" error in tcp transmission... connection aborted ") ;
  2024.   when others =>
  2025.     put_line ("unknown exception in smtp... exiting") ;
  2026.     raise ;
  2027.   end ;
  2028. put_line("Any more mail to send  (y for yes)? " ) ;
  2029. get_line(continue,len) ;
  2030. end loop ;
  2031. put_line(" Exit SMTP ") ;
  2032. exception
  2033.   when others =>
  2034.     put_line ("unknown exception in smtp... exiting") ;
  2035. end usmtp ;
  2036. --::::::::::::::
  2037. --utext.txt
  2038. --::::::::::::::
  2039. -----------------------------------------------------------------------
  2040. --
  2041. --         DoD Protocols    NA-00010-200       80-01232-100(-)
  2042. --         E-Systems, Inc.  August 07, 1985
  2043. --
  2044. --         utext.txt       Author : Paul Higgins
  2045. --
  2046. -----------------------------------------------------------------------
  2047. package usmtp_text is
  2048. --
  2049. -- This package supports the mail data entry mode of usmtp.
  2050. --
  2051. procedure send_text ;
  2052. --
  2053. -- Continually get lines from the user and send them to the transport
  2054. --   layer until end-of-message is found. 
  2055. --
  2056. end usmtp_text ;
  2057. with text_io;           use text_io ;
  2058. with usmtp_utils ;      use usmtp_utils ;
  2059. with usmtp_connections; use usmtp_connections ;
  2060. with usmtp_network ;    use usmtp_network ;
  2061. with usmtp_commands ;   use usmtp_commands ;
  2062. with usmtp_network ;    use usmtp_network ;
  2063. package body usmtp_text is
  2064. procedure send_text is
  2065. --
  2066. -- keep getting lines of data from the user and sending them to the transport
  2067. --   layer until an end-of-message is found.
  2068. --
  2069. -- Limitations:
  2070. --  Current end of message :  <CRLF>.<CRLF>
  2071. --  does not support mailing files.
  2072. --
  2073.   data_line : string(1..max_line_len) ;
  2074.   eol : natural ;
  2075.   reply : string(1..80) ;
  2076.   eof : boolean := false ;
  2077.   --&KJW 21-jul-85 end_mark : string (1..1) ;  -- could be a character if TS allowed it
  2078. begin
  2079. --&KJW 21-jul-85 end_mark(1) := '.' ;
  2080. send_data_to_server ;
  2081. get_reply(reply) ;
  2082. if reply(1..3) /= send_data_ok then
  2083.   put_line("server not responding") ;
  2084.   send_abort_to_transport ;
  2085. else
  2086.   put_line("Enter data. Terminate message with <CRLF>.<CRLF> ") ;
  2087.   while not eof loop
  2088.     get_line(data_line,eol) ;
  2089.     --&KJW 21-jul-85 if data_line(1..eol) = end_mark then
  2090.     --&KJW 21-jul-85   put_line("End of file found") ;
  2091.     --&KJW 21-jul-85   eof := true ;
  2092.     --&KJW 21-jul-85 elsif data_line(1..1) = "."  then 
  2093.     --&KJW 21-jul-85   data_line := " " & data_line(1..79) ;
  2094.     --&KJW 21-jul-85   eol := eol + 1 ;
  2095.     --&KJW 21-jul-85 end if ;
  2096.     --&KJW 21-jul-85 send_string(data_line(1..eol)) ;
  2097.     if data_line(1) = '.' then
  2098.       eof := eol = 1 ;
  2099.       if eof then
  2100.         --&KJW 23-jul-85 put_line("End of file found") ;
  2101.         send_string(".") ;
  2102.       else
  2103.         send_string("." & data_line(1..eol)) ;
  2104.       end if ;
  2105.     else
  2106.       send_string(data_line(1..eol)) ;
  2107.     end if ;
  2108.   end loop ;
  2109.   get_reply(reply) ;
  2110.   if reply(1..3) /= data_ok then 
  2111.     put_line ("server could not deliver") ;
  2112.   end if ;
  2113. end if ;
  2114. exception
  2115.   when others =>
  2116.     put_line("exception in send_text") ;
  2117.     raise ;
  2118. end  send_text ;
  2119. end usmtp_text ;
  2120. --::::::::::::::
  2121. --uutils.txt
  2122. --::::::::::::::
  2123. -----------------------------------------------------------------------
  2124. --
  2125. --         DoD Protocols    NA-00010-200       80-01233-100(-)
  2126. --         E-Systems, Inc.  August 07, 1985
  2127. --
  2128. --         uutils.txt       Author : Paul Higgins
  2129. --
  2130. -----------------------------------------------------------------------
  2131. -------------------------------------------------------------------------------
  2132. --
  2133. -- USMTP globals
  2134. --
  2135. package usmtp_utils is
  2136.   -- abnormal conditions:
  2137.   abort_usmtp : exception ;       -- user requests exit
  2138.   smtp_error  : exception ;       -- server sends error code (4xx or 5xx)
  2139.   unexpected_reply : exception ;  -- server sends insane reply
  2140.   tcp_reset   : exception ;       -- tcp resets connection
  2141.   -- implementation constraints
  2142.   max_line_len : constant integer := 80 ;
  2143. -- the following are the known replies to usmtp
  2144. open_ok      : constant string(1..3) := "220" ;
  2145. data_ok      : constant string(1..3) := "250" ;
  2146. send_data_ok : constant string(1..3) := "354" ;
  2147. rcpt_ok      : constant string(1..3) := "250" ;
  2148. will_forward : constant string(1..3) := "251" ;
  2149. helo_ok      : constant string(1..3) := "250" ;
  2150. quit_ok      : constant string(1..3) := "221" ;
  2151. end usmtp_utils ;
  2152. package body usmtp_utils is
  2153. end usmtp_utils ;
  2154. --::::::::::::::
  2155. --xhost.txt
  2156. --::::::::::::::
  2157. -----------------------------------------------------------------------
  2158. --
  2159. --         DoD Protocols    NA-00010-200       80-01234-100(-)
  2160. --         E-Systems, Inc.  August 07, 1985
  2161. --
  2162. --         xhost.txt       Author : Paul Higgins
  2163. --
  2164. -----------------------------------------------------------------------
  2165. with buffer_data ;      -- to import address type 
  2166. package xhost is
  2167. --
  2168. -- Utilities to translate host names to host addresses
  2169. -- Only TCP format addresses supported
  2170. -- could add some table maintainence procedures here if desired
  2171. --
  2172. procedure translate_host_name_to_address
  2173. --
  2174. -- Look up the host name in the table and return the address.
  2175. --
  2176.    (host_name    :  in string ;
  2177.     host_id      : out buffer_data.thirtytwo_bits ;  -- an internet address
  2178.     host_name_ok : out boolean ) ;
  2179. end ;
  2180. with text_io ;       use text_io ;
  2181. with usmtp_utils ;   use usmtp_utils ;
  2182. with buffer_data ;   use buffer_data ;  -- for type thirtytwo_bits
  2183. package body xhost is
  2184. type name_id_pair is record 
  2185.   name : string (1..80) ;
  2186.   id   : buffer_data.thirtytwo_bits ;
  2187. end record ;
  2188. --&KJW 16-jul-85 a_blank_line : string (1..80) := ( others => ' ' ) ;
  2189. a_blank_line : string (1..80) ;    --&KJW 16-jul-85 
  2190. a_name : string (1..80) ;
  2191. an_id  : thirtytwo_bits ;
  2192. --&KJW 16-jul-85 host_name_table : array (1..10) of name_id_pair :=
  2193. --&KJW 16-jul-85     ( others => (a_blank_line, 0) ) ;
  2194. host_name_table : array (1..10) of name_id_pair ;    --&KJW 16-jul-85 
  2195. number_of_hosts : integer range 1..10 ;
  2196. procedure translate_host_name_to_address
  2197. --
  2198. -- Look up the host name in the table and return the address.
  2199. --
  2200.    (host_name    :  in string ;
  2201.     host_id      : out thirtytwo_bits ;
  2202.     host_name_ok : out boolean ) is
  2203. begin
  2204. host_name_ok := false ;
  2205. a_name := a_blank_line ;
  2206. a_name(1..host_name'length) := host_name ;
  2207. for i in 1..number_of_hosts loop
  2208.   if a_name = host_name_table(i).name then
  2209.     host_id := host_name_table(i).id ;
  2210.     host_name_ok := true ;
  2211.     exit ;
  2212.     end if ;
  2213. end loop ;
  2214. exception
  2215.   when others =>
  2216.     put_line("EXCEPTION IN TRANSLATE_HOST_NAME") ;
  2217.     raise ;
  2218. end ;
  2219. begin
  2220. for char in 1..80 loop        --&KJW 16-jul-85
  2221.   a_blank_line(char) := ' ';    --&KJW 16-jul-85
  2222. end loop;            --&KJW 16-jul-85
  2223. for host in 1..10 loop                --&KJW 16-jul-85 
  2224.   host_name_table(host) := (a_blank_line, 0);    --&KJW 16-jul-85 
  2225. end loop;                    --&KJW 16-jul-85 
  2226. a_name := a_blank_line ;    
  2227. a_name(1..6) := "saturn" ;
  2228. an_id :=  1 ;
  2229. host_name_table (1) := (a_name, an_id) ;
  2230. a_name := a_blank_line ;    
  2231. a_name(1..4) := "mars" ;
  2232. an_id := 2 ;
  2233. host_name_table (2) := (a_name, an_id) ;
  2234. a_name := a_blank_line ;    
  2235. a_name(1..5) := "wicat" ;
  2236. an_id := 3 ;
  2237. host_name_table (3) := (a_name, an_id) ;
  2238. number_of_hosts := 3 ;
  2239. end xhost ;
  2240.