| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 | {    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. **********************************************************************}unit dos;interfaceType  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;{$i dosh.inc}implementationuses  strings, nwserv;{$DEFINE HAS_GETMSCOUNT}{$DEFINE HAS_GETCBREAK}{$DEFINE HAS_SETCBREAK}{$DEFINE HAS_KEEP}{$define FPC_FEXPAND_DRIVES}{$define FPC_FEXPAND_VOLUMES}{$define FPC_FEXPAND_NO_DEFAULT_PATHS}{$I dos.inc}{$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;function GetMsCount: int64;begin  GetMsCount := int64 (Nwserv.GetCurrentTicks) * 55;end;{******************************************************************************                               --- Exec ---******************************************************************************}const maxargs=256;procedure exec(const path : pathstr;const comline : comstr);var c : comstr;    i : integer;    args : array[0..maxargs] of pchar;    arg0 : pathstr;    numargs : integer;begin  //writeln ('dos.exec (',path,',',comline,')');  arg0 := fexpand (path)+#0;  args[0] := @arg0[1];  numargs := 0;  c:=comline;  i:=1;  while i<=length(c) do  begin    if c[i]<>' ' then    begin      {Commandline argument found. append #0 and set pointer in args }      inc(numargs);      args[numargs]:=@c[i];      while (i<=length(c)) and (c[i]<>' ') do        inc(i);      c[i] := #0;    end;    inc(i);  end;  args[numargs+1] := nil;  i := spawnvp (P_WAIT,args[0],@args);  if i >= 0 then  begin    doserror := 0;    lastdosexitcode := i;  end else  begin    doserror := 8;  // for now, what about errno ?  end;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;{******************************************************************************                               --- 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;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 (byte(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 (byte(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;{******************************************************************************                     --- 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_name);      if name = '' then        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;{******************************************************************************                               --- File ---******************************************************************************}Function FSearch(path: pathstr; dirlist: string): pathstr;var  p1     : longint;  s      : searchrec;  newdir : pathstr;begin  { No wildcards allowed in these things }  if (pos('?',path)<>0) or (pos('*',path)<>0) then  begin    fsearch:='';    exit;  end;  { check if the file specified exists }  findfirst(path,anyfile and not(directory),s);  if doserror=0 then    begin     findclose(s);     fsearch:=path;     exit;    end;  findclose(s);  { allow backslash as slash }  DoDirSeparators(dirlist); 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 [DirectorySeparator,DriveSeparator])) then    newdir:=newdir+DirectorySeparator;   findfirst(newdir+path,anyfile and not(directory),s);   if doserror=0 then    newdir:=newdir+path   else    newdir:='';   findclose(s); until (dirlist='') or (newdir<>''); fsearch:=newdir;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);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);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);end;function envstr (index: longint) : string;begin  envstr := '';   {is there a netware function to do that ?????}  ConsolePrintf ('warning: fpc dos.envstr not implemented'#13#10);end;{ works fine (at least with netware 6.5) }Function  GetEnv(envvar: string): string;var envvar0 : array[0..512] of char;    p       : pchar;    i,isDosPath,res : longint;begin  if upcase(envvar) = 'PATH' then  begin  // netware does not have search paths in the environment var PATH         // return it here (needed for the compiler)    GetEnv := '';    i := 1;    res := _NWGetSearchPathElement (i, isdosPath, @envvar0[0]);    while res = 0 do    begin      if GetEnv <> '' then GetEnv := GetEnv + ';';      GetEnv := GetEnv + strpas(envvar0);      inc (i);      res := _NWGetSearchPathElement (i, isdosPath, @envvar0[0]);    end;    DoDirSeparators(getenv);  end else  begin    strpcopy(envvar0,envvar);    p := _getenv (envvar0);    if p = NIL then      GetEnv := ''    else      GetEnv := strpas (p);  end;end;{******************************************************************************                             --- Not Supported ---******************************************************************************}Procedure keep(exitcode : word);Begin { simply wait until nlm will be unloaded } while true do _delay (60000);End;end.
 |