dos.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt and Peter Vreman,
  5. members of the Free Pascal development team
  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 Dos;
  13. Interface
  14. Const
  15. {Max FileName Length for files}
  16. FileNameLen=255;
  17. {Bitmasks for CPU Flags}
  18. fcarry = $0001;
  19. fparity = $0004;
  20. fauxiliary = $0010;
  21. fzero = $0040;
  22. fsign = $0080;
  23. foverflow = $0800;
  24. {Bitmasks for file attribute}
  25. readonly = $01;
  26. hidden = $02;
  27. sysfile = $04;
  28. volumeid = $08;
  29. directory = $10;
  30. archive = $20;
  31. anyfile = $3F;
  32. {File Status}
  33. fmclosed = $D7B0;
  34. fminput = $D7B1;
  35. fmoutput = $D7B2;
  36. fminout = $D7B3;
  37. Type
  38. ComStr = String[FileNameLen];
  39. PathStr = String[FileNameLen];
  40. DirStr = String[FileNameLen];
  41. NameStr = String[FileNameLen];
  42. ExtStr = String[FileNameLen];
  43. SearchRec = packed Record
  44. {Fill : array[1..21] of byte; Fill replaced with below}
  45. SearchNum : LongInt; {to track which search this is}
  46. SearchPos : LongInt; {directory position}
  47. DirPtr : LongInt; {directory pointer for reading directory}
  48. SearchType : Byte; {0=normal, 1=open will close, 2=only 1 file}
  49. SearchAttr : Byte; {attribute we are searching for}
  50. Fill : Array[1..07] of Byte; {future use}
  51. {End of fill}
  52. Attr : Byte; {attribute of found file}
  53. Time : LongInt; {last modify date of found file}
  54. Size : LongInt; {file size of found file}
  55. Reserved : Word; {future use}
  56. Name : String[FileNameLen]; {name of found file}
  57. SearchSpec : String[FileNameLen]; {search pattern}
  58. NamePos : Word; {end of path, start of name position}
  59. End;
  60. {
  61. filerec.inc contains the definition of the filerec.
  62. textrec.inc contains the definition of the textrec.
  63. It is in a separate file to make it available in other units without
  64. having to use the DOS unit for it.
  65. }
  66. {$i filerec.inc}
  67. {$i textrec.inc}
  68. Registers = packed record
  69. case i : integer of
  70. 0 : (ax,f1,bx,f2,cx,f3,dx,f4,bp,f5,si,f51,di,f6,ds,f7,es,f8,flags,fs,gs : word);
  71. 1 : (al,ah,f9,f10,bl,bh,f11,f12,cl,ch,f13,f14,dl,dh : byte);
  72. 2 : (eax, ebx, ecx, edx, ebp, esi, edi : longint);
  73. End;
  74. DateTime = packed record
  75. Year,
  76. Month,
  77. Day,
  78. Hour,
  79. Min,
  80. Sec : word;
  81. End;
  82. Var
  83. DosError : integer;
  84. {Utils}
  85. function weekday(y,m,d : longint) : longint;
  86. Procedure UnixDateToDt(SecsPast: LongInt; Var Dt: DateTime);
  87. Function DTToUnixDate(DT: DateTime): LongInt;
  88. {Info/Date/Time}
  89. Function DosVersion: Word;
  90. Procedure GetDate(var year, month, mday, wday: word);
  91. Procedure GetTime(var hour, minute, second, sec100: word);
  92. procedure SetDate(year,month,day: word);
  93. Procedure SetTime(hour,minute,second,sec100: word);
  94. Procedure UnpackTime(p: longint; var t: datetime);
  95. Procedure PackTime(var t: datetime; var p: longint);
  96. {Exec}
  97. Procedure Exec(const path: pathstr; const comline: comstr);
  98. Function DosExitCode: word;
  99. {Disk}
  100. Procedure AddDisk(const path:string);
  101. Function DiskFree(drive: byte) : int64;
  102. Function DiskSize(drive: byte) : int64;
  103. Procedure FindFirst(const path: pathstr; attr: word; var f: searchRec);
  104. Procedure FindNext(var f: searchRec);
  105. Procedure FindClose(Var f: SearchRec);
  106. {File}
  107. Procedure GetFAttr(var f; var attr: word);
  108. Procedure GetFTime(var f; var time: longint);
  109. Function FSearch(path: pathstr; dirlist: string): pathstr;
  110. Function FExpand(const path: pathstr): pathstr;
  111. Procedure FSplit(path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  112. {Environment}
  113. Function EnvCount: longint;
  114. Function EnvStr(index: integer): string;
  115. Function GetEnv (envvar: string): string;
  116. {Do Nothing Functions, no Linux version}
  117. Procedure Intr(intno: byte; var regs: registers);
  118. Procedure MSDos(var regs: registers);
  119. Procedure SwapVectors;
  120. Procedure GetIntVec(intno: byte; var vector: pointer);
  121. Procedure SetIntVec(intno: byte; vector: pointer);
  122. Procedure Keep(exitcode: word);
  123. Procedure SetFAttr(var f; attr: word);
  124. Procedure SetFTime(var f; time: longint);
  125. Procedure GetCBreak(var breakvalue: boolean);
  126. Procedure SetCBreak(breakvalue: boolean);
  127. Procedure GetVerify(var verify: boolean);
  128. Procedure SetVerify(verify: boolean);
  129. Implementation
  130. Uses
  131. Strings,Unix;
  132. {******************************************************************************
  133. --- Link C Lib if set ---
  134. ******************************************************************************}
  135. type
  136. RtlInfoType = Record
  137. FMode,
  138. FInode,
  139. FUid,
  140. FGid,
  141. FSize,
  142. FMTime : LongInt;
  143. End;
  144. {******************************************************************************
  145. --- Info / Date / Time ---
  146. ******************************************************************************}
  147. Const
  148. {Date Calculation}
  149. C1970 = 2440588;
  150. D0 = 1461;
  151. D1 = 146097;
  152. D2 = 1721119;
  153. type
  154. GTRec = packed Record
  155. Year,
  156. Month,
  157. MDay,
  158. WDay,
  159. Hour,
  160. Minute,
  161. Second : Word;
  162. End;
  163. Function DosVersion:Word;
  164. Var
  165. Buffer : Array[0..255] of Char;
  166. Tmp2,
  167. TmpStr : String[40];
  168. TmpPos,
  169. SubRel,
  170. Rel : LongInt;
  171. info : utsname;
  172. Begin
  173. {$IFNDEF BSD}
  174. UName(info);
  175. Move(info.release,buffer[0],40);
  176. TmpStr:=StrPas(Buffer);
  177. {$ELSE}
  178. TmpStr:='FreeBSD doesn''t support UName';
  179. {$ENDIF}
  180. SubRel:=0;
  181. TmpPos:=Pos('.',TmpStr);
  182. if TmpPos>0 then
  183. begin
  184. Tmp2:=Copy(TmpStr,TmpPos+1,40);
  185. Delete(TmpStr,TmpPos,40);
  186. end;
  187. TmpPos:=Pos('.',Tmp2);
  188. if TmpPos>0 then
  189. Delete(Tmp2,TmpPos,40);
  190. Val(TmpStr,Rel);
  191. Val(Tmp2,SubRel);
  192. DosVersion:=Rel+(SubRel shl 8);
  193. End;
  194. function WeekDay (y,m,d:longint):longint;
  195. {
  196. Calculates th day of the week. returns -1 on error
  197. }
  198. var
  199. u,v : longint;
  200. begin
  201. if (m<1) or (m>12) or (y<1600) or (y>4000) or
  202. (d<1) or (d>30+((m+ord(m>7)) and 1)-ord(m=2)) or
  203. ((m*d=58) and (((y mod 4>0) or (y mod 100=0)) and (y mod 400>0))) then
  204. WeekDay:=-1
  205. else
  206. begin
  207. u:=m;
  208. v:=y;
  209. if m<3 then
  210. begin
  211. inc(u,12);
  212. dec(v);
  213. end;
  214. WeekDay:=(d+2*u+((3*(u+1)) div 5)+v+(v div 4)-(v div 100)+(v div 400)+1) mod 7;
  215. end;
  216. end;
  217. Procedure GetDate(Var Year, Month, MDay, WDay: Word);
  218. Begin
  219. Unix.GetDate(Year,Month,MDay);
  220. Wday:=weekday(Year,Month,MDay);
  221. end;
  222. Procedure SetDate(Year, Month, Day: Word);
  223. Begin
  224. Unix.SetDate ( Year, Month, Day );
  225. End;
  226. Procedure GetTime(Var Hour, Minute, Second, Sec100: Word);
  227. Begin
  228. Unix.GetTime(Hour,Minute,Second,Sec100);
  229. end;
  230. Procedure SetTime(Hour, Minute, Second, Sec100: Word);
  231. Begin
  232. Unix.SetTime ( Hour, Minute, Second );
  233. End;
  234. Procedure packtime(var t : datetime;var p : longint);
  235. Begin
  236. p:=(t.sec shr 1)+(t.min shl 5)+(t.hour shl 11)+(t.day shl 16)+(t.month shl 21)+((t.year-1980) shl 25);
  237. End;
  238. Procedure unpacktime(p : longint;var t : datetime);
  239. Begin
  240. t.sec:=(p and 31) shl 1;
  241. t.min:=(p shr 5) and 63;
  242. t.hour:=(p shr 11) and 31;
  243. t.day:=(p shr 16) and 31;
  244. t.month:=(p shr 21) and 15;
  245. t.year:=(p shr 25)+1980;
  246. End;
  247. Procedure UnixDateToDt(SecsPast: LongInt; Var Dt: DateTime);
  248. Begin
  249. EpochToLocal(SecsPast,dt.Year,dt.Month,dt.Day,dt.Hour,dt.Min,dt.Sec);
  250. End;
  251. Function DTToUnixDate(DT: DateTime): LongInt;
  252. Begin
  253. DTToUnixDate:=LocalToEpoch(dt.Year,dt.Month,dt.Day,dt.Hour,dt.Min,dt.Sec);
  254. End;
  255. {******************************************************************************
  256. --- Exec ---
  257. ******************************************************************************}
  258. var
  259. LastDosExitCode: word;
  260. Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
  261. var
  262. pid : longint;
  263. // The Error-Checking in the previous Version failed, since halt($7F) gives an WaitPid-status of $7F00
  264. Begin
  265. LastDosExitCode:=0;
  266. pid:=Fork;
  267. if pid=0 then
  268. begin
  269. {The child does the actual exec, and then exits}
  270. if ComLine='' then
  271. Execl(Path)
  272. else
  273. Execl(Path+' '+ComLine);
  274. {If the execve fails, we return an exitvalue of 127, to let it be known}
  275. ExitProcess(127);
  276. end
  277. else
  278. if pid=-1 then {Fork failed}
  279. begin
  280. DosError:=8;
  281. exit
  282. end;
  283. {We're in the parent, let's wait.}
  284. LastDosExitCode:=WaitProcess(pid); // WaitPid and result-convert
  285. if (LastDosExitCode>=0) and (LastDosExitCode<>127) then
  286. DosError:=0
  287. else
  288. DosError:=8; // perhaps one time give an better error
  289. End;
  290. Function DosExitCode: Word;
  291. Begin
  292. DosExitCode:=LastDosExitCode;
  293. End;
  294. {******************************************************************************
  295. --- Disk ---
  296. ******************************************************************************}
  297. {
  298. The Diskfree and Disksize functions need a file on the specified drive, since this
  299. is required for the statfs system call.
  300. These filenames are set in drivestr[0..26], and have been preset to :
  301. 0 - '.' (default drive - hence current dir is ok.)
  302. 1 - '/fd0/.' (floppy drive 1 - should be adapted to local system )
  303. 2 - '/fd1/.' (floppy drive 2 - should be adapted to local system )
  304. 3 - '/' (C: equivalent of dos is the root partition)
  305. 4..26 (can be set by you're own applications)
  306. ! Use AddDisk() to Add new drives !
  307. They both return -1 when a failure occurs.
  308. }
  309. Const
  310. FixDriveStr : array[0..3] of pchar=(
  311. '.',
  312. '/fd0/.',
  313. '/fd1/.',
  314. '/.'
  315. );
  316. const
  317. Drives : byte = 4;
  318. var
  319. DriveStr : array[4..26] of pchar;
  320. Procedure AddDisk(const path:string);
  321. begin
  322. if not (DriveStr[Drives]=nil) then
  323. FreeMem(DriveStr[Drives],StrLen(DriveStr[Drives])+1);
  324. GetMem(DriveStr[Drives],length(Path)+1);
  325. StrPCopy(DriveStr[Drives],path);
  326. inc(Drives);
  327. if Drives>26 then
  328. Drives:=4;
  329. end;
  330. Function DiskFree(Drive: Byte): int64;
  331. var
  332. fs : tstatfs;
  333. Begin
  334. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and StatFS(StrPas(fixdrivestr[drive]),fs)) or
  335. ((not (drivestr[Drive]=nil)) and StatFS(StrPas(drivestr[drive]),fs)) then
  336. Diskfree:=int64(fs.bavail)*int64(fs.bsize)
  337. else
  338. Diskfree:=-1;
  339. End;
  340. Function DiskSize(Drive: Byte): int64;
  341. var
  342. fs : tstatfs;
  343. Begin
  344. if ((Drive<4) and (not (fixdrivestr[Drive]=nil)) and StatFS(StrPas(fixdrivestr[drive]),fs)) or
  345. ((not (drivestr[Drive]=nil)) and StatFS(StrPas(drivestr[drive]),fs)) then
  346. DiskSize:=int64(fs.blocks)*int64(fs.bsize)
  347. else
  348. DiskSize:=-1;
  349. End;
  350. {******************************************************************************
  351. --- Findfirst FindNext ---
  352. ******************************************************************************}
  353. Const
  354. RtlFindSize = 15;
  355. Type
  356. RtlFindRecType = Record
  357. SearchNum,
  358. DirPtr,
  359. LastUsed : LongInt;
  360. End;
  361. Var
  362. RtlFindRecs : Array[1..RtlFindSize] of RtlFindRecType;
  363. CurrSearchNum : LongInt;
  364. Procedure FindClose(Var f: SearchRec);
  365. {
  366. Closes dirptr if it is open
  367. }
  368. Var
  369. i : longint;
  370. Begin
  371. if f.SearchType=0 then
  372. begin
  373. i:=1;
  374. repeat
  375. if (RtlFindRecs[i].SearchNum=f.SearchNum) then
  376. break;
  377. inc(i);
  378. until (i>RtlFindSize);
  379. If i<=RtlFindSize Then
  380. Begin
  381. RtlFindRecs[i].SearchNum:=0;
  382. if f.dirptr<>0 then
  383. closedir(pdir(f.dirptr));
  384. End;
  385. end;
  386. f.dirptr:=0;
  387. End;
  388. Function FindGetFileInfo(const s:string;var f:SearchRec):boolean;
  389. var
  390. DT : DateTime;
  391. Info : RtlInfoType;
  392. st : stat;
  393. begin
  394. FindGetFileInfo:=false;
  395. if not Fstat(s,st) then
  396. exit;
  397. info.FSize:=st.Size;
  398. info.FMTime:=st.mtime;
  399. if (st.mode and STAT_IFMT)=STAT_IFDIR then
  400. info.fmode:=$10
  401. else
  402. info.fmode:=$20;
  403. if (st.mode and STAT_IWUSR)=0 then
  404. info.fmode:=info.fmode or 1;
  405. If ((Info.FMode and Not(f.searchattr))=0) Then
  406. Begin
  407. f.Name:=Copy(s,f.NamePos+1,255);
  408. f.Attr:=Info.FMode;
  409. f.Size:=Info.FSize;
  410. UnixDateToDT(Info.FMTime, DT);
  411. PackTime(DT,f.Time);
  412. FindGetFileInfo:=true;
  413. End;
  414. end;
  415. Function FindLastUsed: Longint;
  416. {
  417. Find unused or least recently used dirpointer slot in findrecs array
  418. }
  419. Var
  420. BestMatch,i : Longint;
  421. Found : Boolean;
  422. Begin
  423. BestMatch:=1;
  424. i:=1;
  425. Found:=False;
  426. While (i <= RtlFindSize) And (Not Found) Do
  427. Begin
  428. If (RtlFindRecs[i].SearchNum = 0) Then
  429. Begin
  430. BestMatch := i;
  431. Found := True;
  432. End
  433. Else
  434. Begin
  435. If RtlFindRecs[i].LastUsed > RtlFindRecs[BestMatch].LastUsed Then
  436. BestMatch := i;
  437. End;
  438. Inc(i);
  439. End;
  440. FindLastUsed := BestMatch;
  441. End;
  442. Procedure FindNext(Var f: SearchRec);
  443. {
  444. re-opens dir if not already in array and calls FindWorkProc
  445. }
  446. Var
  447. DirName : Array[0..256] of Char;
  448. i,
  449. ArrayPos : Longint;
  450. FName,
  451. SName : string;
  452. Found,
  453. Finished : boolean;
  454. p : PDirEnt;
  455. Begin
  456. If f.SearchType=0 Then
  457. Begin
  458. ArrayPos:=0;
  459. For i:=1 to RtlFindSize Do
  460. Begin
  461. If RtlFindRecs[i].SearchNum = f.SearchNum Then
  462. ArrayPos:=i;
  463. Inc(RtlFindRecs[i].LastUsed);
  464. End;
  465. If ArrayPos=0 Then
  466. Begin
  467. If f.NamePos = 0 Then
  468. Begin
  469. DirName[0] := '.';
  470. DirName[1] := '/';
  471. DirName[2] := #0;
  472. End
  473. Else
  474. Begin
  475. Move(f.SearchSpec[1], DirName[0], f.NamePos);
  476. DirName[f.NamePos] := #0;
  477. End;
  478. f.DirPtr := longint(opendir(@(DirName)));
  479. If f.DirPtr <> 0 Then
  480. begin
  481. ArrayPos:=FindLastUsed;
  482. If RtlFindRecs[ArrayPos].SearchNum > 0 Then
  483. CloseDir(pdir(rtlfindrecs[arraypos].dirptr));
  484. RtlFindRecs[ArrayPos].SearchNum := f.SearchNum;
  485. RtlFindRecs[ArrayPos].DirPtr := f.DirPtr;
  486. if f.searchpos>0 then
  487. seekdir(pdir(f.dirptr), f.searchpos);
  488. end;
  489. End;
  490. if ArrayPos>0 then
  491. RtlFindRecs[ArrayPos].LastUsed:=0;
  492. end;
  493. {Main loop}
  494. SName:=Copy(f.SearchSpec,f.NamePos+1,255);
  495. Found:=False;
  496. Finished:=(f.dirptr=0);
  497. While Not Finished Do
  498. Begin
  499. p:=readdir(pdir(f.dirptr));
  500. if p=nil then
  501. FName:=''
  502. else
  503. FName:=Strpas(@p^.name);
  504. If FName='' Then
  505. Finished:=True
  506. Else
  507. Begin
  508. If FNMatch(SName,FName) Then
  509. Begin
  510. Found:=FindGetFileInfo(Copy(f.SearchSpec,1,f.NamePos)+FName,f);
  511. if Found then
  512. Finished:=true;
  513. End;
  514. End;
  515. End;
  516. {Shutdown}
  517. If Found Then
  518. Begin
  519. f.searchpos:=telldir(pdir(f.dirptr));
  520. DosError:=0;
  521. End
  522. Else
  523. Begin
  524. FindClose(f);
  525. DosError:=18;
  526. End;
  527. End;
  528. Procedure FindFirst(Const Path: PathStr; Attr: Word; Var f: SearchRec);
  529. {
  530. opens dir and calls FindWorkProc
  531. }
  532. Begin
  533. if Path='' then
  534. begin
  535. DosError:=3;
  536. exit;
  537. end;
  538. {Create Info}
  539. f.SearchSpec := Path;
  540. f.SearchAttr := Attr;
  541. f.SearchPos := 0;
  542. f.NamePos := Length(f.SearchSpec);
  543. while (f.NamePos>0) and (f.SearchSpec[f.NamePos]<>'/') do
  544. dec(f.NamePos);
  545. {Wildcards?}
  546. if (Pos('?',Path)=0) and (Pos('*',Path)=0) then
  547. begin
  548. if FindGetFileInfo(Path,f) then
  549. DosError:=0
  550. else
  551. begin
  552. if ErrNo=Sys_ENOENT then
  553. DosError:=3
  554. else
  555. DosError:=18;
  556. end;
  557. f.DirPtr:=0;
  558. f.SearchType:=1;
  559. f.searchnum:=-1;
  560. end
  561. else
  562. {Find Entry}
  563. begin
  564. Inc(CurrSearchNum);
  565. f.SearchNum:=CurrSearchNum;
  566. f.SearchType:=0;
  567. FindNext(f);
  568. end;
  569. End;
  570. {******************************************************************************
  571. --- File ---
  572. ******************************************************************************}
  573. Procedure FSplit(Path: PathStr; Var Dir: DirStr; Var Name: NameStr;Var Ext: ExtStr);
  574. Begin
  575. Unix.FSplit(Path,Dir,Name,Ext);
  576. End;
  577. Function FExpand(Const Path: PathStr): PathStr;
  578. Begin
  579. FExpand:=Unix.FExpand(Path);
  580. End;
  581. Function FSearch(path : pathstr;dirlist : string) : pathstr;
  582. Var
  583. info:stat;
  584. Begin
  585. if (length(Path)>0) and (path[1]='/') and FStat(path,info) then
  586. FSearch:=path
  587. else
  588. FSearch:=Unix.FSearch(path,dirlist);
  589. End;
  590. Procedure GetFAttr(var f; var attr : word);
  591. Var
  592. info : stat;
  593. LinAttr : longint;
  594. Begin
  595. DosError:=0;
  596. if not FStat(strpas(@textrec(f).name),info) then
  597. begin
  598. Attr:=0;
  599. DosError:=3;
  600. exit;
  601. end
  602. else
  603. LinAttr:=Info.Mode;
  604. if S_ISDIR(LinAttr) then
  605. Attr:=$10
  606. else
  607. Attr:=$20;
  608. if not Access(strpas(@textrec(f).name),W_OK) then
  609. Attr:=Attr or $1;
  610. if (not S_ISDIR(LinAttr)) and (filerec(f).name[0]='.') then
  611. Attr:=Attr or $2;
  612. end;
  613. Procedure getftime (var f; var time : longint);
  614. Var
  615. Info: stat;
  616. DT: DateTime;
  617. Begin
  618. doserror:=0;
  619. if not fstat(filerec(f).handle,info) then
  620. begin
  621. Time:=0;
  622. doserror:=3;
  623. exit
  624. end
  625. else
  626. UnixDateToDT(Info.mTime,DT);
  627. PackTime(DT,Time);
  628. End;
  629. {******************************************************************************
  630. --- Environment ---
  631. ******************************************************************************}
  632. Function EnvCount: Longint;
  633. var
  634. envcnt : longint;
  635. p : ppchar;
  636. Begin
  637. envcnt:=0;
  638. p:=envp; {defined in syslinux}
  639. while (p^<>nil) do
  640. begin
  641. inc(envcnt);
  642. inc(p);
  643. end;
  644. EnvCount := envcnt
  645. End;
  646. Function EnvStr(Index: Integer): String;
  647. Var
  648. i : longint;
  649. p : ppchar;
  650. Begin
  651. p:=envp; {defined in syslinux}
  652. i:=1;
  653. while (i<Index) and (p^<>nil) do
  654. begin
  655. inc(i);
  656. inc(p);
  657. end;
  658. if p=nil then
  659. envstr:=''
  660. else
  661. envstr:=strpas(p^)
  662. End;
  663. Function GetEnv(EnvVar: String): String;
  664. var
  665. p : pchar;
  666. Begin
  667. p:=Unix.GetEnv(EnvVar);
  668. if p=nil then
  669. GetEnv:=''
  670. else
  671. GetEnv:=StrPas(p);
  672. End;
  673. {******************************************************************************
  674. --- Do Nothing Procedures/Functions ---
  675. ******************************************************************************}
  676. Procedure Intr (intno: byte; var regs: registers);
  677. Begin
  678. {! No Linux equivalent !}
  679. End;
  680. Procedure msdos(var regs : registers);
  681. Begin
  682. {! No Linux equivalent !}
  683. End;
  684. Procedure getintvec(intno : byte;var vector : pointer);
  685. Begin
  686. {! No Linux equivalent !}
  687. End;
  688. Procedure setintvec(intno : byte;vector : pointer);
  689. Begin
  690. {! No Linux equivalent !}
  691. End;
  692. Procedure SwapVectors;
  693. Begin
  694. {! No Linux equivalent !}
  695. End;
  696. Procedure keep(exitcode : word);
  697. Begin
  698. {! No Linux equivalent !}
  699. End;
  700. Procedure setftime(var f; time : longint);
  701. Begin
  702. {! No Linux equivalent !}
  703. End;
  704. Procedure setfattr (var f;attr : word);
  705. Begin
  706. {! No Linux equivalent !}
  707. End;
  708. Procedure GetCBreak(Var BreakValue: Boolean);
  709. Begin
  710. {! No Linux equivalent !}
  711. breakvalue:=true
  712. End;
  713. Procedure SetCBreak(BreakValue: Boolean);
  714. Begin
  715. {! No Linux equivalent !}
  716. End;
  717. Procedure GetVerify(Var Verify: Boolean);
  718. Begin
  719. {! No Linux equivalent !}
  720. Verify:=true;
  721. End;
  722. Procedure SetVerify(Verify: Boolean);
  723. Begin
  724. {! No Linux equivalent !}
  725. End;
  726. {******************************************************************************
  727. --- Initialization ---
  728. ******************************************************************************}
  729. End.
  730. {
  731. $Log$
  732. Revision 1.10 2001-09-22 11:17:13 peter
  733. * Fixed passing of command without parameters to Exec() to not include
  734. a space after the executable name
  735. Revision 1.9 2001/07/30 21:38:55 peter
  736. * m68k updates merged
  737. Revision 1.8 2001/07/12 12:42:39 marco
  738. * Fixes to the FreeBSD compability of the datetime patches
  739. Revision 1.7 2001/07/12 07:20:05 michael
  740. + Added setdate/time/datetime functions
  741. Revision 1.6 2001/06/03 20:19:09 peter
  742. * FSStat to StatFS
  743. * StatFS structure to TStatFS
  744. Revision 1.5 2001/06/02 00:31:30 peter
  745. * merge unix updates from the 1.0 branch, mostly related to the
  746. solaris target
  747. Revision 1.4 2001/05/06 14:23:21 peter
  748. * fixed adddisk
  749. Revision 1.3 2001/01/21 20:21:40 marco
  750. * Rename fest II. Rtl OK
  751. Revision 1.2 2000/09/18 13:14:50 marco
  752. * Global Linux +bsd to (rtl/freebsd rtl/unix rtl/linux structure)
  753. Revision 1.3 2000/07/14 10:33:10 michael
  754. + Conditionals fixed
  755. Revision 1.2 2000/07/13 11:33:48 michael
  756. + removed logs
  757. }