dos.pp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  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. { According to tdos2 test it should return 18
  553. if ErrNo=Sys_ENOENT then
  554. DosError:=3
  555. else }
  556. DosError:=18;
  557. end;
  558. f.DirPtr:=0;
  559. f.SearchType:=1;
  560. f.searchnum:=-1;
  561. end
  562. else
  563. {Find Entry}
  564. begin
  565. Inc(CurrSearchNum);
  566. f.SearchNum:=CurrSearchNum;
  567. f.SearchType:=0;
  568. FindNext(f);
  569. end;
  570. End;
  571. {******************************************************************************
  572. --- File ---
  573. ******************************************************************************}
  574. Procedure FSplit(Path: PathStr; Var Dir: DirStr; Var Name: NameStr;Var Ext: ExtStr);
  575. Begin
  576. Unix.FSplit(Path,Dir,Name,Ext);
  577. End;
  578. Function FExpand(Const Path: PathStr): PathStr;
  579. Begin
  580. FExpand:=Unix.FExpand(Path);
  581. End;
  582. Function FSearch(path : pathstr;dirlist : string) : pathstr;
  583. Var
  584. info:stat;
  585. Begin
  586. if (length(Path)>0) and (path[1]='/') and FStat(path,info) then
  587. FSearch:=path
  588. else
  589. FSearch:=Unix.FSearch(path,dirlist);
  590. End;
  591. Procedure GetFAttr(var f; var attr : word);
  592. Var
  593. info : stat;
  594. LinAttr : longint;
  595. Begin
  596. DosError:=0;
  597. if not FStat(strpas(@textrec(f).name),info) then
  598. begin
  599. Attr:=0;
  600. DosError:=3;
  601. exit;
  602. end
  603. else
  604. LinAttr:=Info.Mode;
  605. if S_ISDIR(LinAttr) then
  606. Attr:=$10
  607. else
  608. Attr:=$20;
  609. if not Access(strpas(@textrec(f).name),W_OK) then
  610. Attr:=Attr or $1;
  611. if (not S_ISDIR(LinAttr)) and (filerec(f).name[0]='.') then
  612. Attr:=Attr or $2;
  613. end;
  614. Procedure getftime (var f; var time : longint);
  615. Var
  616. Info: stat;
  617. DT: DateTime;
  618. Begin
  619. doserror:=0;
  620. if not fstat(filerec(f).handle,info) then
  621. begin
  622. Time:=0;
  623. doserror:=6;
  624. exit
  625. end
  626. else
  627. UnixDateToDT(Info.mTime,DT);
  628. PackTime(DT,Time);
  629. End;
  630. {******************************************************************************
  631. --- Environment ---
  632. ******************************************************************************}
  633. Function EnvCount: Longint;
  634. var
  635. envcnt : longint;
  636. p : ppchar;
  637. Begin
  638. envcnt:=0;
  639. p:=envp; {defined in syslinux}
  640. while (p^<>nil) do
  641. begin
  642. inc(envcnt);
  643. inc(p);
  644. end;
  645. EnvCount := envcnt
  646. End;
  647. Function EnvStr(Index: Integer): String;
  648. Var
  649. i : longint;
  650. p : ppchar;
  651. Begin
  652. p:=envp; {defined in syslinux}
  653. i:=1;
  654. while (i<Index) and (p^<>nil) do
  655. begin
  656. inc(i);
  657. inc(p);
  658. end;
  659. if p=nil then
  660. envstr:=''
  661. else
  662. envstr:=strpas(p^)
  663. End;
  664. Function GetEnv(EnvVar: String): String;
  665. var
  666. p : pchar;
  667. Begin
  668. p:=Unix.GetEnv(EnvVar);
  669. if p=nil then
  670. GetEnv:=''
  671. else
  672. GetEnv:=StrPas(p);
  673. End;
  674. {******************************************************************************
  675. --- Do Nothing Procedures/Functions ---
  676. ******************************************************************************}
  677. Procedure Intr (intno: byte; var regs: registers);
  678. Begin
  679. {! No Linux equivalent !}
  680. End;
  681. Procedure msdos(var regs : registers);
  682. Begin
  683. {! No Linux equivalent !}
  684. End;
  685. Procedure getintvec(intno : byte;var vector : pointer);
  686. Begin
  687. {! No Linux equivalent !}
  688. End;
  689. Procedure setintvec(intno : byte;vector : pointer);
  690. Begin
  691. {! No Linux equivalent !}
  692. End;
  693. Procedure SwapVectors;
  694. Begin
  695. {! No Linux equivalent !}
  696. End;
  697. Procedure keep(exitcode : word);
  698. Begin
  699. {! No Linux equivalent !}
  700. End;
  701. Procedure setftime(var f; time : longint);
  702. Var
  703. utim: utimbuf;
  704. DT: DateTime;
  705. path: pathstr;
  706. index: Integer;
  707. Begin
  708. doserror:=0;
  709. with utim do
  710. begin
  711. actime:=getepochtime;
  712. UnPackTime(Time,DT);
  713. modtime:=DTToUnixDate(DT);
  714. end;
  715. for Index:=0 to FilerecNameLength-1 do
  716. path[Index+1]:=filerec(f).name[Index];
  717. if not utime(path,utim) then
  718. begin
  719. Time:=0;
  720. doserror:=3;
  721. end;
  722. End;
  723. Procedure setfattr (var f;attr : word);
  724. Begin
  725. {! No Linux equivalent !}
  726. { Fail for setting VolumeId }
  727. if (attr and VolumeID)<>0 then
  728. doserror:=5;
  729. End;
  730. Procedure GetCBreak(Var BreakValue: Boolean);
  731. Begin
  732. {! No Linux equivalent !}
  733. breakvalue:=true
  734. End;
  735. Procedure SetCBreak(BreakValue: Boolean);
  736. Begin
  737. {! No Linux equivalent !}
  738. End;
  739. Procedure GetVerify(Var Verify: Boolean);
  740. Begin
  741. {! No Linux equivalent !}
  742. Verify:=true;
  743. End;
  744. Procedure SetVerify(Verify: Boolean);
  745. Begin
  746. {! No Linux equivalent !}
  747. End;
  748. {******************************************************************************
  749. --- Initialization ---
  750. ******************************************************************************}
  751. End.
  752. {
  753. $Log$
  754. Revision 1.13 2002-12-08 16:05:34 peter
  755. * small error code fixes so tdos2 passes
  756. Revision 1.12 2002/09/07 16:01:27 peter
  757. * old logs removed and tabs fixed
  758. }