sysutils.pp 14 KB

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