sysutils.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. Sysutils unit for netware
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit sysutils;
  13. interface
  14. {$MODE objfpc}
  15. {$MODESWITCH OUT}
  16. { force ansistrings }
  17. {$H+}
  18. uses DOS;
  19. {$I nwsys.inc}
  20. {$I errno.inc}
  21. {$DEFINE HAS_SLEEP}
  22. {$DEFINE HAS_OSERROR}
  23. TYPE
  24. TNetwareFindData =
  25. RECORD
  26. DirP : PNWDirEnt; { used for opendir }
  27. EntryP: PNWDirEnt; { and readdir }
  28. Magic : WORD; { to avoid abends with uninitialized TSearchRec }
  29. END;
  30. { Include platform independent interface part }
  31. {$i sysutilh.inc}
  32. { additional NetWare file flags}
  33. CONST
  34. faSHARE = $00000080; { Sharable file }
  35. faNO_SUBALLOC = $00000800; { Don't sub alloc. this file }
  36. faTRANS = $00001000; { Transactional file (TTS usable) }
  37. faREADAUD = $00004000; { Read audit }
  38. faWRITAUD = $00008000; { Write audit }
  39. faIMMPURG = $00010000; { Immediate purge }
  40. faNORENAM = $00020000; { Rename inhibit }
  41. faNODELET = $00040000; { Delete inhibit }
  42. faNOCOPY = $00080000; { Copy inhibit }
  43. faFILE_MIGRATED = $00400000; { File has been migrated }
  44. faDONT_MIGRATE = $00800000; { Don't migrate this file }
  45. faIMMEDIATE_COMPRESS = $02000000; { Compress this file immediately }
  46. faFILE_COMPRESSED = $04000000; { File is compressed }
  47. faDONT_COMPRESS = $08000000; { Don't compress this file }
  48. faCANT_COMPRESS = $20000000; { Can't compress this file }
  49. faATTR_ARCHIVE = $40000000; { Entry has had an EA modified, }
  50. { an ownerID changed, or trustee }
  51. { info changed, etc. }
  52. implementation
  53. uses
  54. sysconst;
  55. {$define FPC_FEXPAND_DRIVES}
  56. {$define FPC_FEXPAND_VOLUMES}
  57. {$define FPC_FEXPAND_NO_DEFAULT_PATHS}
  58. { Include platform independent implementation part }
  59. {$i sysutils.inc}
  60. {****************************************************************************
  61. File Functions
  62. ****************************************************************************}
  63. Function FileOpen (Const FileName : string; Mode : Integer) : THandle;
  64. VAR NWOpenFlags : longint;
  65. BEGIN
  66. NWOpenFlags:=0;
  67. Case (Mode and 3) of
  68. 0 : NWOpenFlags:=NWOpenFlags or O_RDONLY;
  69. 1 : NWOpenFlags:=NWOpenFlags or O_WRONLY;
  70. 2 : NWOpenFlags:=NWOpenFlags or O_RDWR;
  71. end;
  72. FileOpen := _open (pchar(FileName),NWOpenFlags,0);
  73. //!! We need to set locking based on Mode !!
  74. end;
  75. Function FileCreate (Const FileName : String) : THandle;
  76. begin
  77. FileCreate:=_open(Pchar(FileName),O_RdWr or O_Creat or O_Trunc,0);
  78. end;
  79. Function FileCreate (Const FileName : String; mode:longint) : THandle;
  80. begin
  81. FileCreate:=FileCreate (FileName);
  82. end;
  83. Function FileRead (Handle : THandle; Out Buffer; Count : longint) : longint;
  84. begin
  85. FileRead:=_read (Handle,@Buffer,Count);
  86. end;
  87. Function FileWrite (Handle : THandle; const Buffer; Count : Longint) : longint;
  88. begin
  89. FileWrite:=_write (Handle,@Buffer,Count);
  90. end;
  91. Function FileSeek (Handle : THandle; FOffset,Origin : Longint) : Longint;
  92. begin
  93. FileSeek:=_lseek (Handle,FOffset,Origin);
  94. end;
  95. Function FileSeek (Handle : THandle; FOffset: Int64; Origin: Longint) : Int64;
  96. begin
  97. {$warning need to add 64bit FileSeek }
  98. FileSeek:=FileSeek(Handle,Longint(FOffset),Longint(Origin));
  99. end;
  100. Procedure FileClose (Handle : THandle);
  101. begin
  102. _close(Handle);
  103. end;
  104. Function FileTruncate (Handle : THandle; Size: Int64) : boolean;
  105. begin
  106. if Size > high (longint) then
  107. FileTruncate := false
  108. {$WARNING Possible support for 64-bit FS to be checked!}
  109. else
  110. FileTruncate:=(_chsize(Handle,Size) = 0);
  111. end;
  112. Function FileLock (Handle,FOffset,FLen : Longint) : Longint;
  113. begin
  114. FileLock := _lock (Handle,FOffset,FLen);
  115. end;
  116. Function FileLock (Handle : Longint; FOffset,FLen : Int64) : Longint;
  117. begin
  118. {$warning need to add 64bit FileLock call }
  119. FileLock := FileLock (Handle, longint(FOffset),longint(FLen));
  120. end;
  121. Function FileUnlock (Handle,FOffset,FLen : Longint) : Longint;
  122. begin
  123. FileUnlock := _unlock (Handle,FOffset,FLen);
  124. end;
  125. Function FileUnlock (Handle : Longint; FOffset,FLen : Int64) : Longint;
  126. begin
  127. {$warning need to add 64bit FileUnlock call }
  128. FileUnlock := FileUnlock (Handle, longint(FOffset),longint(FLen));
  129. end;
  130. Function FileAge (Const FileName : String): Longint;
  131. VAR Info : NWStatBufT;
  132. PTM : PNWTM;
  133. begin
  134. If _stat (pchar(FileName),Info) <> 0 then
  135. exit(-1)
  136. else
  137. begin
  138. PTM := _localtime (Info.st_mtime);
  139. IF PTM = NIL THEN
  140. exit(-1)
  141. else
  142. WITH PTM^ DO
  143. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  144. end;
  145. end;
  146. Function FileExists (Const FileName : String) : Boolean;
  147. VAR Info : NWStatBufT;
  148. begin
  149. FileExists:=(_stat(pchar(filename),Info) = 0);
  150. end;
  151. PROCEDURE find_setfields (VAR f : TsearchRec);
  152. VAR T : Dos.DateTime;
  153. BEGIN
  154. WITH F DO
  155. BEGIN
  156. IF FindData.Magic = $AD01 THEN
  157. BEGIN
  158. {attr := FindData.EntryP^.d_attr AND $FF;} // lowest 8 bit -> same as dos
  159. attr := FindData.EntryP^.d_attr; { return complete netware attributes }
  160. UnpackTime(FindData.EntryP^.d_time + (LONGINT (FindData.EntryP^.d_date) SHL 16), T);
  161. time := DateTimeToFileDate(EncodeDate(T.Year,T.Month,T.day)+EncodeTime(T.Hour,T.Min,T.Sec,0));
  162. size := FindData.EntryP^.d_size;
  163. name := strpas (FindData.EntryP^.d_nameDOS);
  164. END ELSE
  165. BEGIN
  166. FillChar (f,SIZEOF(f),0);
  167. END;
  168. END;
  169. END;
  170. Function FindFirst (Const Path : String; Attr : Longint; out Rslt : TSearchRec) : Longint;
  171. begin
  172. IF path = '' then
  173. exit (18);
  174. Rslt.FindData.DirP := _opendir (pchar(Path));
  175. IF Rslt.FindData.DirP = NIL THEN
  176. exit (18);
  177. IF attr <> faAnyFile THEN
  178. _SetReaddirAttribute (Rslt.FindData.DirP, attr);
  179. Rslt.FindData.Magic := $AD01;
  180. Rslt.FindData.EntryP := _readdir (Rslt.FindData.DirP);
  181. if Rslt.FindData.EntryP = nil then
  182. begin
  183. _closedir (Rslt.FindData.DirP);
  184. Rslt.FindData.DirP := NIL;
  185. result := 18;
  186. end else
  187. begin
  188. find_setfields (Rslt);
  189. result := 0;
  190. end;
  191. end;
  192. Function FindNext (Var Rslt : TSearchRec) : Longint;
  193. begin
  194. IF Rslt.FindData.Magic <> $AD01 THEN
  195. exit (18);
  196. Rslt.FindData.EntryP := _readdir (Rslt.FindData.DirP);
  197. IF Rslt.FindData.EntryP = NIL THEN
  198. exit (18);
  199. find_setfields (Rslt);
  200. result := 0;
  201. end;
  202. Procedure FindClose (Var F : TSearchrec);
  203. begin
  204. IF F.FindData.Magic = $AD01 THEN
  205. BEGIN
  206. IF F.FindData.DirP <> NIL THEN
  207. _closedir (F.FindData.DirP);
  208. F.FindData.Magic := 0;
  209. F.FindData.DirP := NIL;
  210. F.FindData.EntryP := NIL;
  211. END;
  212. end;
  213. Function FileGetDate (Handle : THandle) : Longint;
  214. Var Info : NWStatBufT;
  215. PTM : PNWTM;
  216. begin
  217. If _fstat(Handle,Info) <> 0 then
  218. Result:=-1
  219. else
  220. begin
  221. PTM := _localtime (Info.st_mtime);
  222. IF PTM = NIL THEN
  223. exit(-1)
  224. else
  225. WITH PTM^ DO
  226. Result:=DateTimeToFileDate(EncodeDate(tm_year+1900,tm_mon+1,tm_mday)+EncodeTime(tm_hour,tm_min,tm_sec,0));
  227. end;
  228. end;
  229. Function FileSetDate (Handle : THandle; Age : Longint) : Longint;
  230. begin
  231. { i think its impossible under netware from FileHandle. I dident found a way to get the
  232. complete pathname of a filehandle, that would be needed for ChangeDirectoryEntry }
  233. FileSetDate:=-1;
  234. ConsolePrintf ('warning: fpc sysutils.FileSetDate not implemented'#13#10,0);
  235. {$warning FileSetDate not implemented (i think is impossible) }
  236. end;
  237. Function FileGetAttr (Const FileName : String) : Longint;
  238. Var Info : NWStatBufT;
  239. begin
  240. If _stat (pchar(FileName),Info) <> 0 then
  241. Result:=-1
  242. Else
  243. Result := Info.st_attr AND $FFFF;
  244. end;
  245. Function FileSetAttr (Const Filename : String; Attr: longint) : Longint;
  246. VAR MS : NWModifyStructure;
  247. begin
  248. FillChar (MS, SIZEOF (MS), 0);
  249. if _ChangeDirectoryEntry (PChar (Filename), MS, MFileAtrributesBit, 0) <> 0 then
  250. result := -1
  251. else
  252. result := 0;
  253. end;
  254. Function DeleteFile (Const FileName : String) : Boolean;
  255. begin
  256. Result:= (_UnLink (pchar(FileName)) = 0);
  257. end;
  258. Function RenameFile (Const OldName, NewName : String) : Boolean;
  259. begin
  260. RenameFile:=(_rename(pchar(OldName),pchar(NewName)) = 0);
  261. end;
  262. {****************************************************************************
  263. Disk Functions
  264. ****************************************************************************}
  265. {
  266. The Diskfree and Disksize functions need a file on the specified drive, since this
  267. is required for the statfs system call.
  268. These filenames are set in drivestr[0..26], and have been preset to :
  269. 0 - '.' (default drive - hence current dir is ok.)
  270. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  271. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  272. 3 - '/' (C: equivalent of dos is the root partition)
  273. 4..26 (can be set by you're own applications)
  274. ! Use AddDisk() to Add new drives !
  275. They both return -1 when a failure occurs.
  276. }
  277. Const
  278. FixDriveStr : array[0..3] of pchar=(
  279. '.',
  280. 'a:.',
  281. 'b:.',
  282. 'sys:/'
  283. );
  284. var
  285. Drives : byte;
  286. DriveStr : array[4..26] of pchar;
  287. Procedure AddDisk(const path:string);
  288. begin
  289. if not (DriveStr[Drives]=nil) then
  290. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  291. GetMem(DriveStr[Drives],length(Path)+1);
  292. StrPCopy(DriveStr[Drives],path);
  293. inc(Drives);
  294. if Drives>26 then
  295. Drives:=4;
  296. end;
  297. Function DiskFree(Drive: Byte): int64;
  298. //var fs : statfs;
  299. Begin
  300. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  301. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  302. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  303. else
  304. Diskfree:=-1;}
  305. DiskFree := -1;
  306. ConsolePrintf ('warning: fpc sysutils.diskfree not implemented'#13#10,0);
  307. {$warning DiskFree not implemented (does it make sense ?) }
  308. End;
  309. Function DiskSize(Drive: Byte): int64;
  310. //var fs : statfs;
  311. Begin
  312. { if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and fsstat(StrPas(fixdrivestr[drive]),fs)) or
  313. ((not (drivestr[Drive]=nil)) and fsstat(StrPas(drivestr[drive]),fs)) then
  314. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  315. else
  316. DiskSize:=-1;}
  317. DiskSize := -1;
  318. ConsolePrintf ('warning: fpc sysutils.disksize not implemented'#13#10,0);
  319. {$warning DiskSize not implemented (does it make sense ?) }
  320. End;
  321. Function GetCurrentDir : String;
  322. begin
  323. GetDir (0,Result);
  324. end;
  325. Function SetCurrentDir (Const NewDir : String) : Boolean;
  326. begin
  327. {$I-}
  328. ChDir(NewDir);
  329. {$I+}
  330. result := (IOResult = 0);
  331. end;
  332. Function CreateDir (Const NewDir : String) : Boolean;
  333. begin
  334. {$I-}
  335. MkDir(NewDir);
  336. {$I+}
  337. result := (IOResult = 0);
  338. end;
  339. Function RemoveDir (Const Dir : String) : Boolean;
  340. begin
  341. {$I-}
  342. RmDir(Dir);
  343. {$I+}
  344. result := (IOResult = 0);
  345. end;
  346. function DirectoryExists (const Directory: string): boolean;
  347. VAR Info : NWStatBufT;
  348. begin
  349. If _stat (pchar(Directory),Info) <> 0 then
  350. exit(false)
  351. else
  352. Exit ((Info.st_attr and faDirectory) <> 0);
  353. end;
  354. {****************************************************************************
  355. Misc Functions
  356. ****************************************************************************}
  357. procedure Beep;
  358. begin
  359. _RingTheBell;
  360. end;
  361. {****************************************************************************
  362. Locale Functions
  363. ****************************************************************************}
  364. Procedure GetLocalTime(var SystemTime: TSystemTime);
  365. var xx : word;
  366. begin
  367. Dos.GetTime(SystemTime.Hour, SystemTime.Minute, SystemTime.Second, xx);
  368. Dos.GetDate(SystemTime.Year, SystemTime.Month, SystemTime.Day, xx);
  369. SystemTime.MilliSecond := 0;
  370. end;
  371. Procedure InitAnsi;
  372. Var i : longint;
  373. begin
  374. { Fill table entries 0 to 127 }
  375. for i := 0 to 96 do
  376. UpperCaseTable[i] := chr(i);
  377. for i := 97 to 122 do
  378. UpperCaseTable[i] := chr(i - 32);
  379. for i := 123 to 191 do
  380. UpperCaseTable[i] := chr(i);
  381. Move (CPISO88591UCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  382. for i := 0 to 64 do
  383. LowerCaseTable[i] := chr(i);
  384. for i := 65 to 90 do
  385. LowerCaseTable[i] := chr(i + 32);
  386. for i := 91 to 191 do
  387. LowerCaseTable[i] := chr(i);
  388. Move (CPISO88591LCT,UpperCaseTable[192],SizeOf(CPISO88591UCT));
  389. end;
  390. Procedure InitInternational;
  391. begin
  392. InitInternationalGeneric;
  393. InitAnsi;
  394. end;
  395. function SysErrorMessage(ErrorCode: Integer): String;
  396. begin
  397. Result:=''; // StrError(ErrorCode);
  398. end;
  399. {****************************************************************************
  400. OS utility functions
  401. ****************************************************************************}
  402. Function GetEnvironmentVariable(Const EnvVar : String) : String;
  403. begin
  404. Result:=StrPas(_getenv(PChar(EnvVar)));
  405. end;
  406. Function GetEnvironmentVariableCount : Integer;
  407. begin
  408. // Result:=FPCCountEnvVar(EnvP);
  409. Result:=0;
  410. end;
  411. Function GetEnvironmentString(Index : Integer) : String;
  412. begin
  413. // Result:=FPCGetEnvStrFromP(Envp,Index);
  414. Result:='';
  415. end;
  416. function ExecuteProcess(Const Path: AnsiString; Const ComLine: AnsiString;Flags:TExecuteFlags=[]):integer;
  417. var
  418. e : EOSError;
  419. CommandLine: AnsiString;
  420. begin
  421. dos.exec(path,comline);
  422. if (Dos.DosError <> 0) then
  423. begin
  424. if ComLine <> '' then
  425. CommandLine := Path + ' ' + ComLine
  426. else
  427. CommandLine := Path;
  428. e:=EOSError.CreateFmt(SExecuteProcessFailed,[CommandLine,Dos.DosError]);
  429. e.ErrorCode:=Dos.DosError;
  430. raise e;
  431. end;
  432. Result := DosExitCode;
  433. end;
  434. function ExecuteProcess (const Path: AnsiString;
  435. const ComLine: array of AnsiString;Flags:TExecuteFlags=[]): integer;
  436. var
  437. CommandLine: AnsiString;
  438. I: integer;
  439. begin
  440. Commandline := '';
  441. for I := 0 to High (ComLine) do
  442. if Pos (' ', ComLine [I]) <> 0 then
  443. CommandLine := CommandLine + ' ' + '"' + ComLine [I] + '"'
  444. else
  445. CommandLine := CommandLine + ' ' + Comline [I];
  446. ExecuteProcess := ExecuteProcess (Path, CommandLine);
  447. end;
  448. procedure Sleep(milliseconds: Cardinal);
  449. begin
  450. _delay (milliseconds);
  451. end;
  452. Function GetLastOSError : Integer;
  453. begin
  454. Result:=Integer(__get_errno_ptr^);
  455. end;
  456. {****************************************************************************
  457. Initialization code
  458. ****************************************************************************}
  459. Initialization
  460. InitExceptions; { Initialize exceptions. OS independent }
  461. InitInternational; { Initialize internationalization settings }
  462. Finalization
  463. DoneExceptions;
  464. end.