sysutils.pp 15 KB

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