home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 13 / CDA13.ISO / cdactual / demobin / share / program / Pascal / 10TLST.ZIP / TENTOOLS.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1990-10-17  |  55.7 KB  |  1,734 lines

  1. {$F+}
  2. Unit TenTools;
  3.  
  4. Interface
  5.  
  6. Uses DOS,CRT;
  7.  
  8. CONST
  9.    TNTI : Boolean = False; {Initialized False, this Boolean tells whether the
  10.                      the initialization procedure has been run successfully.}
  11.    HPointer : Integer =1;
  12.   TPointer : Integer =1;
  13.    CPointer : Integer =1;
  14.  
  15. { The next three parameters can be set dynamically using the
  16.   TenConfig Function}
  17.                                           MaxSendBufferSize : Word = 0;  {Size of largest record to TBsend}
  18.    MaxRecBufferSize : Word = 0;  {Size of largest record to TBreceive}
  19.    MaxReceives : Integer = 0;   {Number of TBReceives to buffer}
  20.  
  21. {This parameter will change if TenConfig is called with new MAXRECBUFFERSIZE}
  22.  
  23. {   MaxRecvSets = MaxRecBufferSize div 457 + 1; }
  24.  
  25.    MAXRCVWAIT : Integer = 30; {Can be changed through SetWait function}
  26.  
  27.    SCLim : Array[0..6] of Integer = (1,99,12,28,24,60,60);
  28.    SCMon : Array[1..12] of Integer= (31,28,31,30,31,30,31,31,30,31,30,31);
  29.    SCMin : Array[0..6] of Integer = (0,0,1,1,0,0,0);
  30.  
  31. TYPE
  32.  
  33.    PW8 = Array[1..8] of Char;              {Used for 8 character password  }
  34.    SID = Array[1..12] of Char;             {Used for 12 character serverID }
  35.    S8 = String[8];
  36.    String80 = String[80];
  37.    S12 = String[12];
  38.    S15 = String[15];
  39.    TID = Real;
  40.    TStamp = Real;
  41.    RcvBlock = Array[1..457] of Char;
  42.    MAXBytes = Array[1..65521] of Byte;
  43.    ChatBytes = Array[1..100] of Byte;
  44.    PathString = String[128];
  45.    NotifyTypes = (Start,Reply,Completion,ExplQueue,NoFF,IDPage,QueueTop);
  46.    NotifySet = Set of NotifyTypes;
  47.  
  48. {The Pre-Configuration Table and the Configuration Table are the Internal
  49.  Structures within 10Net's Data Segment. These Tables provide information
  50.  that is necessary for some of the functions in this toolbox. They are
  51.  already allocated by 10Net when it is loaded and add no extra memory usage
  52.  to the toolbox. }
  53.    PreConfigurationTable =
  54.    Record
  55.       {First variable located at CTAB-51 bytes or PreCTAB }
  56.       PCT_PhyAddr : Array[1..6] of Byte;   {Physical Adapter Address       }
  57.       PCT_NPID    : Word;               {NPID Table Address             }
  58.       PCT_NCBFST  : Word;               {First NCB in Pool              }
  59.       PCT_LDEVTAB : Word;               {Local Dev Table Addr(FOXCOM)   }
  60.       PCT_EXT_MAP : Word;               {Extended Network Err Table Addr}
  61.       PCT_SDEVTAB : Word;               {SDEV Address                   }
  62.       PCT_RESV1   : Integer;
  63.       PCT_RBUFCNT : Byte;                  {Receive Buffer Counter         }
  64.       PCT_CBUF_CNT: Byte;                  {Collect Buffer Counter         }
  65.       PCT_TUF     : Word;               {TUF Address                    }
  66.       PCT_ENABLE  : Byte;                  {Enable Flag                    }
  67.       PCT_KEEP    : Byte;                  {FCB Keep Flag                  }
  68.       PCT_RESV2   : Integer;
  69.       PCT_DS6F    : Integer;               {Dropped Send 6F Count          }
  70.       PCT_BFRST   : Integer;               {Buffer Chain                   }
  71.       PCT_RESV3   : Integer;
  72.       PCT_RTY     : Integer;               {Broadcast Retry Count          }
  73.       PCT_TOVAL   : Byte;                  {#FFFF Loops before retry       }
  74.       PCT_UFH     : Word;               {UFH Address                    }
  75.       PCT_NETH    : Word;               {NetH Address                   }
  76.       PCT_LTAB    : Word;               {LTab Address                   }
  77.       PCT_SFH     : Word;               {SFH Address                    }
  78.       PCT_FTAB    : Word;               {FTAB Address                   }
  79.       PCT_RLTAB   : Word;               {RLTAB Address                  }
  80.       PCT_SMI     : Word;               {Semaphore Address              }
  81.       PCT_NTAB    : Word;               {NTAB Address                   }
  82.      End;
  83.  
  84.      ConfigurationTable =
  85.       Record
  86.       CT_REDIR    : Word;               {Redirection Table Address      }
  87.                                            {sometimes called CT_ADDR       }
  88.       CT_NUM      : Byte;               {RDR_TAB Entries- 5(LPT1-3 & AUX-2)}
  89.       CT_LNAME    : PW8;                   {Login Name                     }
  90.       CT_NID      : Array[1..15] of Char;  {Node ID                        }
  91.       CT_UNODE    : Array[1..3] of Char;   {Unique portion of Node Address }
  92.       CT_FLG      : Byte;                  {Flag (DPC - Bit 6)             }
  93.       CT_CFLG     : Byte;                  {Chat permit flag               }
  94.       CT_PSFLG    : Byte;                  {Print and Submit Flag          }
  95.       CT_NETFLGS  : Array[1..2] of Byte;   {10Net System Status Flag       }
  96.       CT_L_INT    : Byte;                  {Last Interrupt                 }
  97.       CT_L21      : Byte;                  {Last Interrupt 21              }
  98.       CT_L6F      : Byte;                  {Last Interrupt 6F              }
  99.       CT_L60      : Byte;                  {Last Interrupt 60              }
  100.       CT_BFLG     : Byte;                  {Break Flag                     }
  101.       CT_BTYP     : Integer;               {Break Type                     }
  102.       CT_TALY     : Array[1..6] of Integer;{Send Tallies                   }
  103.  
  104.       CT_PENDF    : Byte;                  {DO_COND Pending COMMAND MAP    }
  105.       CT_CERRF    : Byte;                  {Reserved                       }
  106.  
  107.       CT_RESV2    : Array[1..5] of Byte;   {Reserved                       }
  108.  
  109.       CT_CB       : Byte;                  {CB Channel                     }
  110.       CT_CBCNT    : Byte;                  {Send6F on Que                  }
  111.       CT_CBCHL    : Array[1..9] of Byte;   {Chnls 1-9 Activity             }
  112.       CT_GATE     : Byte;                  {Bits: 1-RS232Gate, 2-Send6FGate}
  113.       CT_RGATE    : Array[1..2] of Integer;{Dbl word ptr into Gate         }
  114.       CT_SGATE    : Array[1..2] of Integer;{Dbl word ptr into 10Net Send   }
  115.       CT_TIMR     : Integer;               {Address of Timer Blocks        }
  116.  
  117.       {Those variables below are only implemented in 10Net 4.1 and above}
  118.       CT_CTSTO    : Integer;               {Datagram send time out value   }
  119.       CT_DGRETRY  : Byte;                  {Datagram retry count           }
  120.       CT_NCBMSES  : Byte;                  {Max Netbios sessions           }
  121.       CT_NCBMCOMM : Byte;                  {Max Netbios command blocks     }
  122.       CT_BUFFNUM  : Byte;                  {Number of total buffers        }
  123.       CT_CLCTNUM  : Byte;                  {Number of Collect buffers      }
  124.       CT_CLCTFST  : Integer;               {Offs of 1st coll. buffer chain }
  125.       CT_DEVMASK  : Word;                  {Shared disk drives bit mask    }
  126.       CT_DEVPRN   : Byte;                  {Shared LPT bit mask            }
  127.       CT_DEVCOM   : Byte;                  {Shared COM bit mask            }
  128.       CT_RESV3    : LongInt;               {Reserved}
  129.       CT_DOSVER   : Integer;               {Dos Version(Int21/30)          }
  130.       CT_PHYSDRVS : Byte;                  {Number of physical drives      }
  131.       CT_RESV4    : Array[1..13] of Byte;  {Reserved}
  132.       CT_SRVNUM   : Byte;                  {Server NCB Name Number         }
  133.       CT_RDRNUM   : Byte;                  {Redirector NCB Name Number     }
  134.       CT_MSGNUM   : Byte;                  {Messenger NCB Name Number      }
  135.       CT_RESV5    : LongInt;               {Reserved}
  136.       CT_CHATCALL : Integer;               {Chat Call Key                  }
  137.       CT_CHATIME  : Integer;               {Chat Time Out                  }
  138.       CT_AUTOSP1  : Byte;                  {AutoSP Flag (0=No AutoSp)      }
  139.       CT_AUTOSP2  : Byte;                  {TMR_TIC=CT_AutoSP1*Ct_AutoSP2  }
  140.    End;
  141.  
  142. { What follows are structures used in function calls}
  143.  
  144.    TenNetTableRec = Record
  145.        Alloc : Integer;
  146.         Free : Integer;
  147.     Reserved : Integer;
  148.      end;
  149.  
  150.    GetTableDataRec = Record
  151.            NodeID : SID;
  152.            RES1   : Byte;
  153.        ServerFlag : Byte;                  { 0=Worker, 1=Server           }
  154.        BufferSize : Integer;               { Size of Receive Buffers      }
  155.       TotalMemory : Integer;               { Total RAM memory in K        }
  156.       TenNetMemory : LongInt;               { Memory alloc. to 10Net (bytes}
  157.       AvailMemory : LongInt;               { Available Memory in Bytes    }
  158.       TenNetTables : Array[1..22] of
  159.                     TenNetTableRec;
  160.        DeviceList : Array[1..64] of Char;
  161.        SecurityFN : Array[1..64] of Char;
  162.           AuditFN : Array[1..64] of Char;
  163.      PrimaryDrive : Array[1..2] of Char;
  164.         OtherJunk : Array[1..48] of Char;
  165.     end;
  166.  
  167.    LogRec = Record
  168.       UserName : PW8;
  169.       PassWord : PW8;
  170.       NodeName : SID;
  171.    end;
  172.  
  173.    SendFormat = Record
  174.       RNode : SID;
  175.       DataBytes : Integer;
  176.    End;
  177.  
  178.    PRec = Record
  179.       TransID : TID;     {6 bytes}
  180.        Packet : Byte;    {1}
  181.      TPackets : Byte;    {1}
  182.         TType : Integer; {2}
  183.       TLength : Integer; {2}
  184.      RespType : Byte;    {1}
  185.    end;
  186.  
  187.    RecSet = set of 1..144;
  188.  
  189.    DateTimeRec = Record
  190.            Year,Month,Day,Hour,Minute,Second : Integer;
  191.     End;
  192.  
  193.    RecvRec = Record
  194.        Sender : S12;
  195.       TransID : TID;
  196.     TrackRecv : RecSet;
  197.         TType : Integer;
  198.       TLength : Integer;
  199.      RespType : Byte;
  200.         RTime : Real;
  201.            CB : Boolean;
  202.    end;
  203.  
  204.    RecvData = Array[1..143] of RcvBlock;
  205.  
  206.  
  207.    HeapRecBlock = Array[1..1310] of RecvRec;
  208.    HeapDataBlock = Array[1..2040] of ^RecvData;
  209.  
  210.    ChRec = Record
  211.         MsgLength : Integer;
  212.         ChatText : Array[1..101] of Char;
  213.    end;
  214.  
  215.    NodeRec = Record
  216.         NID : SID;
  217.         NT : Byte;
  218.         UID : Array[1..8] of Char;
  219.         Ver : Array[1..3] of Char;
  220.    end;
  221.    NARec = S12;
  222.    NWRec = Record
  223.         NID : SID;
  224.         Ver : Array[1..4] of Byte;
  225.    end;
  226.    NBuffer = Array[1..140] of NodeRec;
  227.    NABuffer = Array[1..140] of NARec;
  228.    NWBuffer = Array[1..140] of NWRec;
  229.  
  230.    SDRec = Record             {MountList/NetUse List Record Structure}
  231.          ServerID : S12;
  232.           RPath : PathString;
  233.      end;
  234.  
  235.    DriveArray = Array['A'..'Z'] of SDRec;
  236.  
  237.    PrintArray = Array['1'..'3'] of SDRec;
  238.  
  239.    LogArray = Array[0..19] of S12;
  240.    DeviceArray = Array[0..24] of S8;
  241.    SDev = Record         {used in Get/Set/Delete/Get User Shared Device}
  242.         Alias : PW8;
  243.         Path : Array[1..64] of Char;
  244.         PassWord : PW8;
  245.         Access : Byte;
  246.         Mask : Array[1..4] of Char;
  247.      end;
  248.  
  249.  
  250.   StatusBlock = Record
  251.       S_Name : Array[1..8] of Char;  {User Name}
  252.       S_Flag : Byte;                 {0-user node,1-superstation,2-gate,
  253.                                       3-gateactive,4-on more than 2 superstns,
  254.                                       5-Reserved}
  255.       S_Srvr : Array[1..24] of Byte; {Superstation Nodes logged into (reserved)}
  256.       S_NID : SID;                   {NodeID}
  257.       Reserved0 : Array[1..2] of Byte;
  258.  
  259.       {From Superstations:}
  260.  
  261.       S_SDRV : Array[1..2] of Byte;  {Drives avail: Bits 0-15/A-P}
  262.       S_UFlag : Byte;                {User Service Flag:
  263.                                       0-Mail for you     1-News for you
  264.                                       2-Calendar for you 3-Mail for Node
  265.                                       4-Submit ON        6-Print Permit ON
  266.                                       6-Gate                               }
  267.       S_SPRTRT : Byte;               {Bit 0-7 set for Printers 1-3    }
  268.       Reserved1 : Array[1..3] of Byte;
  269.       S_PRIU   : Byte;               {Primary Unit (0=A,1=B,etc) }
  270.       Reserved2 : Byte;
  271.       LoggedNodes : Array[1..444] of Char; {Logged on NodeIDS}
  272.       S_Time : Array[1..3] of Byte;  {Time: SEC/MIN/HR}
  273.       S_Date : Array[1..3] of Byte;  {Date: DAY/MON/YR-1980}
  274.       Reserved3 : Array[1..6] of Byte;
  275.   end;
  276.  
  277.    SpoolBlock = Record
  278.     UCode : Integer;
  279.     UFile : Array[1..11] of Char;
  280.     UNote : Byte;
  281.     UDays : Byte;
  282.     UDVC : Byte;
  283.     ULen : Integer;
  284.     UArea : Byte;
  285.    end;
  286.  
  287. {These variable declarations allocate approximately 1660 bytes of memory
  288.  to the Tentools Unit}
  289.  
  290. VAR
  291.    I10 : Integer;
  292.    TenTest : Word;
  293.    TenRegs : Registers;
  294.    SendSet : SendFormat;
  295.    SendBuffer : Array[1..470] of Char;
  296.    ReceiveBuffer : Array[1..484] of Byte;
  297.    LogData : LogRec;
  298.    PreConfig : ^PreConfigurationTable;
  299.    ConfigTable : ^ConfigurationTable;
  300.    UserName : String[8];
  301.    DataBuffer : Array[1..470] of Byte;
  302.    PacketRec : PRec;
  303.    ChatRec : ChRec;
  304.    TBR : ^HeapRecBlock;
  305.    TBD : ^HeapDataBlock;
  306.    MaxRecvSets : Integer;
  307.    NodeArray : ^NBuffer;
  308.    NAArray : ^NABuffer;
  309.    NWArray : ^NWBuffer;
  310.    SpoolSettings : SpoolBlock;
  311.    Spooling : Boolean;
  312.  
  313. { The Procedures/Functions }
  314.  
  315. Function TimeStamp : Real;
  316.  
  317. Function StampAge(StartTime : Real): LongInt;
  318.  
  319. Function Loaded : Boolean;
  320.  
  321. Function Chat(NodeID : S12; VAR DBuffer {:String[n]} ) : Word;
  322.  
  323. Function Status(NodeName : S15; VAR SBlock : StatusBlock): Word;
  324.  
  325. Function NODEName : S12;
  326.  
  327. Function Login(ServerID : S12;PW10Net : S8): Word;
  328.  
  329. Function Logoff(ServerID : S12): Word;
  330.  
  331. Function Mount(ServerID : S12; LocalDevice,RemoteDevice : Char) : Word;
  332.  
  333. Function UnMount(LocalDrive : Char) : Word;
  334.  
  335. Function Send(NodeID : S12; VAR DBuffer; DLength :Integer): Word;
  336.  
  337. Function Receive(VAR DBuffer; Secs : Word; VAR Available : Integer; VAR CBMessage : Boolean): Word;
  338.  
  339. Function GetRemoteMemory(NodeID : S12; VAR DBuffer; VAR DLength : Integer;
  340.                          RemSeg,RemOfs : Word) : Word;
  341.  
  342. Procedure SetCBChannel(CBChannel : Byte);
  343.  
  344. Function TBSend(NodeID : S12;VAR DBuffer;DLength : Integer;TransactionID : TID;
  345.                 TransType : Integer;ResponseType : Byte) : Word;
  346.  
  347. Function TBReceive(VAR SenderID: S12;VAR DBuffer;VAR DLength : Integer;
  348.                    VAR TransactionID : TID;VAR TransType : Integer;
  349.                    VAR Available : Integer;VAR CB : Boolean): Word;
  350.  
  351. Function Nodes(VAR NodeBuffer;VAR MaxNodes : Integer;SuperstationsOnly : Boolean) : Word;
  352.  
  353. Function MountList(VAR MountTable : DriveArray;VAR PrintTable : PrintArray;VAR TableEntries : Integer): Word;
  354.  
  355. Function LogList(VAR Logins : LogArray;VAR TableEntries : Integer): Word;
  356.  
  357. Function GetTableData(VAR TableBuffer : GetTableDataRec): Word;
  358.  
  359. Function MountsAvail : Integer;
  360.  
  361. Function TenConfig(MaxSendRec,MaxRecvRec : Integer;MaxRecs : Integer) : Word;
  362.  
  363. Function SetWait(WaitLimit : Integer): Word;
  364.  
  365. Procedure SetUserName(UName : S8);
  366.  
  367. Function Get10Time(NodeName : S15 ;VAR TenTime : DateTimeRec) : Word;
  368.  
  369. Function GetDevices(ServerID : S12;VAR Device : DeviceArray;VAR DeviceCount : Integer): Word;
  370.  
  371. Function NetUse(ServerID : S12; LocalDrive : Char; RemoteDevice : String;NetUsePassWord : S8) : Word;
  372.  
  373. Function UnUse(LocalDrive : Char) : Word;
  374.  
  375. Function Submit(ServerID : S12; CommandLine : String): Word;
  376.  
  377. Function SetSpool(Printer : Byte; SpoolName : S12; Notification : NotifySet; RDays : Byte): Word;
  378.  
  379. Function OpenSpool(NewSpoolName : S12) : Word;
  380.  
  381. Function CloseSpool : Word;
  382.  
  383. Function UpCase8(Str_8 : S8): S8;
  384.  
  385. Function UpCase12(Str_12 : S12): S12;
  386.  
  387. {******************************************************************************}
  388.  
  389.  
  390. Implementation
  391.  
  392. Function UpCase12(Str_12 : S12): S12;
  393. {Expands and "Upcases" a 12 character string}
  394. VAR I : Integer;
  395. Begin
  396.    For I:=1 to Length(Str_12) do Str_12[I]:=Upcase(Str_12[I]);
  397.    While Length(Str_12)<12 do Str_12:=Str_12+' ';
  398.    UpCase12:=Str_12;
  399. End;
  400.  
  401. Function UpCase8(Str_8 : S8): S8;
  402. {Expands and "Upcases" an 8 character string}
  403. VAR I : Integer;
  404. Begin
  405.    For I:=1 to Length(Str_8) do Str_8[I]:=Upcase(Str_8[I]);
  406.    While Length(Str_8)<8 do Str_8:=Str_8+' ';
  407.    UpCase8:=Str_8;
  408. End;
  409.  
  410.  
  411. Function TimeStamp : Real;
  412. {Returns a timestamp of 6 bytes ordered, Year,Month,Day,Hour(24),Minute,
  413.  Second }
  414. VAR
  415.    TS : Array[1..6] of Byte;
  416.    TStmp : Real absolute TS;
  417.    Year,Month,Day,DOW,Hour,Minute,Sec,Hund : Word;
  418. Begin
  419.    GetTime(Hour,Minute,Sec,Hund);
  420.    GetDate(Year,Month,Day,DOW);
  421.    Year:=Year mod 100;
  422.    TS[1]:=Byte(Year);
  423.    TS[2]:=Byte(Month);
  424.    TS[3]:=Byte(Day);
  425.    TS[4]:=Byte(Hour);
  426.    TS[5]:=Byte(Minute);
  427.    TS[6]:=Byte(Sec);
  428.    TimeStamp:=TStmp;
  429. End;
  430.  
  431.  
  432. Function StampAge(StartTime : Real): LongInt;
  433. { Returns the difference in seconds between the currenttime and the
  434. "Starttime" timestamp.}
  435. VAR
  436.    TS1 : Array[1..6] of Byte absolute StartTime;
  437.    TStamp2 : Real;
  438.    TS2 : Array[1..6] of Byte absolute TStamp2;
  439.    IArray : Array[1..6] of Integer;
  440.    SA : Longint;
  441.    I : Integer;
  442.    Leaps : Integer;
  443.  
  444.  {==========}
  445.    procedure TDec(Pos : Integer);
  446.    begin
  447.       if Pos>0
  448.       then
  449.        begin
  450.           If (TS2[Pos]=SCMin[Pos])
  451.           then
  452.            begin
  453.               TDec(Pos-1);
  454.               If (Pos=3) then TS2[Pos]:=SCMon[TS2[2]]
  455.               else
  456.                begin
  457.                   If Pos>3 then TS2[Pos]:=SCLim[Pos]-1
  458.                   else TS2[Pos]:=SCLim[Pos];
  459.                end;
  460.            end
  461.           else
  462.           TS2[Pos]:=TS2[Pos]-1;
  463.        end;
  464.    end;
  465.  {==========}
  466.  
  467. Begin
  468.    FillChar(IArray,12,0);
  469.    TStamp2:=TimeStamp;
  470.    {Count leaps if necessary}
  471.    Leaps:=0;
  472.    If TS2[1]>(TS1[1]+1) then for I:=TS1[1]+1 to TS2[1]-1 do
  473.     if (I mod 4 = 0) then Leaps:=Leaps+1;
  474.    If TS2[1]=TS1[1]+1 then if (((TS1[1] mod 4 = 0) and (TS1[2]<=2)) or
  475.    ((TS2[1] mod 4 =0) and (TS2[2]>2))) then Leaps:=Leaps+1;
  476.    If (((TS1[1]=TS2[1]) and (TS1[1] mod 4 = 0)) and ((TS1[2]<=2)and (TS2[2]>2)))
  477.     then Leaps:=Leaps+1;
  478.    For I:=6 downto 1 do
  479.     begin
  480.        If (TS2[I]<TS1[I])
  481.        then
  482.         begin
  483.            TS2[I]:=TS2[I]+SCLim[I];
  484.            TDec(I-1);
  485.         end;
  486.        IArray[I]:=TS2[I]-TS1[I];
  487.     end;
  488.    IArray[3]:=IArray[3]+Leaps;
  489.    {Using leaps now to count days}
  490.    Leaps:=0;
  491.    I:=TS2[2];
  492.    While I<>TS1[2] do
  493.     begin
  494.        Leaps:=Leaps+SCMon[I];
  495.        I:=I+1;
  496.        If I>12 then I:=1;
  497.     end;
  498.    If IArray[1]>0 then Leaps:=Leaps+IArray[1]*365;
  499.    Leaps:=Leaps+IArray[3];
  500.    SA:=Leaps;
  501.    SA:=SA*24+IArray[4];
  502.    SA:=SA*60+IArray[5];
  503.    StampAge:=SA*60+IArray[6];
  504. End;
  505.  
  506.  
  507. Function Loaded : Boolean;
  508. { Is 10Net Loaded? }
  509. TYPE
  510.   LoadCheck = Array[1..4] of Char;
  511. VAR
  512.   LPtr : ^LoadCheck;
  513. Begin
  514.    With TenRegs do
  515.     begin
  516.        AX:=$356F;
  517.        MSDos(TenRegs);
  518.        LPtr:=Ptr(ES,BX-4);
  519.        If (LPtr^[4]+Lptr^[3]+LPtr^[2]+LPtr^[1]='1XOF')
  520.        then Loaded:=True
  521.        else Loaded:=False;
  522.     end;
  523.  end;
  524.  
  525. Function NODEName : S12;
  526. {Returns the current nodename }
  527. VAR
  528.  I : Integer;
  529.  NN : S12;
  530. Begin
  531.    NN:='';
  532.    If TNTI then for I:=1 to 12 do NN:=NN+ConfigTable^.CT_NID;
  533.    NodeName:=NN;
  534. End;
  535.  
  536.  
  537.  
  538. Function Chat(NodeID : S12; VAR DBuffer {:String[n]} ) : Word;
  539. { The DBuffer should be a Turbo Pascal String (length indicator in byte 0)
  540.   The string should be no more than 100 bytes long. This function sends a
  541.   10Net Chat message to the NodeID specified. }
  542. VAR
  543.    I : Integer;
  544.    LI : ^Byte;
  545.    PBuffer : ^ChatBytes;
  546. Begin
  547.    With TenRegs do if TNTI then
  548.     begin
  549.        For I:=1 to Length(NodeID) do LogData.NodeName[I]:=NodeID[I];
  550.        If (Length(NodeID)<12) then for I:=Length(NodeID)+1 to 12 do
  551.         LogData.NodeName[I]:=#32;
  552.        For I:=1 to 8 do LogData.Password[I]:=#32;
  553.        For I:=1 to 8 do LogData.UserName[I]:=ConfigTable^.CT_LName[I];
  554.        PBuffer:=@DBuffer;
  555.        LI:=@DBuffer;
  556.        ChatRec.MsgLength:=Integer(LI^)+2;
  557.        If ChatRec.MsgLength>102
  558.        then
  559.         begin
  560.            ChatRec.MsgLength:=102;
  561.            LI^:=100;
  562.         end;
  563. {@#@}       Move(PBuffer^[2],ChatRec.ChatText,ChatRec.MsgLength-1);
  564.        AX:=$0A00;
  565.        DS:=Seg(LogData);
  566.        BX:=Ofs(LogData);
  567.        DX:=Ofs(ChatRec);
  568.        Intr($6F,TenRegs);
  569.        If Not ((Flags and $01)=0)
  570.        then Chat:=AX
  571.        else Chat:=0;
  572.     end
  573.   else
  574.     begin
  575.        Writeln('TENTOOLS Not Initialized');
  576.        Halt;
  577.     end;
  578. end;
  579.  
  580. Function Status(NodeName : S15; VAR SBlock : StatusBlock): Word;
  581. { Returns a Block of Status information from the Nodename requested if
  582.   that node is on the network.}
  583. TYPE
  584.    A20 = Array[1..23] of Char;
  585. VAR
  586.    SBP : ^A20;
  587.    I : Integer;
  588. Begin
  589.    If TNTI then with TenRegs do
  590.     begin
  591.        NodeName:=Upcase12(NodeName);
  592.        FillChar(SBlock,Sizeof(StatusBlock),0);
  593.        While Length(NodeName)<15 do NodeName:=NodeName+' ';
  594.        Move(NodeName[1],SBlock,15);
  595.        SBP:=@SBlock;
  596.        Move(ConfigTable^.CT_LName,SBP^[16],8);
  597.        AX:=$0200;
  598.        DS:=Seg(SBlock);
  599.        DX:=Ofs(SBlock);
  600.        Intr($6F,TenRegs);
  601.        If Not ((Flags and $01)=0)
  602.        then Status:=AX
  603.        else Status:=0;
  604.     end
  605.    else
  606.     begin
  607.        Writeln('TENTOOLS Not Initialized');
  608.        Halt;
  609.     end;
  610. end;
  611. Function Get10Time(NodeName : S15 ;VAR TenTime : DateTimeRec) : Word;
  612. {Returns the Date and Time in a DateTimeRec Record from the Node Requested.}
  613.  
  614. VAR
  615.    TempStatus : ^StatusBlock;
  616. Begin
  617.    GetMem(TempStatus,512);
  618.    TenTest:=Status(NodeName,TempStatus^);
  619.    If (TenTest=0)
  620.    then with TempStatus^ do
  621.     begin
  622.        with TenTime do
  623.         begin
  624.            Year:=S_Date[3]+1980;
  625.            Month:=S_Date[2];
  626.            Day:=S_Date[1];
  627.            Hour:=S_Time[3];
  628.            Minute:=S_Time[2];
  629.            Second:=S_Time[1];
  630.            Get10Time:=0;
  631.         end;
  632.     end
  633.    else Get10Time:=TenTest;
  634.    FreeMem(TempStatus,512);
  635. End;
  636.  
  637. Function Login(ServerID : S12;PW10Net : S8): Word;
  638. { Logs into the requested server. }
  639. VAR
  640.   I : Integer;
  641. Begin
  642.    With TenRegs do if TNTI then
  643.     begin
  644.        Move(ConfigTable^.CT_LName,LogData.UserName,8);
  645.        PW10Net:=Upcase8(PW10Net);
  646.        For I:=1 to 8 do LogData.Password[I]:=PW10Net[I];
  647.        ServerID:=Upcase12(ServerID);
  648.        Move(ServerID[1],LogData.NodeName,12);
  649. {       Writeln(LogData.UserName,'<');
  650.        Writeln(LogData.PassWord,'<');
  651.        Writeln(LogData.NodeName,'<');
  652. }      AX:=$0000;
  653.        DS:=Seg(LogData);
  654.        DX:=Ofs(LogData);
  655.        Intr($6F,TenRegs);
  656.        If Not ((Flags and $01)=0)
  657.        then Login:=AX
  658.        else Login:=0;
  659. (*       Case AX of
  660.             $0000 : Write('Good Login');
  661.             $01FF : Write('No response from Superstation');
  662.             $02FF : Write('Network Error');
  663.             $03FF : Write('Invalid password');
  664.             $04FF : Write('No Local Buffer available');
  665.             $05FF : Write('Superstation device is not available');
  666.             $06FF : Write('Node Already logged in under different name.');
  667.             $07FF : Write('Login not valid from this node ID.');
  668.             $09FF : Write('Node is not a superstation');
  669.             $0AFF : Write('Node-ID already in use by another station!');
  670.             else Write('ErrorCode ',AX);
  671.            end; {Case}
  672.  *)
  673.     end
  674.   else
  675.    begin
  676.       Writeln('TENTOOLS Not Initialized');
  677.       Halt;
  678.    end;
  679. end;
  680.  
  681. Function Logoff(ServerID : S12): Word;
  682. { Logs off the requested server. }
  683. Begin
  684.    While Length(ServerID)<12 do ServerID:=ServerID+' ';
  685.    With TenRegs do if Loaded then
  686.     begin
  687.        AX:=$0100;
  688.        DS:=Seg(ServerID);
  689.        DX:=Ofs(ServerID)+1;
  690.        Intr($6F,TenRegs);
  691.        If Not ((Flags and $01)=0)
  692.        then Logoff:=AX
  693.        else Logoff:=0;
  694.     end
  695.    else Logoff:=$FFFF;
  696. End;
  697.  
  698. Function Mount(ServerID : S12; LocalDevice,RemoteDevice : Char) : Word;
  699. { For Drive mounting, mounts drive REMOTEDRIVE at SERVERID as LOCALDRIVE
  700.  locally; for printer mounting, use "1" for LPT1, etc. }
  701. VAR
  702.  LDrive : Integer;
  703. Begin
  704.    With TenRegs do if Loaded then
  705.     begin
  706.        If LocalDevice in ['A'..'Z'] then LDrive:=Ord(LocalDevice)-65
  707.        else if LocalDevice in ['1'..'3'] then LDrive:=Ord(LocalDevice)-49;
  708.        While Length(ServerID)<12 do ServerID:=ServerID+' ';
  709.        AX:=$1700+LDrive;
  710.        DX:=Ofs(ServerID)+1;
  711.        DS:=Seg(ServerID);
  712.        BL:=Ord(RemoteDevice);
  713.        Intr($6F,TenRegs);
  714.        If ((Flags AND 1)<>0)
  715.        then
  716.         begin
  717.            Mount:=AX;
  718. {           TextColor(White+Blink);
  719.            Writeln('Error: ',AX);}
  720.         end
  721.        else Mount:=0;
  722.     end
  723.    else Mount:=$FFFF;
  724. end;
  725.  
  726.  
  727. Function UnMount(LocalDrive : Char) : Word;
  728. { Unmounts previously mounted drive or printer }
  729. VAR
  730.  LDrive : Integer;
  731.  LPrint : Integer absolute LDrive;
  732. Begin
  733.    If Loaded then
  734.    With TenRegs do
  735.     begin
  736.        If (LocalDrive in ['A'..'Z'])
  737.        then
  738.         begin
  739.            LDrive:=Ord(LocalDrive)-65;
  740.            AX:=$1800+LDrive;
  741.            BL:=0;
  742.         end
  743.        else if (LocalDrive in ['1'..'3'])
  744.        then
  745.         begin
  746.            LPrint:=Ord(LocalDrive)-49;
  747.            AX:=$1800+LPrint;
  748.            BL:=1;
  749.         end;
  750.        Intr($6F,TenRegs);
  751.        If ((Flags AND 1)<>0)
  752.        then UnMount:=AX
  753.        else UnMount:=0;
  754.     end
  755.    else UnMount:=$FFFF;
  756. end;
  757.  
  758. Function NetUse(ServerID : S12; LocalDrive : Char; RemoteDevice : String;NetUsePassWord : S8) : Word;
  759. { Attaches to a Device at a Remote Server. The RemoteDevice can be an ALIAS }
  760. VAR
  761.    I : Integer;
  762.    DriveString : S8;
  763.    SERVERZ : S12;
  764.    RemoteString : String;
  765. Begin
  766.    If Loaded
  767.    then with TenRegs do
  768.     begin
  769.        SERVERZ:=ServerID;
  770.        For I:=1 to Length(SERVERZ) do SERVERZ[I]:=Upcase(SERVERZ[I]);
  771.        While ServerZ[Length(ServerZ)]=' ' do Dec(ServerZ[0]);
  772.        For I:=1 to Length(NetUsePassword) do NetUsePassword[I]:=Upcase(NetUsePassword[I]);
  773.        BL:=4;
  774.        CX:=0;
  775.        DriveString:=Upcase(LocalDrive)+':'+#0;
  776.        DS:=Seg(DriveString);
  777.        SI:=Ofs(DriveString)+1;
  778.        For I:=1 to Length(RemoteDevice) do RemoteDevice[I]:=Upcase(RemoteDevice[I]);
  779.        RemoteString:='\\'+SERVERZ+'\'+RemoteDevice+#0+NetUsePassWord;
  780.        While RemoteString[Length(RemoteString)]=' ' do Dec(RemoteString[0]);
  781.        RemoteString:=RemoteString+#0;
  782.        ES:=Seg(RemoteString);
  783.        DI:=Ofs(RemoteString)+1;
  784.        AX:=$5F03;  {uses the Dos function call "Redirect Device"}
  785.        MSDOS(TenRegs);
  786.        If ((Flags AND 1)<>0)
  787.        then
  788.         NetUse:=AX
  789.        else
  790.         NetUse:=0;
  791.     end
  792.    else NetUse:=$FFFF;
  793. End;
  794.  
  795.  
  796. Function UnUse(LocalDrive : Char) : Word;
  797. { Detaches from a shared device at a remote server. The attachment was made
  798. through a Net Use (or NetUse), and the local drive letter is all that is
  799. needed to detach}
  800. VAR
  801.    DriveString : S8;
  802.  
  803. Begin
  804.    If Loaded
  805.    then with TenRegs do
  806.     begin
  807.        DriveString:=Upcase(LocalDrive)+':'+#0;
  808.        DS:=Seg(DriveString);
  809.        SI:=Ofs(DriveString)+1;
  810.        AX:=$5F04;
  811.        MSDos(TenRegs);
  812.        If ((Flags AND 1)<>0)
  813.        then
  814.         UnUse:=AX
  815.        else
  816.         UnUse:=0;
  817.     end
  818.    else UnUse:=$FFFF;
  819. End;
  820.  
  821.  
  822. Function Send(NodeID : S12; VAR DBuffer; DLength :Integer): Word;
  823. {Send a data packet on the network to NODEID ( or on a CB Channel if
  824. NODEID is CB##, limited to 470 byte packets. Used within the Toolbox to
  825. accomplish TBSend, which allows large records to be sent.}
  826.  
  827. VAR
  828.  I,SR : Integer;
  829.  CBL : String[2];
  830. Begin
  831.    If DLength<=470
  832.    then
  833.     begin
  834.       NodeID:=Upcase12(NodeId);
  835.       Move(NodeID[1],SendSet.RNode,12);
  836.       SendSet.DataBytes:=DLength;
  837.       Move(DBuffer,SendBuffer,DLength);
  838.       If ((NodeID[1]='C') and (NodeID[2]='B'))
  839.       then
  840.        begin
  841.           CBL:=Copy(NodeID,3,2);
  842.           If CBL[2]=' ' then CBL[0]:=#1;
  843.           VAL(CBL,I,SR);
  844.           If SR=0
  845.           then
  846.            begin
  847.               SendSet.RNode[2]:=#0;
  848.               SendSet.RNode[1]:=Char(I);
  849.            end;
  850.        end;
  851.       With TenRegs do
  852.        begin
  853.           DS:=Seg(SendSet);
  854.           BX:=Ofs(SendSet);
  855.           DX:=Ofs(SendBuffer);
  856.           AX:=$0400;
  857.           Intr($6F,TenRegs);
  858.           If Flags and 1 <> 0 then
  859.           Send:=AX
  860.           else Send:=0;
  861.        end;
  862.     end
  863.    else Send:=$FFFF;
  864. End;
  865.  
  866. Function Receive(VAR DBuffer; Secs : Word; VAR Available : Integer; VAR CBMessage : Boolean): Word;
  867. {Receive a data packet on the network in the structure below:
  868.          data           bytes
  869.          =====================
  870.          SenderNodeID : 12
  871.          Len          : 2
  872.          Data         : (Len)
  873.   Available is set to the number of packets available INCLUDING the
  874.   current message. Receives data sent through the SEND function, which is
  875.   limited to data structures of length 470 or less. TBSend and TBReceive
  876.   (which use Send and Receive) can be used for larger structures.
  877. }
  878. VAR
  879.  TestString : ^String80;
  880. Begin
  881.    TestString:=@DBuffer;
  882.    CBMessage:=False;
  883.    With TenRegs do
  884.     begin
  885.        DX:=Ofs(DBuffer);
  886.        DS:=Seg(DBuffer);
  887.        CX:=Secs;
  888.        AX:=$0500;
  889.        Intr($6F,TenRegs);
  890.        If (Flags and 1 <> 0) then
  891.        Receive:=AX
  892.        else
  893.         begin
  894.            Receive:=0;
  895.            If AL=$FE then CBMessage:=True;
  896.            Available:=ConfigTable^.CT_CBCNT+1;
  897.         end;
  898.     end;
  899. End;
  900.  
  901.  
  902.  
  903.  
  904. Function GetRemoteMemory(NodeID : S12; VAR DBuffer; VAR DLength : Integer; RemSeg,RemOfs : Word) : Word;
  905. {Copy a section of memory from a remote node to DBuffer (maximum of 470 bytes) }
  906. VAR
  907.  I : Integer;
  908.  
  909. Begin
  910.    With TenRegs do
  911.     begin
  912.        AX:=$1400;
  913.        BX:=RemSeg;
  914.        CX:=DLength;
  915.        SI:=RemOfs;
  916.        DS:=Seg(DBuffer);
  917.        DX:=Ofs(NodeID)+1;
  918.        NodeID:=Upcase12(NodeID);
  919.        DI:=Ofs(DBuffer);
  920.        Intr($6F,TenRegs);
  921.        If (Flags and 1)>0
  922.        then GetRemoteMemory:=AX
  923.        else
  924.         begin
  925.            DLength:=CX;
  926.            GetRemoteMemory:=0;
  927.         end;
  928.     end;
  929. End;
  930.  
  931. Procedure SetCBChannel(CBChannel : Byte);
  932. {      This procedure will set your "Listening" Channel to the CBCHANNEL (1
  933.  through 40 are available) specified. TBSends to this CBChannel from other
  934.  nodes will be available here through TBReceive. TBSends to other CBChannels
  935.  will not be seen here. TBSends directed specifically to this node will also
  936.  be seen here, of course.
  937.        The advantages of CB messaging are that many nodes can be setup to
  938.  receive messages on a particular channel, and the sender will not be held
  939.  up waiting for a network handshake to tell him that his Send was Received.
  940. }
  941. Begin
  942.    If TNTI
  943.    then
  944.     begin
  945.        ConfigTable^.CT_CB:=CBChannel;
  946.     end;
  947. End;
  948.  
  949. Function TBSend(NodeID : S12;            {Node to send to                 }
  950.            VAR DBuffer;                   {The data record                 }
  951.                 DLength : Integer;        {Length (bytes) of data          }
  952.           TransactionID : TID;            {Tag to identify record (4 bytes)}
  953.               TransType : Integer;        {Transaction Type - (external to
  954.                                           this toolbox) an integer type used
  955.                                           to maintain that one is receiving
  956.                                           only the correct type of records.}
  957.            ResponseType : Byte            {Not implemented}
  958.  
  959.  
  960.               ) : Word;
  961. { TBSend will send a large interapplication message (DBuffer) of length
  962. DLENGTH across the network. The TransactionID is user defineable and can be
  963. used to acknowledge the receipt or processing of a record to the originator.
  964. TransType, optional, can be used to identify the type of processing required
  965. of a record. The data in DBuffer can be of any structure.
  966.      The message is effectively broken into packets, and sent with a
  967. "packet marker" to assist in its reconstruction when received. Unique
  968. Transaction IDs is essential for records larger than 457 bytes to maintain
  969. unique record identity. Packet Data consists of a PRec (see data Type
  970. definitions) and 457 bytes of the DataRec.
  971.      The network provides handshaking with Sends and Receives if they are
  972. directed to a particular node. If CB# is used instead, there is no
  973. handshaking provided. If a node is specified, and it is not currently
  974. available or its 10Net SBuffers buffering is full, the sending node will
  975. be stuck waiting for a timeout or until the receiver or buffer space appears.
  976. For this reason, in some applications which can't be held up waiting, it is
  977. wise to use CB channel communication. (See the "SetCBChannel" function for a
  978. discussion of its usage.)
  979.  
  980. }
  981. VAR
  982. RetCode : Word;
  983. PBuffer : ^MaxBytes;
  984. ILength : Integer;
  985. Begin
  986.    If TNTI
  987.    then
  988.     begin
  989.        If DLength<MaxSendBufferSize
  990.        then
  991.         begin
  992.            NodeID:=Upcase12(NodeID);
  993.            With PacketRec do
  994.             begin
  995.                PBuffer:=@DBuffer;
  996.                TransID:=TransactionID;
  997.                TPackets:=DLength div 457;
  998.                If (DLength mod 457>0) then TPackets:=TPackets+1;
  999.                TType:=TransType;
  1000.                TLength:=DLength;
  1001.                RespType:=ResponseType;
  1002.                For Packet:=1 to TPackets do
  1003.                 begin
  1004.                    If Packet=TPackets then ILength:=DLength mod 457
  1005.                    else ILength:=457;
  1006.                    Move(PacketRec,SendBuffer,13);
  1007.                    Move(PBuffer^[(Packet-1)*457+1],SendBuffer[14],ILength);
  1008.                    RetCode:=Send(NodeID,SendBuffer,ILength+13);
  1009.                    If RetCode<>0
  1010.                    then Packet:=TPackets;
  1011.                 end;
  1012.                If RetCode<>0 then TBSend:=RetCode else TBSend:=0;
  1013.             end;
  1014.         end
  1015.        else
  1016.         begin
  1017.            Writeln('');
  1018.            Writeln('Record Size too large for TenTools Configuration.');
  1019.            Writeln('MaxSendBufferSize=',MaxSendBufferSize);
  1020.            Writeln('Record not Sent!');
  1021.            Delay(1000);
  1022.         end;
  1023.      end
  1024.     else
  1025.      begin
  1026.         Writeln('TENTOOLS Not Initialized');
  1027.         Halt;
  1028.      end;
  1029. End;
  1030.  
  1031. Function TBReceive( VAR SenderID: S12;      {Sending NodeID : String12       }
  1032.                     VAR DBuffer;           {Variable (record) to receive    }
  1033.                     VAR DLength : Integer; {Maximum length record to receive}
  1034.               VAR TransactionID : TID;     {See description of TBSend       }
  1035.                   VAR TransType : Integer; {See description of TBSend       }
  1036.                   VAR Available : Integer; {Number of records available
  1037.                                             including the one passed back   }
  1038.                          VAR CB : Boolean) {Was this a CB transmission?     }
  1039.                          : Word;  {Return code indicates a 10Net error($XXFF)
  1040.                                    or an error in a passed parameter ($FFXX)}
  1041. VAR
  1042.    LLRs,LLRet,I : Integer;
  1043.    SenderNode : SID absolute ReceiveBuffer;
  1044.    RLength : ^Integer;
  1045.    RPack : ^PRec;
  1046.    RcvData : ^Byte;
  1047.    CBM : Boolean;
  1048. Begin
  1049.    If TNTI
  1050.    then
  1051.     begin
  1052.       RLength:=@ReceiveBuffer[13];
  1053.       RPack:=@ReceiveBuffer[15];
  1054.       RcvData:=@ReceiveBuffer[15+Sizeof(RPack^)];
  1055.       Repeat {process 10net receives}
  1056.          LLRet:=Receive(ReceiveBuffer,0,LLRs,CBM);
  1057.          If LLRet=0
  1058.          then
  1059.           begin
  1060.              CPointer:=TPointer;
  1061.              If RPack^.Packet=1
  1062.              then CPointer:=HPointer
  1063.              else while ((TBR^[CPointer].TransID <> RPack^.TransID)
  1064.              and (CPointer<>HPointer)) do
  1065.               begin
  1066.                  CPointer:=CPointer+1;
  1067.                  If CPointer>MaxReceives then CPointer:=1;
  1068.               end;
  1069.              If CPointer=HPointer
  1070.              then
  1071.               begin
  1072.                  {beginning a new record}
  1073.                  HPointer:=HPointer+1;
  1074.                  If HPointer>MaxReceives then HPointer:=1;
  1075.                  If TPointer=HPointer
  1076.                  then
  1077.                   begin
  1078.                      TPointer:=TPointer+1;
  1079.                      If TPointer>MaxReceives then TPointer:=1;
  1080.                   end;
  1081.                  TBR^[CPointer].Sender:='';
  1082.                  For I:=1 to 12 do
  1083.                  TBR^[CPointer].Sender:=TBR^[CPointer].Sender+SenderNode[I];
  1084.                  TBR^[CPointer].TransID:=RPack^.TransID;
  1085.                  TBR^[CPointer].TType:=RPack^.TType;
  1086.                  TBR^[CPointer].RTime:=TimeStamp;
  1087.                  TBR^[CPointer].TrackRecv:=[];
  1088.                  For I:=1 to RPack^.TPackets do
  1089.                  TBR^[CPointer].TrackRecv:=TBR^[CPointer].TrackRecv+[I];
  1090.                  TBR^[CPointer].Resptype:=RPack^.RespType;
  1091.                  TBR^[CPointer].TLength:=RPack^.TLength;
  1092.                  TBR^[CPointer].CB:=CBM;
  1093.               end;
  1094.              Move(RcvData^,TBD^[CPointer]^[RPack^.Packet],RLength^-Sizeof(RPack^));
  1095.              TBR^[CPointer].TrackRecv:=TBR^[CPointer].TrackRecv-[RPack^.Packet];
  1096.           end;
  1097.       Until LLRet<>0;
  1098.       {Count number of records ready, keeping track of the first.}
  1099.       Available:=0;
  1100.       CPointer:=TPointer;
  1101.       While CPointer<>HPointer do
  1102.        begin
  1103.           If TBR^[CPointer].TrackRecv=[]
  1104.           then
  1105.            begin
  1106.               Available:=Available+1;
  1107.               If Available=1
  1108.               then
  1109.                begin
  1110.                   SenderID:=TBR^[CPointer].Sender;
  1111.                   DLength:=TBR^[CPointer].TLength;
  1112.                   If TBR^[CPointer].TLength>MaxRecBufferSize
  1113.                   then DLength:=MaxRecBufferSize;
  1114.                   TransactionID:=TBR^[CPointer].TransID;
  1115.                   TransType:=TBR^[CPointer].TType;
  1116.                   CB:=TBR^[CPointer].CB;
  1117.                   Move(TBD^[CPointer]^,DBuffer,DLength);
  1118.                   If CPointer<>TPointer
  1119.                   then Move(TBR^[TPointer],TBR^[CPointer],Sizeof(TBR^[1]));
  1120.                   TPointer:=TPointer+1;
  1121.                   If TPointer>MaxReceives then TPointer:=1;
  1122.                end;
  1123.            end
  1124.           else if ((CPointer=TPointer) and (StampAge(TBR^[CPointer].RTime)>MAXRCVWAIT))
  1125.           then
  1126.            begin
  1127.               TPointer:=TPointer+1;
  1128.               If TPointer>MaxReceives then TPointer:=1;
  1129.            end;
  1130.           CPointer:=CPointer+1;
  1131.           If CPointer>MaxReceives then CPointer:=1;
  1132.        End;
  1133.       If Available>0 then TBReceive:=0
  1134.       else if LLRet<>$01FF then TBReceive:=LLRet
  1135.       else TBReceive:=0;
  1136.    end
  1137.   else
  1138.    begin
  1139.       Writeln('TENTOOLS Not Initialized');
  1140.       Halt;
  1141.    end;
  1142. End;
  1143.  
  1144. Function Nodes(VAR NodeBuffer;VAR MaxNodes : Integer;
  1145.                   SuperstationsOnly : Boolean) : Word;
  1146. { A call to this function should be made with NODEBUFFER being an
  1147.  Array[1..MaxNodes] of S12. MaxNodes being the largest number of nodes you
  1148.  expect to see on the network. If the Returncode of NODES is 0, MaxNodes will
  1149.  have the actual number of nodenames returned and the array will be filled
  1150.  with their names. SuperstationsOnly is a boolean which allows nodes to be
  1151.  called to list only superstations. }
  1152.  
  1153. VAR
  1154.    LIAV : LongInt;
  1155.    Av : Word;
  1156.    I,J,K,MaxRecs : Integer;
  1157.    Adjust : S12;
  1158. Begin
  1159.    If MaxNodes>1024 then MaxNodes:=0;
  1160.    If (TNTI and (MaxNodes>0))
  1161.    then with TenRegs do
  1162.     begin
  1163.        LIAV:=MaxAvail;
  1164.        If (LIAV>=$FFFF)
  1165.        then AV:=$FFFF
  1166.        else AV:=LIAV;
  1167.        MaxRecs:=Av div 24;
  1168.        If MaxNodes<MaxRecs
  1169.        then
  1170.         begin
  1171.            MaxRecs:=MaxNodes;
  1172.            AV:=MaxRecs*24;
  1173.         end;
  1174.        GetMem(NodeArray,AV);
  1175.        AX:=$0D02;
  1176.        If SuperstationsOnly then AX:=$0D01;
  1177.        CX:=AV;
  1178.        DS:=Seg(NodeArray^);
  1179.        DX:=Ofs(NodeArray^);
  1180.        Intr($6F,TenRegs);
  1181.        NAArray:=@NodeBuffer;
  1182.        NWArray:=@NodeArray^;
  1183.        MaxNodes:=CX;
  1184.        K:=1;
  1185.        For J:=1 to MaxNodes do
  1186.         begin
  1187.            Adjust:='            ';
  1188.            for I:=1 to 12 do Case SuperStationsOnly of
  1189.            False : Adjust[I]:=NodeArray^[J].NID[I];
  1190.            True : Adjust[I]:=NWArray^[J].NID[I];
  1191.            end;
  1192.            If SuperStationsOnly
  1193.            then
  1194.             begin
  1195.                if (NWArray^[J].Ver[1]and 1=0)
  1196.                then
  1197.                 begin
  1198.                    NAArray^[K]:=Adjust;
  1199.                    Inc(K);
  1200.                 end
  1201.             end
  1202.            else NAArray^[J]:=Adjust;
  1203.         end;
  1204.        If (Flags and 1)>0
  1205.        then Nodes:=AX
  1206.        else Nodes:=0;
  1207.        If SuperStationsOnly then MaxNodes:=K-1;
  1208.        FreeMem(NodeArray,AV);
  1209.     end
  1210.     else if (MaxNodes<=0) then Nodes:=$FFFF;
  1211. End;
  1212.  
  1213. Function GetDevices(ServerID : S12;
  1214.              VAR Device : DeviceArray;
  1215.              VAR DeviceCount : Integer): Word;
  1216. { Returns a list of devices through the Variable parameter Devices (which is
  1217.   defined as Array[1..25] of S8). Uses the Get/Set/Delete/Get User Shared
  1218.   Device (Int-$6F,Service-$15) function call.
  1219.   }
  1220. VAR
  1221.    DCount : Integer;
  1222.    DeviceTable : SDev;
  1223.    SERVERZ : S12;
  1224.    I : Integer;
  1225. Begin
  1226.    FillChar(Device,Sizeof(Device),0);  {initialize to all nullstrings}
  1227.    If Loaded
  1228.    then with TenRegs do
  1229.     begin
  1230.        SERVERZ:=Upcase12(ServerID);
  1231.        DCount:=0;
  1232.        Repeat
  1233.           AX:=$1501;
  1234.           BX:=DCount;
  1235.           DS:=Seg(ServerZ);
  1236.           SI:=Ofs(ServerZ)+1;
  1237.           ES:=Seg(DeviceTable);
  1238.           DI:=Ofs(DeviceTable);
  1239.           Intr($6F,TenRegs);
  1240.           If not ((Flags and 1)>0)
  1241.           then
  1242.            begin
  1243.               Device[DCount]:=DeviceTable.Alias;
  1244.               Inc(DCount);
  1245.            end
  1246.           else GetDevices:=AX;
  1247.        Until ((Flags and 1)>0);
  1248.        DeviceCount:=DCount;
  1249.        If DeviceCount=0 then GetDevices:=AX else GetDevices:=0;
  1250.     end
  1251.    else GetDevices:=$FFFF;
  1252. End;
  1253.  
  1254. Function GetTableData(VAR TableBuffer : GetTableDataRec): Word;
  1255. VAR
  1256.  I : Integer;
  1257. Begin
  1258.    If Loaded then
  1259.    With TenRegs do
  1260.     begin
  1261.        For I:=1 to 12 do TableBuffer.NodeID[I]:=ConfigTable^.CT_NID[I];
  1262.        TableBuffer.Res1:=0;
  1263.        AX:=$1D00;
  1264.        DS:=Seg(TableBuffer);
  1265.        DX:=Ofs(TableBuffer);
  1266.        Intr($6F,TenRegs);
  1267.        If not ((Flags and 1)>0)
  1268.         then GetTableData:=0
  1269.         else GetTableData:=AX;
  1270.     end
  1271.    else GetTableData:=$FFFF;
  1272. End;
  1273.  
  1274. Function MountsAvail : Integer;
  1275.  VAR
  1276.     TempTable : ^GetTableDataRec;
  1277. Begin
  1278.    GetMem(TempTable,Sizeof(GetTableDataRec));
  1279.    If (GetTableData(TempTable^)=0) then
  1280.    MountsAvail:=TempTable^.TenNetTables[1].Free+TempTable^.TenNetTables[1].Alloc
  1281.    else MountsAvail:=0;
  1282.    FreeMem(TempTable,Sizeof(GetTableDataRec));
  1283. End;
  1284.  
  1285.  
  1286. Function MountList(VAR MountTable : DriveArray;VAR PrintTable : PrintArray;VAR TableEntries : Integer): Word;
  1287. {Returns a mountlist of type DriveTable (with TableEntries as a count of
  1288. actual table entries returned), and PrintTable of Printer reassignments.
  1289. The caller must specify a maximum tablesize by setting table entries before
  1290. calling. Returns with a value of 0 if it worked without any hitches, and the
  1291. value of a 10net error if there is any problem. Will return with a value of
  1292. $FFFF if not loaded. Will return names of Devices if any are currently
  1293. "NetUsed".}
  1294. VAR
  1295.   I,IB,IM : Integer;
  1296.   SA : Word;
  1297.   SR : SearchRec;
  1298.   MChar : Char;
  1299.   Highest : Integer;
  1300.   LD : ^Byte;
  1301.   HighestLocal : Integer;
  1302.   LDevBuffer : Array[1..128] of Char;
  1303.   RDevBuffer : Array[1..128] of Char;
  1304. Begin
  1305.    If TableEntries<0 then TableEntries:=26;
  1306.    Highest:=0;
  1307.    If not Loaded
  1308.    then MountList:=$FFFF
  1309.    else with TenRegs do
  1310.     begin
  1311.        HighestLocal:=ConfigTable^.CT_PHYSDRVS;
  1312.        MountList:=0;
  1313.        Highest:=MountsAvail;
  1314.        If TableEntries>Highest then TableEntries:=Highest;
  1315.        For MChar:='A' to Char(TableEntries+64) do with MountTable[MChar] do
  1316.         begin
  1317.            If Ord(MChar)-64<=HighestLocal then ServerID:='Local       '
  1318.            else ServerID:='            ';
  1319.            RPath:=MChar;
  1320.         end;
  1321.        For MChar:='1' to '3' do with PrintTable[MChar] do
  1322.         begin
  1323.            ServerID:='            ';
  1324.            RPath:='';
  1325.         end;
  1326.        IB:=0;
  1327.        Flags:=0;
  1328.        while not ((Flags and 1)>0) do
  1329.         begin
  1330.            AX:=$1C00;
  1331.            BX:=IB;
  1332.            DS:=Seg(SendSet);
  1333.            DI:=Ofs(SendSet);
  1334.            Intr($6F,TenRegs);
  1335.            If not ((Flags and 1)>0)
  1336.            then
  1337.             begin
  1338.                IM:=0;
  1339.                While not ((Flags and 1)>0) do
  1340.                 begin
  1341.                    AX:=$1B00;
  1342.                    BX:=IM;
  1343.                    DS:=Seg(SendSet);
  1344.                    DX:=Ofs(SendSet);
  1345.                    Intr($6F,TenRegs);
  1346.                    If not ((Flags and 1)>0)
  1347.                    then
  1348.                     begin
  1349.                        If (AH in [65..90])
  1350.                        then
  1351.                         begin
  1352.                            MChar:=Char(AH);
  1353.                            If AH<=(TableEntries+64)
  1354.                            then
  1355.                             begin
  1356.                                MountTable[MChar].ServerID[0]:=#12;
  1357.                                Move(SendSet.RNode,MountTable[MChar].ServerID[1],12);
  1358.                                MountTable[MChar].RPath:=Char(AL);
  1359.                             end;
  1360.                         end
  1361.                        else if (AH in [49..51])
  1362.                        then
  1363.                         begin
  1364.                            MChar:=Char(AH);
  1365.                            PrintTable[MChar].ServerID[0]:=#12;
  1366.                            Move(SendSet.RNode,PrintTable[MChar].ServerID[1],12);
  1367.                            PrintTable[MChar].RPath:=Char(AL);
  1368.                         end;
  1369.                     end
  1370.                    else if not (AX=$25FF)
  1371.                    then
  1372.                     begin
  1373.                        MountList:=AX;
  1374.                        TableEntries:=Highest;
  1375.                        Exit;
  1376.                     end;
  1377.                    Inc(IM);
  1378.                 end;
  1379.               Flags:=0;
  1380.             end
  1381.            else if not (AX=$08FF) then MountList:=AX;
  1382.            Inc(IB);
  1383.         end;
  1384.        IB:=0;
  1385.         Repeat
  1386.            AX:=$5F02;
  1387.            BX:=IB;
  1388.            DS:=Seg(LDevBuffer);
  1389.            SI:=Ofs(LDevBuffer);
  1390.            ES:=Seg(RDevBuffer);
  1391.            DI:=Ofs(RDevBuffer);
  1392.            MSDOS(TenRegs);
  1393.            If not ((Flags and 1)>0)
  1394.            then with MountTable[LDevBuffer[1]] do
  1395.             begin
  1396.                I:=3;
  1397.                RPath:='';
  1398.                ServerID:='';
  1399.                While not (RDevBuffer[I]='\') do
  1400.                 begin
  1401.                    ServerID:=ServerID+RDevBuffer[I];
  1402.                    Inc(I);
  1403.                 end;
  1404.                Inc(I);
  1405.                While not(RDevBuffer[I]=#0) do
  1406.                 begin
  1407.                    RPath:=RPath+RDevBuffer[I];
  1408.                    Inc(I);
  1409.                 end;
  1410.             end;
  1411.            Inc(IB);
  1412.         Until ((Flags and 1)>0);
  1413.     end;
  1414. End;
  1415.  
  1416. Function LogList(VAR Logins : LogArray;VAR TableEntries : Integer): Word;
  1417. {Returns a list of nodes that the local station is logged into. LogArray
  1418.  is a TYPE defined as Array[0..19] of String[12] and can be used in the
  1419.  calling program. }
  1420. VAR
  1421.   IB : Integer;
  1422.  
  1423. Begin
  1424.    If not Loaded
  1425.    then LogList:=$FFFF
  1426.    else with TenRegs do
  1427.     begin
  1428.        IB:=0;
  1429.        Flags:=0;
  1430.        while not ((Flags and 1)>0) do
  1431.         begin
  1432.            AX:=$1C00;
  1433.            BX:=IB;
  1434.            DS:=Seg(Sendset);
  1435.            DI:=Ofs(SendSet);
  1436.            Intr($6F,TenRegs);
  1437.            If not ((Flags and 1)>0)
  1438.            then
  1439.             begin
  1440.                Logins[IB][0]:=#12;
  1441.                Move(SendSet.RNode,Logins[IB][1],12);
  1442.                Inc(IB);
  1443.             end;
  1444.            LogList:=0;
  1445.         end;
  1446.        TableEntries:=IB;
  1447.     end;
  1448. End;
  1449.  
  1450. Function Submit(ServerID : S12; CommandLine : String): Word;
  1451. { If the local User is LOGGED INTO the node SERVERID, and the submit permit
  1452.  is ON at ServerID, and ServerID is currently at a DOS prompt, then the
  1453.  Commandline will be SUBMITTED to ServerID. If it is not currently at a DOS
  1454.  prompt, it will be SUBMITTED when it reaches a DOS prompt. }
  1455.  
  1456. TYPE
  1457.    SubmitRec = Record
  1458.       Nodeid : Array[1..12] of Char;
  1459.       CLen   : Integer;
  1460.       CLine : Array[1..100] of Char;
  1461.    end;
  1462. VAR
  1463.    ServerZ : S12;
  1464.    I : Integer;
  1465.    SRec : SubmitRec;
  1466. Begin
  1467.    If Loaded
  1468.    then with TenRegs do
  1469.     begin
  1470.        SERVERZ:=Upcase12(ServerID);
  1471.        Move(ServerZ[1],SRec.Nodeid,12);
  1472.        If Pos(#13,Commandline)>0 then SRec.CLen:=Pos(#13,Commandline)-1
  1473.        else SRec.CLen:=Length(Commandline);
  1474.        CommandLine:=CommandLine+#13+#10;
  1475.        Inc(SRec.CLen,2);
  1476.        Move(Commandline[1],SRec.CLine,SRec.CLen);
  1477.        AX:=$0900;
  1478.        DS:=Seg(SRec);
  1479.        BX:=Ofs(SRec);
  1480.        Intr($6F,TenRegs);
  1481.        If ((Flags and 1)>0)
  1482.        then
  1483.         begin
  1484.            Submit:=AX;
  1485.         end
  1486.        else Submit:=0;
  1487.     end
  1488.    else Submit:=$FFFF;
  1489. End;
  1490.  
  1491. Function SetSpool(Printer : Byte; SpoolName : S12; Notification : NotifySet; RDays : Byte): Word;
  1492. { When SetSpool is first called, it merely sets up a "Template" for
  1493.   subsequent calls to OpenSpool and CloseSpool. You must be logged into the
  1494.   Superstation where you want to spool and be mounted to a printer and a
  1495.   drive on that Superstation. SetSpool will determine where the Printer
  1496.   (1,2, or 3 for your local LPT1:,LPT2:, or LPT3:) is mounted and a drive
  1497.   letter that you are mounted to. }
  1498.  
  1499. VAR
  1500.   NT : NotifyTypes;
  1501.   DriveTable : DriveArray;
  1502.   PrintTable : PrintArray;
  1503.   MaxDrive : Integer;
  1504.   SSC : Char;
  1505.   Pr : String[5];
  1506.   SplServer : S12;
  1507.  
  1508. Begin
  1509.    If Loaded then with SpoolSettings do
  1510.     begin
  1511. { Look at which server printer is mounted on and find out which drives it is
  1512.   also mounted to. }
  1513.        MaxDrive:=26;
  1514.        TenTest:=MountList(DriveTable,PrintTable,MaxDrive);
  1515.        If (TenTest=0)
  1516.        then
  1517.         begin
  1518.            SplServer:=PrintTable[Char(Printer+48)].ServerID;
  1519.            If ((SplServer='            ')or(SplServer='Local       '))
  1520.            then SplServer:=''
  1521.            else
  1522.             begin
  1523.                Pr:='LPT'+Char(Printer+48)+':';
  1524.                SSC:='A';
  1525.                While not ((SSC>Char(MaxDrive+64))or(DriveTable[SSC].ServerID=SplServer)) do Inc(SSC);
  1526.                If not (DriveTable[SSC].ServerID=SplServer) then SSC:=#0;
  1527.             end;
  1528.            If ((SSC<>#0)and(SplServer<>''))
  1529.            then
  1530.             begin
  1531.                UDVC:=Printer;
  1532.                UDVC:=UDVC+(Ord(SSC)-64)shl 4;
  1533.                UCode:=00;
  1534.                If Spoolname<>''
  1535.                then
  1536.                 begin
  1537.                    While (Pos(' ',Spoolname)>0) do Delete(Spoolname,Pos(' ',Spoolname),1);
  1538.                    If (Pos('.',Spoolname)>0) then Delete(Spoolname,Pos('.',Spoolname),1);
  1539.                 end;
  1540.                While Length(Spoolname)<11 do Spoolname:=Spoolname+' ';
  1541.                Move(Spoolname[1],SpoolSettings.UFile,11);
  1542.                UNote:=0;
  1543.                If (Start in Notification) then UNote:=UNote or 1;
  1544.                If (Reply in Notification) then UNote:=UNote or 2;
  1545.                If (Completion in Notification) then UNote:=UNote or 4;
  1546.                If (ExplQueue in Notification) then UNote:=UNote or 8;
  1547.                If (NoFF in Notification) then UNote:=UNote or 32;
  1548.                If (IDPage in Notification) then UNote:=UNote or 64;
  1549.                If (QueueTop in Notification) then UNote:=UNote or 2;
  1550.                UDays:=RDays;
  1551.                ULen:=0;
  1552.                UArea:=0;
  1553.                SetSpool:=0;
  1554.                Spooling:=True;
  1555.             end
  1556.            else SetSpool:=$23FF;
  1557.         end
  1558.        else SetSpool:=$25FF;
  1559.     end
  1560.   else SetSpool:=$FFFF;
  1561. End;
  1562.  
  1563.  
  1564. Function OpenSpool(NewSpoolname : S12) : Word;
  1565.  {Once SetSpool has "configured" your spool, calls to OpenSpool will
  1566.   create a new spoolfile with the optional Newspoolname, or with a name
  1567.   automatically set by 10Net if NewSpoolName=''. }
  1568.  
  1569. VAR
  1570.    OpenSpoolSet : SpoolBlock;
  1571.  
  1572. Begin
  1573.    If Spooling
  1574.    then with TenRegs do
  1575.     begin
  1576.        If NewSpoolname<>''
  1577.        then
  1578.         begin
  1579.            While (Pos(' ',NewSpoolname)>0) do Delete(NewSpoolname,Pos(' ',NewSpoolname),1);
  1580.            If (Pos('.',NewSpoolname)>0) then Delete(NewSpoolname,Pos('.',NewSpoolname),1);
  1581.         end;
  1582.        While Length(NewSpoolname)<11 do NewSpoolname:=NewSpoolname+' ';
  1583.        Move(NewSpoolname[1],SpoolSettings.UFile,11);
  1584.        Move(SpoolSettings,OpenSpoolSet,Sizeof(SpoolSettings));
  1585.        DS:=Seg(OpenSpoolSet);
  1586.        DX:=Ofs(OpenSpoolSet);
  1587.        AX:=$0E00;
  1588.        OpenSpoolSet.UCode:=0;
  1589.        Intr($6F,TenRegs);
  1590.        If ((Flags and 1)>0)
  1591.        then
  1592.         begin
  1593.            OpenSpool:=AX;
  1594.         end
  1595.        else OpenSpool:=0;
  1596.     end
  1597.    else OpenSpool:=$FFFF;
  1598. End;
  1599.  
  1600. Function CloseSpool : Word;
  1601. { Calls to CloseSpool, after a spool has been started through OpenSpool and
  1602.   some print has been "sent to the printer", will cause the Spoolfile to
  1603.   close and printing to begin if the Print Permit is ON at the location
  1604.   where the printer is mounted.
  1605.      "Sending print to the printer" is done in the usual manner, from within
  1606.   programs, by "Typing and Piping" (TYPE>LPT1 <filename>), by Copying from a
  1607.   file to the printer, etc.}
  1608.  
  1609. VAR
  1610.    CloseSpoolSet : SpoolBlock;
  1611. Begin
  1612.    If Spooling
  1613.    then with TenRegs do
  1614.     begin
  1615.        Move(SpoolSettings,CloseSpoolSet,Sizeof(SpoolSettings));
  1616.        DS:=Seg(CloseSpoolSet);
  1617.        DX:=Ofs(CloseSpoolSet);
  1618.        AX:=$0E00;
  1619.        CloseSpoolSet.UCode:=2;
  1620.        Intr($6F,TenRegs);
  1621.        If ((Flags and 1)>0)
  1622.        then
  1623.         begin
  1624.            CloseSpool:=AX;
  1625.         end
  1626.        else CloseSpool:=0;
  1627.     end
  1628.    else CloseSpool:=$FFFF;
  1629. End;
  1630.  
  1631.  
  1632. Function TenConfig(MaxSendRec,MaxRecvRec : Integer; {Size of largest records
  1633.                                                      to send/receive}
  1634.                    MaxRecs : Integer)   {Maximum number of Records to recv}
  1635.                           : Word;
  1636. VAR
  1637.    I : Integer;
  1638.    RetCode : Word;
  1639. { This function allows the user to dynamically change the size of the
  1640. buffers being used by TBSend and TBReceive to optimize usage.
  1641. MaxSendRec is the size of the largest TBSEND record
  1642. MaxRecvRec is the size of the largest TBRECEIVE record
  1643. MaxRecs is the number of TBReceive records to buffer
  1644. }
  1645. Begin
  1646.    If TNTI
  1647.    then
  1648.     begin
  1649.        For I:=1 to MaxReceives do
  1650.         begin
  1651.            FreeMem(TBD^[I],Sizeof(RcvBlock)*MaxRecvSets);
  1652.         end;
  1653.        FreeMem(TBD,MaxReceives*4);
  1654.        FreeMem(TBR,MaxReceives*Sizeof(RecvRec));
  1655.     end;
  1656.    RetCode:=0;
  1657.    If MaxRecs<1310 then MaxReceives:=MaxRecs
  1658.    else RetCode:=RetCode+1;
  1659.    If MaxSendRec<=65521 then MaxSendBufferSize:=MaxSendRec
  1660.    else RetCode:=RetCode+2;
  1661.    If MaxRecvRec<=65521 then MaxRecBuffersize:=MaxRecvRec
  1662.    else RetCode:=RetCode+4;
  1663.    If MaxRecs>0
  1664.    then
  1665.     begin
  1666.        MaxRecvSets:= MaxRecBufferSize div 457 + 1;
  1667.        GetMem(TBR,MaxReceives*Sizeof(RecvRec));
  1668.        GetMem(TBD,MaxReceives*4);
  1669.        For I:=1 to MaxReceives do
  1670.        GetMem(TBD^[I],Sizeof(RcvBlock)*MaxRecvSets);
  1671.     end;
  1672.    TenConfig:=RetCode;
  1673. End;
  1674.  
  1675. Function SetWait(WaitLimit : Integer): Word;
  1676. { Changes the maximum seconds to wait for receive packets in the same record,
  1677.   Defaults to 30 }
  1678. Begin
  1679.    If ((WaitLimit>0) and (WaitLimit<3000))
  1680.    then
  1681.     begin
  1682.        MaxRcvWait:=WaitLimit;
  1683.        SetWait:=0;
  1684.     end
  1685.    else SetWait:=$FFFF;
  1686. End;
  1687.  
  1688.  
  1689. Procedure SetUserName(UName : S8);
  1690. {Changes the Username in the Network Table and in the Global variable
  1691.   USERNAME}
  1692. VAR
  1693.    I : Integer;
  1694. Begin
  1695.    If Loaded
  1696.    then
  1697.     begin
  1698.        UserName:=Upcase8(UName);
  1699.        Move(UserName[1],ConfigTable^.CT_LName,8);
  1700.     end
  1701.    else UserName:=Upcase8(UName);
  1702. end;
  1703.  
  1704. { The Unit Initialization Code below locates the Configuration Table Address
  1705. and establishes the buffers necessary to make 10Net function calls. It will
  1706. be called at the beginning of a program to make the tools available
  1707. throughout the program. }
  1708.  
  1709.  
  1710. Begin
  1711.    If Loaded
  1712.    then with TenRegs do
  1713.     begin
  1714. (*      Initially, no space is allocated for Sends and Receives; These
  1715.        buffers can be established dynamically with a call to TenConfig.
  1716.        TenTest:=TenConfig(MaxSendBufferSize,MaxRecBufferSize,MaxReceives);
  1717.        If TenTest<>0 then Writeln('TenConfig Error: ',TenTest);
  1718. *)       AX:=$0300;
  1719.        Intr($6F,TenRegs);
  1720.        ConfigTable:=Ptr(ES,BX);
  1721.        PreConfig:=Ptr(ES,BX-51);
  1722.        UserName:='';
  1723.        For I10:=1 to 8 do UserName:=UserName+ConfigTable^.CT_LName[I10];
  1724.        TNTI:=True;
  1725.        Spooling:=False;
  1726.     end
  1727.    else
  1728.     begin
  1729.        Writeln('TenTools inititalization Error!');
  1730.        Writeln('Netword not Loaded!');
  1731.        Spooling:=False;
  1732.     end;
  1733. End. { Of TenTools Unit }
  1734.