IMPLEMENTATION MODULE EconetDate ;

(* Obtains the date from the network fileserver *)

FROM Econet IMPORT Errors , ControlBlockR ,
                   Transmit , InitiateReceive , Receive ;
IMPORT Debug ;
FROM Debug IMPORT WriteS , Wrch ;
FROM SYSTEM IMPORT ADR , TKCALL ;
FROM TKCalls IMPORT TKstring , TKnewl , TKcli ;
FROM String IMPORT CopyLC ;

PROCEDURE FindEconetDate(FileServerBridge : CARDINAL;
                         FileServerStation : CARDINAL;
                         VAR TheDate : ARRAY OF CHAR) : INTEGER ;

CONST
   MyPort                    = 1 ;
   FileServerPort            = 099H ;   (* File servers listen on this port *)
   SizeOfBuffer              = 20 ;

TYPE
   EightBit                  = CHAR ;


VAR
   ReplyBuffer               : ARRAY [ 0..SizeOfBuffer ] OF EightBit ;
   RequestBuffer             : ARRAY [ 0..SizeOfBuffer ] OF EightBit ;
   Why                       : Errors ;
   ErrorString               : ARRAY [ 0..30 ] OF CHAR ;
   I                         : CARDINAL ;
   RxControlBlock            : ControlBlockR ;
   TxControlBlock            : ControlBlockR ;

   MonthString               : ARRAY [ 0..35 ] OF CHAR ;
   MonthOffset               : [ 0..33 ] ;

   PROCEDURE PutNumber( VAR String : ARRAY OF CHAR ;
                        Offset : CARDINAL ;
                        Number : CARDINAL ) ;
   BEGIN
      IF Number > 9 THEN
         PutNumber( String , Offset - 1 , Number DIV 10 ) ;
      END (* if *) ;
      String[ Offset ] := CHAR( ( Number MOD 10 ) + ORD( '0' ) ) ;
   END PutNumber ;

BEGIN
   RxControlBlock.Port := MyPort ;
   RxControlBlock.Station.Number := 00H ;
   RxControlBlock.Station.Bridge := 0 ;
   RxControlBlock.Buffer := ADR( ReplyBuffer ) ;
   RxControlBlock.Length := 7 ;
   InitiateReceive( RxControlBlock ) ;
   TxControlBlock.Command := 080H ;
   TxControlBlock.Port := FileServerPort ;
   TxControlBlock.Station.Number := FileServerStation ;
   TxControlBlock.Station.Bridge := FileServerBridge ;
   TxControlBlock.Buffer := ADR( RequestBuffer ) ;
   TxControlBlock.Length := 5 ;
   RequestBuffer[ 0 ] := EightBit( MyPort ) ;
   RequestBuffer[ 1 ] := EightBit( 16 ) ;  (* Please send the date and time *)
   RequestBuffer[ 2 ] := EightBit( 000H ) ;
   RequestBuffer[ 3 ] := EightBit( 000H ) ;
   RequestBuffer[ 4 ] := EightBit( 000H ) ;
   IF NOT Transmit( TxControlBlock , Why ) THEN
      CASE Why OF
      ErrorJammed :
         ErrorString := "Line Jammed" ;
   |
      ErrorDamaged :
         ErrorString := "Packet Damaged" ;
   |
      ErrorNotListening :
         ErrorString := "Not Listening" ;
   |
      ErrorNoClock :
         ErrorString := "No Clock" ;
   |
      ErrorBadTxControl :
         ErrorString := "Bad Transmit Control block" ;
      ELSE
         ErrorString := "Strange net Error" ;
      END (* case *) ;
      Debug.WriteS( "Cannot read the date because : *'" ) ;
      Debug.WriteS( ErrorString ) ;
      Debug.WriteS( "*'*N" ) ;
      RETURN -42 ;
   ELSE
      Receive( RxControlBlock ) ;
      (* date format dd-mmm-yy hh:mm:ss
                     012345678901234567    *)
      CopyLC( "00-mmm-yy 00:00:00" , TheDate ) ;
      MonthString := "JanFebMarAprMayJunJulAugSepOctNovDec" ;
      PutNumber( TheDate , 17 , CARDINAL( ReplyBuffer[ 6 ] ) ) ;
      PutNumber( TheDate , 14 , CARDINAL( ReplyBuffer[ 5 ] ) ) ;
      PutNumber( TheDate , 11 , CARDINAL( ReplyBuffer[ 4 ] ) ) ;
      MonthOffset := ( ( CARDINAL( ReplyBuffer[ 3 ] ) MOD 16 ) - 1 ) * 3 ;
      FOR I := 0 TO 2 DO
         TheDate[ 3 + I ] := MonthString[ MonthOffset + I ] ;
      END (* for *) ;
      PutNumber( TheDate ,  8 ,
                           ( CARDINAL( ReplyBuffer[ 3 ] ) DIV 16 ) + 81 ) ;
      PutNumber( TheDate ,  1 , CARDINAL( ReplyBuffer[ 2 ] ) ) ;
      RETURN 0 ;
   END (* if *) ;
END FindEconetDate ;

(* ========================================================================= *)

PROCEDURE SetEconetDate(FileServerBridge : CARDINAL;
                        FileServerStation : CARDINAL;
                        VAR TheDate : ARRAY OF CHAR ) : INTEGER ;

CONST
   MyPort                    = 1 ;
   FileServerPort            = 099H ;   (* File servers listen on this port *)
   SizeOfBuffer              = 20 ;

TYPE
   EightBit                  = CHAR ;


VAR
   ReplyBuffer               : ARRAY [ 0..SizeOfBuffer ] OF EightBit ;
   RequestBuffer             : ARRAY [ 0..SizeOfBuffer ] OF EightBit ;
   Why                       : Errors ;
   ErrorString               : ARRAY [ 0..30 ] OF CHAR ;
   I                         : CARDINAL ;
   RxControlBlock            : ControlBlockR ;
   TxControlBlock            : ControlBlockR ;

   MonthString               : ARRAY [ 0..35 ] OF CHAR ;
   MonthOffset               : [ 0..33 ] ;

   PROCEDURE GetNumber( VAR String : ARRAY OF CHAR ;
                        Offset : CARDINAL ) : CARDINAL ;

      PROCEDURE Digit( Ch : CHAR ) : CARDINAL ;
      BEGIN
         IF ( '0' <= Ch ) AND ( Ch <= '9' ) THEN
            RETURN ORD( Ch ) - ORD( '0' ) ;
         ELSE
            RETURN 0 ;
         END (* if *) ;
      END Digit ;

   VAR Result : INTEGER ;
   BEGIN
      RETURN Digit( String[ Offset - 1 ] ) * 10 + Digit( String[ Offset ] ) ;
   END GetNumber ;

BEGIN
   RxControlBlock.Port := MyPort ;
   RxControlBlock.Station.Number := 00H ;
   RxControlBlock.Station.Bridge := 0 ;
   RxControlBlock.Buffer := ADR( ReplyBuffer ) ;
   RxControlBlock.Length := 7 ;
   InitiateReceive( RxControlBlock ) ;
   TxControlBlock.Command := 080H ;
   TxControlBlock.Port := FileServerPort ;
   TxControlBlock.Station.Number := FileServerStation ;
   TxControlBlock.Station.Bridge := FileServerBridge ;
   TxControlBlock.Buffer := ADR( RequestBuffer ) ;
   TxControlBlock.Length := 10 ;
   RequestBuffer[ 0 ] := EightBit( MyPort ) ;
   RequestBuffer[ 1 ] := EightBit( 28 ) ;  (* Here is a new date and time *)
   RequestBuffer[ 2 ] := EightBit( 000H ) ;
   RequestBuffer[ 3 ] := EightBit( 000H ) ;
   RequestBuffer[ 4 ] := EightBit( 000H ) ;
   (* Thedate format is 19yy-mm-dd hh:mm:ss.ss
                        0123456789012345678901
   *)
   RequestBuffer[ 5 ] := EightBit( GetNumber( TheDate ,  9 ) ) ;
   RequestBuffer[ 6 ] := EightBit( ( GetNumber( TheDate ,  3 ) - 81 ) * 16 +
                                   GetNumber( TheDate ,  6 ) ) ;
   RequestBuffer[ 7 ] := EightBit( GetNumber( TheDate , 12 ) ) ;
   RequestBuffer[ 8 ] := EightBit( GetNumber( TheDate , 15 ) ) ;
   RequestBuffer[ 9 ] := EightBit( GetNumber( TheDate , 18 ) ) ;
   IF NOT Transmit( TxControlBlock , Why ) THEN
      CASE Why OF
      ErrorJammed :
         ErrorString := "Line Jammed" ;
   |
      ErrorDamaged :
         ErrorString := "Packet Damaged" ;
   |
      ErrorNotListening :
         ErrorString := "Not Listening" ;
   |
      ErrorNoClock :
         ErrorString := "No Clock" ;
   |
      ErrorBadTxControl :
         ErrorString := "Bad Transmit Control block" ;
      ELSE
         ErrorString := "Strange net Error" ;
      END (* case *) ;
      Debug.WriteS( "Cannot read the date because : *'" ) ;
      Debug.WriteS( ErrorString ) ;
      Debug.WriteS( "*'*N" ) ;
      RETURN -43 ;
   ELSE
      Receive( RxControlBlock ) ;
      RETURN 0 ;
   END (* if *) ;
END SetEconetDate ;

END EconetDate.                                
