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;
- interface
- Type
- 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}
- implementation
- uses
- 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.
|