mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 16:59:45 +01:00 
			
		
		
		
	* renamed winsock2 to winsock for win32 compatinility * new sockets unit for netware * changes for compiler warnings
		
			
				
	
	
		
			871 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			871 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    $Id$
 | 
						|
    This file is part of the Free Pascal run time library.
 | 
						|
    Copyright (c) 1999-2000 by the Free Pascal development team.
 | 
						|
 | 
						|
    Dos unit for BP7 compatible RTL (novell netware)
 | 
						|
 | 
						|
    See the file COPYING.FPC, included in this distribution,
 | 
						|
    for details about the copyright.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
						|
 | 
						|
 **********************************************************************}
 | 
						|
 | 
						|
{ 2000/09/03 armin: first version
 | 
						|
  2001/04/08 armin: implemented more functions
 | 
						|
                      OK: Implemented and tested
 | 
						|
                      NI: not implemented
 | 
						|
  2001/04/15 armin: FindFirst bug corrected, FExpand and FSearch tested, GetCBreak, SetCBreak
 | 
						|
                    implemented
 | 
						|
}
 | 
						|
 | 
						|
unit dos;
 | 
						|
interface
 | 
						|
 | 
						|
Const
 | 
						|
  {Bitmasks for CPU Flags}
 | 
						|
  fcarry     = $0001;
 | 
						|
  fparity    = $0004;
 | 
						|
  fauxiliary = $0010;
 | 
						|
  fzero      = $0040;
 | 
						|
  fsign      = $0080;
 | 
						|
  foverflow  = $0800;
 | 
						|
 | 
						|
  {Bitmasks for file attribute}
 | 
						|
  readonly  = $01;
 | 
						|
  hidden    = $02;
 | 
						|
  sysfile   = $04;
 | 
						|
  volumeid  = $08;
 | 
						|
  nwexeconly= $08;
 | 
						|
  directory = $10;
 | 
						|
  archive   = $20;
 | 
						|
  sharable  = $80;
 | 
						|
  anyfile   = $3F;
 | 
						|
 | 
						|
  {File Status}
 | 
						|
  fmclosed = $D7B0;
 | 
						|
  fminput  = $D7B1;
 | 
						|
  fmoutput = $D7B2;
 | 
						|
  fminout  = $D7B3;
 | 
						|
 | 
						|
 | 
						|
Type
 | 
						|
{ Needed for LFN Support }
 | 
						|
  ComStr  = String[255];
 | 
						|
  PathStr = String[255];
 | 
						|
  DirStr  = String[255];
 | 
						|
  NameStr = String[255];
 | 
						|
  ExtStr  = String[255];
 | 
						|
 | 
						|
{
 | 
						|
  filerec.inc contains the definition of the filerec.
 | 
						|
  textrec.inc contains the definition of the textrec.
 | 
						|
  It is in a separate file to make it available in other units without
 | 
						|
  having to use the DOS unit for it.
 | 
						|
}
 | 
						|
{$i filerec.inc}
 | 
						|
{$i textrec.inc}
 | 
						|
 | 
						|
  DateTime = packed record
 | 
						|
    Year,
 | 
						|
    Month,
 | 
						|
    Day,
 | 
						|
    Hour,
 | 
						|
    Min,
 | 
						|
    Sec   : word;
 | 
						|
  End;
 | 
						|
 | 
						|
  searchrec = packed record
 | 
						|
     DirP  : POINTER;              { used for opendir }
 | 
						|
     EntryP: POINTER;              { and readdir }
 | 
						|
     Magic : WORD;
 | 
						|
     fill  : array[1..11] of byte;
 | 
						|
     attr  : byte;
 | 
						|
     time  : longint;
 | 
						|
     { reserved : word; not in DJGPP V2 }
 | 
						|
     size  : longint;
 | 
						|
     name  : string[255]; { NW uses only [12] but more can't hurt }
 | 
						|
   end;
 | 
						|
 | 
						|
  registers = packed record
 | 
						|
    case i : integer of
 | 
						|
     0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
 | 
						|
     1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
 | 
						|
     2 : (eax,  ebx,  ecx,  edx,  ebp,  esi,  edi : longint);
 | 
						|
    end;
 | 
						|
 | 
						|
 | 
						|
Var
 | 
						|
  DosError : integer;
 | 
						|
 | 
						|
 | 
						|
 | 
						|
{Info/Date/Time}
 | 
						|
Function  DosVersion: Word;                                  {ok}
 | 
						|
Procedure GetDate(var year, month, mday, wday: word);        {ok}
 | 
						|
Procedure GetTime(var hour, minute, second, sec100: word);   {ok}
 | 
						|
procedure SetDate(year,month,day: word);                     {ok}
 | 
						|
Procedure SetTime(hour,minute,second,sec100: word);          {ok}
 | 
						|
Procedure UnpackTime(p: longint; var t: datetime);           {ok}
 | 
						|
Procedure PackTime(var t: datetime; var p: longint);         {ok}
 | 
						|
 | 
						|
{Exec}
 | 
						|
Procedure Exec(const path: pathstr; const comline: comstr);  {ni}
 | 
						|
Function  DosExitCode: word;                                 {ni}
 | 
						|
 | 
						|
{Disk}
 | 
						|
{$ifdef Int64}
 | 
						|
 Function  DiskFree(drive: byte) : int64;                    {ok}
 | 
						|
 Function  DiskSize(drive: byte) : int64;                    {ok}
 | 
						|
{$else}
 | 
						|
 Function  DiskFree(drive: byte) : longint;                  {ok}
 | 
						|
 Function  DiskSize(drive: byte) : longint;                  {ok}
 | 
						|
{$endif}
 | 
						|
 | 
						|
{FincClose has to be called to avoid memory leaks}
 | 
						|
Procedure FindFirst(const path: pathstr; attr: word;         {ok}
 | 
						|
                    var f: searchRec);
 | 
						|
Procedure FindNext(var f: searchRec);                        {ok}
 | 
						|
Procedure FindClose(Var f: SearchRec);                       {ok}
 | 
						|
 | 
						|
{File}
 | 
						|
Procedure GetFAttr(var f; var attr: word);                   {ok}
 | 
						|
Procedure GetFTime(var f; var time: longint);                {ok}
 | 
						|
Function  FSearch(path: pathstr; dirlist: string): pathstr;  {ok}
 | 
						|
Function  FExpand(const path: pathstr): pathstr;             {ok}
 | 
						|
Procedure FSplit(path: pathstr; var dir: dirstr; var name:   {untested}
 | 
						|
                 namestr; var ext: extstr);
 | 
						|
 | 
						|
{Environment}
 | 
						|
Function  EnvCount: longint;                                 {ni}
 | 
						|
Function  EnvStr(index: integer): string;                    {ni}
 | 
						|
Function  GetEnv(envvar: string): string;                    {ok}
 | 
						|
 | 
						|
{Misc}
 | 
						|
Procedure SetFAttr(var f; attr: word);                       {ni}
 | 
						|
Procedure SetFTime(var f; time: longint);                    {ni}
 | 
						|
Procedure GetCBreak(var breakvalue: boolean);                {ni}
 | 
						|
Procedure SetCBreak(breakvalue: boolean);                    {ni}
 | 
						|
Procedure GetVerify(var verify: boolean);                    {ni}
 | 
						|
Procedure SetVerify(verify: boolean);                        {ni}
 | 
						|
 | 
						|
{Do Nothing Functions}
 | 
						|
Procedure SwapVectors;                                       {ni}
 | 
						|
Procedure GetIntVec(intno: byte; var vector: pointer);       {ni}
 | 
						|
Procedure SetIntVec(intno: byte; vector: pointer);           {ni}
 | 
						|
Procedure Keep(exitcode: word);                              {ni}
 | 
						|
 | 
						|
Procedure Intr(intno: byte; var regs: registers);            {ni}
 | 
						|
Procedure MSDos(var regs: registers);                        {ni}
 | 
						|
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
uses
 | 
						|
  strings;
 | 
						|
 | 
						|
{$ASMMODE ATT}
 | 
						|
{$I nwsys.inc }
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                        --- Info / Date / Time ---
 | 
						|
******************************************************************************}
 | 
						|
{$PACKRECORDS 4}
 | 
						|
 | 
						|
 | 
						|
function dosversion : word;
 | 
						|
VAR F : FILE_SERV_INFO;
 | 
						|
begin
 | 
						|
  IF GetServerInformation(SIZEOF(F),@F) = 0 THEN
 | 
						|
    dosversion := WORD (F.netwareVersion) SHL 8 + F.netwareSubVersion;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure getdate(var year,month,mday,wday : word);
 | 
						|
VAR N : NWdateAndTime;
 | 
						|
begin
 | 
						|
  GetFileServerDateAndTime (N);
 | 
						|
  wday:=N.DayOfWeek;
 | 
						|
  year:=1900 + N.Year;
 | 
						|
  month:=N.Month;
 | 
						|
  mday:=N.Day;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure setdate(year,month,day : word);
 | 
						|
VAR N : NWdateAndTime;
 | 
						|
begin
 | 
						|
  GetFileServerDateAndTime (N);
 | 
						|
  SetFileServerDateAndTime(year,month,day,N.Hour,N.Minute,N.Second);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure gettime(var hour,minute,second,sec100 : word);
 | 
						|
VAR N : NWdateAndTime;
 | 
						|
begin
 | 
						|
  GetFileServerDateAndTime (N);
 | 
						|
  hour := N.Hour;
 | 
						|
  Minute:= N.Minute;
 | 
						|
  Second := N.Second;
 | 
						|
  sec100 := 0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure settime(hour,minute,second,sec100 : word);
 | 
						|
VAR N : NWdateAndTime;
 | 
						|
begin
 | 
						|
  GetFileServerDateAndTime (N);
 | 
						|
  SetFileServerDateAndTime(N.year,N.month,N.day,hour,minute,second);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure packtime(var t : datetime;var p : longint);
 | 
						|
Begin
 | 
						|
  p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
 | 
						|
End;
 | 
						|
 | 
						|
 | 
						|
Procedure unpacktime(p : longint;var t : datetime);
 | 
						|
Begin
 | 
						|
  with t do
 | 
						|
   begin
 | 
						|
     sec:=(p and 31) shl 1;
 | 
						|
     min:=(p shr 5) and 63;
 | 
						|
     hour:=(p shr 11) and 31;
 | 
						|
     day:=(p shr 16) and 31;
 | 
						|
     month:=(p shr 21) and 15;
 | 
						|
     year:=(p shr 25)+1980;
 | 
						|
   end;
 | 
						|
End;
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                               --- Exec ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
var
 | 
						|
  lastdosexitcode : word;
 | 
						|
 | 
						|
procedure exec(const path : pathstr;const comline : comstr);
 | 
						|
begin
 | 
						|
  ConsolePrintf ('warning: fpc dos.exec not implemented'#13#10,0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function dosexitcode : word;
 | 
						|
begin
 | 
						|
  dosexitcode:=lastdosexitcode;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure getcbreak(var breakvalue : boolean);
 | 
						|
begin
 | 
						|
  breakvalue := _SetCtrlCharCheckMode (false);  { get current setting }
 | 
						|
  if breakvalue then
 | 
						|
    _SetCtrlCharCheckMode (breakvalue);         { and restore old setting }
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure setcbreak(breakvalue : boolean);
 | 
						|
begin
 | 
						|
  _SetCtrlCharCheckMode (breakvalue);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure getverify(var verify : boolean);
 | 
						|
begin
 | 
						|
  verify := true;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure setverify(verify : boolean);
 | 
						|
begin
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                               --- Disk ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
function getvolnum (drive : byte) : longint;
 | 
						|
var dir : STRING[255];
 | 
						|
    P,PS,
 | 
						|
    V   : LONGINT;
 | 
						|
begin
 | 
						|
  if drive = 0 then
 | 
						|
  begin  // get volume name from current directory (i.e. SERVER-NAME/VOL2:TEST)
 | 
						|
    getdir (0,dir);
 | 
						|
    p := pos (':', dir);
 | 
						|
    if p = 0 then
 | 
						|
    begin
 | 
						|
      getvolnum := -1;
 | 
						|
      exit;
 | 
						|
    end;
 | 
						|
    byte (dir[0]) := p-1;
 | 
						|
    dir[p] := #0;
 | 
						|
    PS := pos ('/', dir);
 | 
						|
    INC (PS);
 | 
						|
    if _GetVolumeNumber (@dir[PS], V) <> 0 then
 | 
						|
      getvolnum := -1
 | 
						|
    else
 | 
						|
      getvolnum := V;
 | 
						|
  end else
 | 
						|
    getvolnum := drive-1;
 | 
						|
end;
 | 
						|
 | 
						|
{$ifdef Int64}
 | 
						|
 | 
						|
function diskfree(drive : byte) : int64;
 | 
						|
VAR Buf                 : ARRAY [0..255] OF CHAR;
 | 
						|
    TotalBlocks         : WORD;
 | 
						|
    SectorsPerBlock     : WORD;
 | 
						|
    availableBlocks     : WORD;
 | 
						|
    totalDirectorySlots : WORD;
 | 
						|
    availableDirSlots   : WORD;
 | 
						|
    volumeisRemovable   : WORD;
 | 
						|
    volumeNumber        : LONGINT;
 | 
						|
begin
 | 
						|
  volumeNumber := getvolnum (drive);
 | 
						|
  if volumeNumber >= 0 then
 | 
						|
  begin
 | 
						|
    {i think thats not the right function but for others i need a connection handle}
 | 
						|
    if _GetVolumeInfoWithNumber (volumeNumber,@Buf,
 | 
						|
                                 TotalBlocks,
 | 
						|
                                 SectorsPerBlock,
 | 
						|
                                 availableBlocks,
 | 
						|
                                 totalDirectorySlots,
 | 
						|
                                 availableDirSlots,
 | 
						|
                                 volumeisRemovable) = 0 THEN
 | 
						|
    begin
 | 
						|
      diskfree := int64 (availableBlocks) * int64 (SectorsPerBlock) * 512;
 | 
						|
    end else
 | 
						|
      diskfree := 0;
 | 
						|
  end else
 | 
						|
    diskfree := 0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function disksize(drive : byte) : int64;
 | 
						|
VAR Buf                 : ARRAY [0..255] OF CHAR;
 | 
						|
    TotalBlocks         : WORD;
 | 
						|
    SectorsPerBlock     : WORD;
 | 
						|
    availableBlocks     : WORD;
 | 
						|
    totalDirectorySlots : WORD;
 | 
						|
    availableDirSlots   : WORD;
 | 
						|
    volumeisRemovable   : WORD;
 | 
						|
    volumeNumber        : LONGINT;
 | 
						|
begin
 | 
						|
  volumeNumber := getvolnum (drive);
 | 
						|
  if volumeNumber >= 0 then
 | 
						|
  begin
 | 
						|
    {i think thats not the right function but for others i need a connection handle}
 | 
						|
    if _GetVolumeInfoWithNumber (volumeNumber,@Buf,
 | 
						|
                                 TotalBlocks,
 | 
						|
                                 SectorsPerBlock,
 | 
						|
                                 availableBlocks,
 | 
						|
                                 totalDirectorySlots,
 | 
						|
                                 availableDirSlots,
 | 
						|
                                 volumeisRemovable) = 0 THEN
 | 
						|
    begin
 | 
						|
      disksize := int64 (TotalBlocks) * int64 (SectorsPerBlock) * 512;
 | 
						|
    end else
 | 
						|
      disksize := 0;
 | 
						|
  end else
 | 
						|
    disksize := 0;
 | 
						|
end;
 | 
						|
{$else}
 | 
						|
 | 
						|
function diskfree(drive : byte) : longint;
 | 
						|
VAR Buf                 : ARRAY [0..255] OF CHAR;
 | 
						|
    TotalBlocks         : WORD;
 | 
						|
    SectorsPerBlock     : WORD;
 | 
						|
    availableBlocks     : WORD;
 | 
						|
    totalDirectorySlots : WORD;
 | 
						|
    availableDirSlots   : WORD;
 | 
						|
    volumeisRemovable   : WORD;
 | 
						|
    volumeNumber        : LONGINT;
 | 
						|
begin
 | 
						|
  volumeNumber := getvolnum (drive);
 | 
						|
  if (volumeNumber >= 0) and (volumeNumber <= 255) then
 | 
						|
  begin
 | 
						|
    {i think thats not the right function but for others i need a connection handle}
 | 
						|
    if _GetVolumeInfoWithNumber (byte(volumeNumber),@Buf,
 | 
						|
                                 TotalBlocks,
 | 
						|
                                 SectorsPerBlock,
 | 
						|
                                 availableBlocks,
 | 
						|
                                 totalDirectorySlots,
 | 
						|
                                 availableDirSlots,
 | 
						|
                                 volumeisRemovable) = 0 THEN
 | 
						|
    begin
 | 
						|
      diskfree := availableBlocks * SectorsPerBlock * 512;
 | 
						|
    end else
 | 
						|
      diskfree := 0;
 | 
						|
  end else
 | 
						|
    diskfree := 0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function disksize(drive : byte) : longint;
 | 
						|
VAR Buf                 : ARRAY [0..255] OF CHAR;
 | 
						|
    TotalBlocks         : WORD;
 | 
						|
    SectorsPerBlock     : WORD;
 | 
						|
    availableBlocks     : WORD;
 | 
						|
    totalDirectorySlots : WORD;
 | 
						|
    availableDirSlots   : WORD;
 | 
						|
    volumeisRemovable   : WORD;
 | 
						|
    volumeNumber        : LONGINT;
 | 
						|
begin
 | 
						|
  volumeNumber := getvolnum (drive);
 | 
						|
  if (volumeNumber >= 0) and (volumeNumber <= 255) then
 | 
						|
  begin
 | 
						|
    {i think thats not the right function but for others i need a connection handle}
 | 
						|
    if _GetVolumeInfoWithNumber (byte(volumeNumber),@Buf,
 | 
						|
                                 TotalBlocks,
 | 
						|
                                 SectorsPerBlock,
 | 
						|
                                 availableBlocks,
 | 
						|
                                 totalDirectorySlots,
 | 
						|
                                 availableDirSlots,
 | 
						|
                                 volumeisRemovable) = 0 THEN
 | 
						|
    begin
 | 
						|
      disksize := TotalBlocks * SectorsPerBlock * 512;
 | 
						|
    end else
 | 
						|
      disksize := 0;
 | 
						|
  end else
 | 
						|
    disksize := 0;
 | 
						|
end;
 | 
						|
 | 
						|
{$endif}
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                     --- Findfirst FindNext ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
 | 
						|
PROCEDURE find_setfields (VAR f : searchRec);
 | 
						|
BEGIN
 | 
						|
  WITH F DO
 | 
						|
  BEGIN
 | 
						|
    IF Magic = $AD01 THEN
 | 
						|
    BEGIN
 | 
						|
      attr := WORD (PNWDirEnt(EntryP)^.d_attr);  // lowest 16 bit -> same as dos
 | 
						|
      time := PNWDirEnt(EntryP)^.d_time + (LONGINT (PNWDirEnt(EntryP)^.d_date) SHL 16);
 | 
						|
      size := PNWDirEnt(EntryP)^.d_size;
 | 
						|
      name := strpas (PNWDirEnt(EntryP)^.d_nameDOS);
 | 
						|
      doserror := 0;
 | 
						|
    END ELSE
 | 
						|
    BEGIN
 | 
						|
      FillChar (f,SIZEOF(f),0);
 | 
						|
      doserror := 18;
 | 
						|
    END;
 | 
						|
  END;
 | 
						|
END;
 | 
						|
 | 
						|
 | 
						|
procedure findfirst(const path : pathstr;attr : word;var f : searchRec);
 | 
						|
var
 | 
						|
  path0 : array[0..256] of char;
 | 
						|
begin
 | 
						|
  IF path = '' then
 | 
						|
  begin
 | 
						|
    doserror := 18;
 | 
						|
    exit;
 | 
						|
  end;
 | 
						|
  strpcopy(path0,path);
 | 
						|
  PNWDirEnt(f.DirP) := _opendir (path0);
 | 
						|
  IF f.DirP = NIL THEN
 | 
						|
    doserror := 18
 | 
						|
  ELSE
 | 
						|
  BEGIN
 | 
						|
    IF attr <> anyfile THEN
 | 
						|
      _SetReaddirAttribute (PNWDirEnt(f.DirP), attr);
 | 
						|
    F.Magic := $AD01;
 | 
						|
    PNWDirEnt(f.EntryP) := _readdir (PNWDirEnt(f.DirP));
 | 
						|
    IF F.EntryP = NIL THEN
 | 
						|
    BEGIN
 | 
						|
      _closedir (PNWDirEnt(f.DirP));
 | 
						|
      f.Magic := 0;
 | 
						|
      doserror := 18;
 | 
						|
    END ELSE
 | 
						|
      find_setfields (f);
 | 
						|
  END;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure findnext(var f : searchRec);
 | 
						|
begin
 | 
						|
  IF F.Magic <> $AD01 THEN
 | 
						|
  BEGIN
 | 
						|
    doserror := 18;
 | 
						|
    EXIT;
 | 
						|
  END;
 | 
						|
  doserror:=0;
 | 
						|
  PNWDirEnt(f.EntryP) := _readdir (PNWDirEnt(f.DirP));
 | 
						|
  IF F.EntryP = NIL THEN
 | 
						|
    doserror := 18
 | 
						|
  ELSE
 | 
						|
    find_setfields (f);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure FindClose(Var f: SearchRec);
 | 
						|
begin
 | 
						|
  IF F.Magic <> $AD01 THEN
 | 
						|
  BEGIN
 | 
						|
    doserror := 18;
 | 
						|
    EXIT;
 | 
						|
  END;
 | 
						|
  doserror:=0;
 | 
						|
  _closedir (PNWDirEnt(f.DirP));
 | 
						|
  f.Magic := 0;
 | 
						|
  f.DirP := NIL;
 | 
						|
  f.EntryP := NIL;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure swapvectors;
 | 
						|
begin
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                               --- File ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
procedure fsplit(path : pathstr;var dir : dirstr;var name : namestr;var ext : extstr);
 | 
						|
var
 | 
						|
   dotpos,p1,i : longint;
 | 
						|
begin
 | 
						|
  { allow slash as backslash }
 | 
						|
  for i:=1 to length(path) do
 | 
						|
   if path[i]='/' then path[i]:='\';
 | 
						|
  { get drive name }
 | 
						|
  p1:=pos(':',path);
 | 
						|
  if p1>0 then
 | 
						|
    begin
 | 
						|
       dir:=path[1]+':';
 | 
						|
       delete(path,1,p1);
 | 
						|
    end
 | 
						|
  else
 | 
						|
    dir:='';
 | 
						|
  { split the path and the name, there are no more path informtions }
 | 
						|
  { if path contains no backslashes                                 }
 | 
						|
  while true do
 | 
						|
    begin
 | 
						|
       p1:=pos('\',path);
 | 
						|
       if p1=0 then
 | 
						|
         break;
 | 
						|
       dir:=dir+copy(path,1,p1);
 | 
						|
       delete(path,1,p1);
 | 
						|
    end;
 | 
						|
  { try to find out a extension }
 | 
						|
  if LFNSupport then
 | 
						|
    begin
 | 
						|
       Ext:='';
 | 
						|
       i:=Length(Path);
 | 
						|
       DotPos:=256;
 | 
						|
       While (i>0) Do
 | 
						|
         Begin
 | 
						|
            If (Path[i]='.') Then
 | 
						|
              begin
 | 
						|
                 DotPos:=i;
 | 
						|
                 break;
 | 
						|
              end;
 | 
						|
            Dec(i);
 | 
						|
         end;
 | 
						|
       Ext:=Copy(Path,DotPos,255);
 | 
						|
       Name:=Copy(Path,1,DotPos - 1);
 | 
						|
    end
 | 
						|
  else
 | 
						|
    begin
 | 
						|
       p1:=pos('.',path);
 | 
						|
       if p1>0 then
 | 
						|
         begin
 | 
						|
            ext:=copy(path,p1,4);
 | 
						|
            delete(path,p1,length(path)-p1+1);
 | 
						|
         end
 | 
						|
       else
 | 
						|
         ext:='';
 | 
						|
       name:=path;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function fexpand(const path : pathstr) : pathstr;
 | 
						|
var
 | 
						|
  s,pa : pathstr;
 | 
						|
  i,j  : longint;
 | 
						|
begin
 | 
						|
  getdir(0,s);
 | 
						|
  i:=ioresult;
 | 
						|
  if LFNSupport then
 | 
						|
   begin
 | 
						|
     pa:=path;
 | 
						|
   end
 | 
						|
  else
 | 
						|
   if FileNameCaseSensitive then
 | 
						|
    pa:=path
 | 
						|
   else
 | 
						|
    pa:=upcase(path);
 | 
						|
 | 
						|
  { allow slash as backslash }
 | 
						|
  for i:=1 to length(pa) do
 | 
						|
   if pa[i]='/' then
 | 
						|
    pa[i]:='\';
 | 
						|
 | 
						|
  if (length(pa)>1) and (pa[2]=':') and (pa[1] in ['A'..'Z','a'..'z']) then
 | 
						|
    begin
 | 
						|
       { Always uppercase driveletter }
 | 
						|
       if (pa[1] in ['a'..'z']) then
 | 
						|
        pa[1]:=Chr(Ord(Pa[1])-32);
 | 
						|
       { we must get the right directory }
 | 
						|
       getdir(ord(pa[1])-ord('A')+1,s);
 | 
						|
       i:=ioresult;
 | 
						|
       if (ord(pa[0])>2) and (pa[3]<>'\') then
 | 
						|
         if pa[1]=s[1] then
 | 
						|
           begin
 | 
						|
             { remove ending slash if it already exists }
 | 
						|
             if s[length(s)]='\' then
 | 
						|
              dec(s[0]);
 | 
						|
             pa:=s+'\'+copy (pa,3,length(pa));
 | 
						|
           end
 | 
						|
         else
 | 
						|
           pa:=pa[1]+':\'+copy (pa,3,length(pa))
 | 
						|
    end
 | 
						|
  else
 | 
						|
    if pa[1]='\' then
 | 
						|
      begin
 | 
						|
        { Do not touch Network drive names if LFNSupport is true }
 | 
						|
        if not ((Length(pa)>1) and (pa[2]='\') and LFNSupport) then
 | 
						|
          pa:=s[1]+':'+pa;
 | 
						|
      end
 | 
						|
    else if s[0]=#3 then
 | 
						|
      pa:=s+pa
 | 
						|
    else
 | 
						|
      pa:=s+'\'+pa;
 | 
						|
 | 
						|
{ Turbo Pascal gives current dir on drive if only drive given as parameter! }
 | 
						|
if length(pa) = 2 then
 | 
						|
 begin
 | 
						|
   getdir(byte(pa[1])-64,s);
 | 
						|
   pa := s;
 | 
						|
 end;
 | 
						|
 | 
						|
{First remove all references to '\.\'}
 | 
						|
  while pos ('\.\',pa)<>0 do
 | 
						|
   delete (pa,pos('\.\',pa),2);
 | 
						|
{Now remove also all references to '\..\' + of course previous dirs..}
 | 
						|
  repeat
 | 
						|
    i:=pos('\..\',pa);
 | 
						|
    if i<>0 then
 | 
						|
     begin
 | 
						|
       j:=i-1;
 | 
						|
       while (j>1) and (pa[j]<>'\') do
 | 
						|
        dec (j);
 | 
						|
       if pa[j+1] = ':' then j := 3;
 | 
						|
       delete (pa,j,i-j+3);
 | 
						|
     end;
 | 
						|
  until i=0;
 | 
						|
 | 
						|
  { Turbo Pascal gets rid of a \.. at the end of the path }
 | 
						|
  { Now remove also any reference to '\..'  at end of line
 | 
						|
    + of course previous dir.. }
 | 
						|
  i:=pos('\..',pa);
 | 
						|
  if i<>0 then
 | 
						|
   begin
 | 
						|
     if i = length(pa) - 2 then
 | 
						|
      begin
 | 
						|
        j:=i-1;
 | 
						|
        while (j>1) and (pa[j]<>'\') do
 | 
						|
         dec (j);
 | 
						|
        delete (pa,j,i-j+3);
 | 
						|
      end;
 | 
						|
      pa := pa + '\';
 | 
						|
    end;
 | 
						|
  { Remove End . and \}
 | 
						|
  if (length(pa)>0) and (pa[length(pa)]='.') then
 | 
						|
   dec(byte(pa[0]));
 | 
						|
  { if only the drive + a '\' is left then the '\' should be left to prevtn the program
 | 
						|
    accessing the current directory on the drive rather than the root!}
 | 
						|
  { if the last char of path = '\' then leave it in as this is what TP does! }
 | 
						|
  if ((length(pa)>3) and (pa[length(pa)]='\')) and (path[length(path)] <> '\') then
 | 
						|
   dec(byte(pa[0]));
 | 
						|
  { if only a drive is given in path then there should be a '\' at the
 | 
						|
    end of the string given back }
 | 
						|
  if length(pa) = 2 then pa := pa + '\';
 | 
						|
  fexpand:=pa;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Function FSearch(path: pathstr; dirlist: string): pathstr;
 | 
						|
var
 | 
						|
  i,p1   : longint;
 | 
						|
  s      : searchrec;
 | 
						|
  newdir : pathstr;
 | 
						|
begin
 | 
						|
{ check if the file specified exists }
 | 
						|
  findfirst(path,anyfile,s);
 | 
						|
  if doserror=0 then
 | 
						|
   begin
 | 
						|
     findclose(s);
 | 
						|
     fsearch:=path;
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
{ No wildcards allowed in these things }
 | 
						|
  if (pos('?',path)<>0) or (pos('*',path)<>0) then
 | 
						|
    fsearch:=''
 | 
						|
  else
 | 
						|
    begin
 | 
						|
       { allow slash as backslash }
 | 
						|
       for i:=1 to length(dirlist) do
 | 
						|
         if dirlist[i]='/' then dirlist[i]:='\';
 | 
						|
       repeat
 | 
						|
         p1:=pos(';',dirlist);
 | 
						|
         if p1<>0 then
 | 
						|
          begin
 | 
						|
            newdir:=copy(dirlist,1,p1-1);
 | 
						|
            delete(dirlist,1,p1);
 | 
						|
          end
 | 
						|
         else
 | 
						|
          begin
 | 
						|
            newdir:=dirlist;
 | 
						|
            dirlist:='';
 | 
						|
          end;
 | 
						|
         if (newdir<>'') and (not (newdir[length(newdir)] in ['\',':'])) then
 | 
						|
          newdir:=newdir+'\';
 | 
						|
         findfirst(newdir+path,anyfile,s);
 | 
						|
         if doserror=0 then
 | 
						|
          newdir:=newdir+path
 | 
						|
         else
 | 
						|
          newdir:='';
 | 
						|
       until (dirlist='') or (newdir<>'');
 | 
						|
       fsearch:=newdir;
 | 
						|
    end;
 | 
						|
  findclose(s);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                       --- Get/Set File Time,Attr ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
procedure getftime(var f;var time : longint);
 | 
						|
VAR StatBuf : NWStatBufT;
 | 
						|
    T       : DateTime;
 | 
						|
    DosDate,
 | 
						|
    DosTime : WORD;
 | 
						|
begin
 | 
						|
  IF _fstat (FileRec (f).Handle, StatBuf) = 0 THEN
 | 
						|
  BEGIN
 | 
						|
    _ConvertTimeToDos (StatBuf.st_mtime, DosDate, DosTime);
 | 
						|
    time := DosTime + (LONGINT (DosDate) SHL 16);
 | 
						|
  END ELSE
 | 
						|
    time := 0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure setftime(var f;time : longint);
 | 
						|
begin
 | 
						|
  {is there a netware function to do that ?????}
 | 
						|
  ConsolePrintf ('warning: fpc dos.setftime not implemented'#13#10,0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure getfattr(var f;var attr : word);
 | 
						|
VAR StatBuf : NWStatBufT;
 | 
						|
begin
 | 
						|
  IF _fstat (FileRec (f).Handle, StatBuf) = 0 THEN
 | 
						|
  BEGIN
 | 
						|
    attr := word (StatBuf.st_attr);
 | 
						|
  END ELSE
 | 
						|
    attr := 0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure setfattr(var f;attr : word);
 | 
						|
begin
 | 
						|
  {is there a netware function to do that ?????}
 | 
						|
  ConsolePrintf ('warning: fpc dos.setfattr not implemented'#13#10,0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                             --- Environment ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
function envcount : longint;
 | 
						|
begin
 | 
						|
  envcount := 0;  {is there a netware function to do that ?????}
 | 
						|
  ConsolePrintf ('warning: fpc dos.envcount not implemented'#13#10,0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function envstr(index : integer) : string;
 | 
						|
begin
 | 
						|
  envstr := '';   {is there a netware function to do that ?????}
 | 
						|
  ConsolePrintf ('warning: fpc dos.envstr not implemented'#13#10,0);
 | 
						|
end;
 | 
						|
 | 
						|
{ the function exists in clib but i dont know how to set environment vars.
 | 
						|
  may be it's only a dummy in clib }
 | 
						|
Function  GetEnv(envvar: string): string;
 | 
						|
var
 | 
						|
  envvar0 : array[0..256] of char;
 | 
						|
  p       : pchar;
 | 
						|
begin
 | 
						|
  strpcopy(envvar0,envvar);
 | 
						|
  p := _getenv (envvar0);
 | 
						|
  if p = NIL then
 | 
						|
    GetEnv := ''
 | 
						|
  else
 | 
						|
    GetEnv := strpas (p);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{******************************************************************************
 | 
						|
                             --- Not Supported ---
 | 
						|
******************************************************************************}
 | 
						|
 | 
						|
Procedure keep(exitcode : word);
 | 
						|
Begin
 | 
						|
 { no netware equivalent }
 | 
						|
End;
 | 
						|
 | 
						|
Procedure getintvec(intno : byte;var vector : pointer);
 | 
						|
Begin
 | 
						|
 { no netware equivalent }
 | 
						|
End;
 | 
						|
 | 
						|
Procedure setintvec(intno : byte;vector : pointer);
 | 
						|
Begin
 | 
						|
 { no netware equivalent }
 | 
						|
End;
 | 
						|
 | 
						|
procedure intr(intno : byte;var regs : registers);
 | 
						|
begin
 | 
						|
 { no netware equivalent }
 | 
						|
end;
 | 
						|
 | 
						|
procedure msdos(var regs : registers);
 | 
						|
begin
 | 
						|
 { no netware equivalent }
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
end.
 | 
						|
{
 | 
						|
  $Log$
 | 
						|
  Revision 1.6  2003-03-25 18:17:54  armin
 | 
						|
  * support for fcl, support for linking without debug info
 | 
						|
  * renamed winsock2 to winsock for win32 compatinility
 | 
						|
  * new sockets unit for netware
 | 
						|
  * changes for compiler warnings
 | 
						|
 | 
						|
  Revision 1.5  2002/09/07 16:01:20  peter
 | 
						|
    * old logs removed and tabs fixed
 | 
						|
 | 
						|
}
 |