dos.pp 20 KB

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