dos.pp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2004 by Olle Raab and
  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. Uses
  15. macostp;
  16. Const
  17. {Max PathName Length for files}
  18. FileNameLen=255;
  19. Type
  20. SearchRec = packed record
  21. Attr: Byte; {attribute of found file}
  22. Time: LongInt; {last modify date of found file}
  23. Size: LongInt; {file size of found file}
  24. Reserved: Word; {future use}
  25. Name: string[FileNameLen]; {name of foundfile}
  26. SearchSpec: string[FileNameLen]; {search pattern}
  27. NamePos: Word; {end of path,start of name position}
  28. {MacOS specific params, private, do not use:}
  29. paramBlock: CInfoPBRec;
  30. searchFSSpec: FSSpec;
  31. searchAttr: Byte; {attribute we are searching for}
  32. exactMatch: Boolean;
  33. end;
  34. {$i dosh.inc}
  35. Implementation
  36. {TODO Obtain disk size and disk free values for volumes > 2 GB.
  37. For this, PBXGetVolInfoSync can be used. However, this function
  38. is not available on older versions of Mac OS, so the function has
  39. to be weak linked. An alternative is to directly look into the VCB
  40. (Volume Control Block), but since this is on low leveel it is a
  41. compatibility risque.}
  42. {TODO Perhaps make SearchRec.paramBlock opaque, so that uses macostp;
  43. is not needed in the interface part.}
  44. {TODO Perhaps add some kind of "Procedure AddDisk" for accessing other
  45. volumes. At lest accessing the possible disk drives with
  46. driver number 1 and 2 should be easy.}
  47. {TODO Perhaps implement Exec with Apple Events, calling ToolServer.}
  48. {TODO Perhaps use LongDateTime for time functions. But the function
  49. calls must then be weak linked.}
  50. Uses
  51. macutils,
  52. unixutil {for FNMatch};
  53. function MacTimeToDosPackedTime(macfiletime: UInt32): Longint;
  54. var
  55. mdt: DateTimeRec; {Mac OS datastructure}
  56. ddt: Datetime; {Dos OS datastructure}
  57. dospackedtime: Longint;
  58. begin
  59. SecondsToDate(macfiletime, mdt);
  60. with ddt do
  61. begin
  62. year := mdt.year;
  63. month := mdt.month;
  64. day := mdt.day;
  65. hour := mdt.hour;
  66. min := mdt.minute;
  67. sec := mdt.second;
  68. end;
  69. Packtime(ddt, dospackedtime);
  70. MacTimeToDosPackedTime:= dospackedtime;
  71. end;
  72. {******************************************************************************
  73. --- Info / Date / Time ---
  74. ******************************************************************************}
  75. function DosVersion:Word;
  76. begin
  77. DosVersion:=
  78. (macosSystemVersion and $FF00) or
  79. ((macosSystemVersion and $00F0) shr 4);
  80. end;
  81. procedure GetDate (var year, month, mday, wday: word);
  82. var
  83. d: DateTimeRec;
  84. begin
  85. Macostp.GetTime(d);
  86. year := d.year;
  87. month := d.month;
  88. mday := d.day;
  89. wday := d.dayOfWeek - 1; {1-based on mac}
  90. end;
  91. procedure GetTime (var hour, minute, second, sec100: word);
  92. var
  93. d: DateTimeRec;
  94. begin
  95. Macostp.GetTime(d);
  96. hour := d.hour;
  97. minute := d.minute;
  98. second := d.second;
  99. sec100 := 0;
  100. end;
  101. procedure Packtime(var t : datetime;var p : longint);
  102. Begin
  103. 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);
  104. End;
  105. procedure Unpacktime(p : longint;var t : datetime);
  106. Begin
  107. t.sec:=(p and 31) shl 1;
  108. t.min:=(p shr 5) and 63;
  109. t.hour:=(p shr 11) and 31;
  110. t.day:=(p shr 16) and 31;
  111. t.month:=(p shr 21) and 15;
  112. t.year:=(p shr 25)+1980;
  113. End;
  114. Procedure SetDate(Year, Month, Day: Word);
  115. var
  116. d: DateTimeRec;
  117. Begin
  118. Macostp.GetTime(d);
  119. d.year := year;
  120. d.month := month;
  121. d.day := day;
  122. Macostp.SetTime(d)
  123. End;
  124. Procedure SetTime(Hour, Minute, Second, Sec100: Word);
  125. var
  126. d: DateTimeRec;
  127. Begin
  128. Macostp.GetTime(d);
  129. d.hour := hour;
  130. d.minute := minute;
  131. d.second := second;
  132. Macostp.SetTime(d)
  133. End;
  134. {******************************************************************************
  135. --- Exec ---
  136. ******************************************************************************}
  137. Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
  138. Begin
  139. DosError:=8; //TODO A better error sometime
  140. End;
  141. Function DosExitCode: Word;
  142. Begin
  143. DosExitCode := 3; //Indicate failure TODO a better error sometime.
  144. End;
  145. {******************************************************************************
  146. --- Disk ---
  147. ******************************************************************************}
  148. {If drive is 0 the free space on the volume of the working directory is returned.
  149. If drive is 1 or 2, the free space on the first or second floppy disk is returned.
  150. If drive is 3 the free space on the boot volume is returned.
  151. If the free space is > 2 GB, then 2 GB is reported.}
  152. Function DiskFree(drive: Byte): Int64;
  153. var
  154. myHPB: HParamBlockRec;
  155. myErr: OSErr;
  156. begin
  157. myHPB.ioNamePtr := NIL;
  158. myHPB.ioVolIndex := 0;
  159. case drive of
  160. 0: myHPB.ioVRefNum := GetWorkingDirectoryVRefNum;
  161. 1: myHPB.ioVRefNum := 1;
  162. 2: myHPB.ioVRefNum := 2;
  163. 3: myHPB.ioVRefNum := macosBootVolumeVRefNum;
  164. else
  165. begin
  166. Diskfree:= -1;
  167. Exit;
  168. end;
  169. end;
  170. myErr := PBHGetVInfoSync(@myHPB);
  171. if myErr = noErr then
  172. Diskfree := myHPB.ioVAlBlkSiz * myHPB.ioVFrBlk
  173. else
  174. Diskfree:= -1;
  175. End;
  176. {If drive is 0 the size of the volume of the working directory is returned.
  177. If drive is 1 or 2, the size of the first or second floppy disk is returned.
  178. If drive is 3 the size of the boot volume is returned.
  179. If the actual size is > 2 GB, then 2 GB is reported.}
  180. Function DiskSize(drive: Byte): Int64;
  181. var
  182. myHPB: HParamBlockRec;
  183. myErr: OSErr;
  184. Begin
  185. myHPB.ioNamePtr := NIL;
  186. myHPB.ioVolIndex := 0;
  187. case drive of
  188. 0: myHPB.ioVRefNum := GetWorkingDirectoryVRefNum;
  189. 1: myHPB.ioVRefNum := 1;
  190. 2: myHPB.ioVRefNum := 2;
  191. 3: myHPB.ioVRefNum := macosBootVolumeVRefNum;
  192. else
  193. begin
  194. DiskSize:= -1;
  195. Exit;
  196. end;
  197. end;
  198. myErr := PBHGetVInfoSync(@myHPB);
  199. if myErr = noErr then
  200. DiskSize := myHPB.ioVAlBlkSiz * myHPB.ioVNmAlBlks
  201. else
  202. DiskSize:=-1;
  203. End;
  204. {******************************************************************************
  205. --- Findfirst FindNext ---
  206. ******************************************************************************}
  207. (*
  208. {The one defined in Unixutils.pp is used instead}
  209. function FNMatch (const Pattern, Name: string): Boolean;
  210. var
  211. LenPat, LenName: longint;
  212. function DoFNMatch (i, j: longint): Boolean;
  213. var
  214. Found: boolean;
  215. begin
  216. Found := true;
  217. while Found and (i <= LenPat) do
  218. begin
  219. case Pattern[i] of
  220. '?':
  221. Found := (j <= LenName);
  222. '*':
  223. begin
  224. {find the next character in pattern, different of ? and *}
  225. while Found and (i < LenPat) do
  226. begin
  227. i := i + 1;
  228. case Pattern[i] of
  229. '*':
  230. ;
  231. '?':
  232. begin
  233. j := j + 1;
  234. Found := (j <= LenName);
  235. end;
  236. otherwise
  237. Found := false;
  238. end;
  239. end;
  240. {Now, find in name the character which i points to, if the * or ?}
  241. {wasn 't the last character in the pattern, else, use up all the}
  242. {chars in name }
  243. Found := true;
  244. if (i <= LenPat) then
  245. begin
  246. repeat
  247. {find a letter (not only first !) which maches pattern[i]}
  248. while (j <= LenName) and (name[j] <> pattern[i]) do
  249. j := j + 1;
  250. if (j < LenName) then
  251. begin
  252. if DoFnMatch(i + 1, j + 1) then
  253. begin
  254. i := LenPat;
  255. j := LenName;{we can stop}
  256. Found := true;
  257. end
  258. else
  259. j := j + 1;{We didn't find one, need to look further}
  260. end;
  261. until (j >= LenName);
  262. end
  263. else
  264. j := LenName;{we can stop}
  265. end;
  266. otherwise {not a wildcard character in pattern}
  267. Found := (j <= LenName) and (pattern[i] = name[j]);
  268. end;
  269. i := i + 1;
  270. j := j + 1;
  271. end;
  272. DoFnMatch := Found and (j > LenName);
  273. end;
  274. begin {start FNMatch}
  275. LenPat := Length(Pattern);
  276. LenName := Length(Name);
  277. FNMatch := DoFNMatch(1, 1);
  278. end;
  279. *)
  280. function GetFileAttrFromPB (var paramBlock: CInfoPBRec): Word;
  281. var
  282. isLocked, isInvisible, isDirectory, isNameLocked: Boolean;
  283. attr: Word;
  284. {NOTE "nameLocked" was in pre-System 7 called "isSystem".
  285. It is used for files whose name and icon cannot be changed by the user,
  286. that is essentially system files. However in System 9 the folder
  287. "Applications (Mac OS 9)" also has this attribute, and since this is
  288. not a system file in traditional meaning, we will not use this attribute
  289. as the "sysfile" attribute.}
  290. begin
  291. with paramBlock do
  292. begin
  293. attr := 0;
  294. isDirectory := (ioFlAttrib and $10) <> 0;
  295. if isDirectory then
  296. attr := (attr or directory);
  297. isLocked := (ioFlAttrib and $01) <> 0;
  298. if isLocked then
  299. attr := (attr or readonly);
  300. if not isDirectory then
  301. begin
  302. isInvisible := (ioFlFndrInfo.fdFlags and 16384) <> 0;
  303. (* isNameLocked := (ioFlFndrInfo.fdFlags and 4096) <> 0; *)
  304. end
  305. else
  306. begin
  307. isInvisible := (ioDrUsrWds.frFlags and 16384) <> 0;
  308. (* isNameLocked := (ioDrUsrWds.frFlags and 4096) <> 0; *)
  309. end;
  310. if isInvisible then
  311. attr := (attr or hidden);
  312. (*
  313. if isNameLocked then
  314. attr := (attr or sysfile);
  315. *)
  316. GetFileAttrFromPB := attr;
  317. end;
  318. end;
  319. procedure SetPBFromFileAttr (var paramBlock: CInfoPBRec; attr: Word);
  320. begin
  321. with paramBlock do
  322. begin
  323. (*
  324. {Doesn't seem to work, despite the documentation.}
  325. {Can instead be set by FSpSetFLock/FSpRstFLock}
  326. if (attr and readonly) <> 0 then
  327. ioFlAttrib := (ioFlAttrib or $01)
  328. else
  329. ioFlAttrib := (ioFlAttrib and not($01));
  330. *)
  331. if (attr and hidden) <> 0 then
  332. ioFlFndrInfo.fdFlags := (ioFlFndrInfo.fdFlags or 16384)
  333. else
  334. ioFlFndrInfo.fdFlags := (ioFlFndrInfo.fdFlags and not(16384))
  335. end;
  336. end;
  337. function GetFileSizeFromPB (var paramBlock: CInfoPBRec): Longint;
  338. begin
  339. with paramBlock do
  340. if ((ioFlAttrib and $10) <> 0) then {if directory}
  341. GetFileSizeFromPB := 0
  342. else
  343. GetFileSizeFromPB := ioFlLgLen + ioFlRLgLen; {Add length of both forks}
  344. end;
  345. function DoFindOne (var spec: FSSpec; var paramBlock: CInfoPBRec): Integer;
  346. var
  347. err: OSErr;
  348. begin
  349. with paramBlock do
  350. begin
  351. ioVRefNum := spec.vRefNum;
  352. ioDirID := spec.parID;
  353. ioNamePtr := @spec.name;
  354. ioFDirIndex := 0;
  355. err := PBGetCatInfoSync(@paramBlock);
  356. DoFindOne := MacOSErr2RTEerr(err);
  357. end;
  358. end;
  359. {To be used after a call to DoFindOne, with the same spec and paramBlock.}
  360. {Change those parameters in paramBlock, which is to be changed.}
  361. function DoSetOne (var spec: FSSpec; var paramBlock: CInfoPBRec): Integer;
  362. var
  363. err: OSErr;
  364. begin
  365. with paramBlock do
  366. begin
  367. ioVRefNum := spec.vRefNum;
  368. ioDirID := spec.parID;
  369. ioNamePtr := @spec.name;
  370. err := PBSetCatInfoSync(@paramBlock);
  371. DoSetOne := MacOSErr2RTEerr(err);
  372. end;
  373. end;
  374. procedure DoFind (var F: SearchRec; firstTime: Boolean);
  375. var
  376. err: OSErr;
  377. s: Str255;
  378. begin
  379. with F, paramBlock do
  380. begin
  381. ioVRefNum := searchFSSpec.vRefNum;
  382. if firstTime then
  383. ioFDirIndex := 0;
  384. while true do
  385. begin
  386. s := '';
  387. ioDirID := searchFSSpec.parID;
  388. ioFDirIndex := ioFDirIndex + 1;
  389. ioNamePtr := @s;
  390. err := PBGetCatInfoSync(@paramBlock);
  391. if err <> noErr then
  392. begin
  393. if err = fnfErr then
  394. DosError := 18
  395. else
  396. DosError := MacOSErr2RTEerr(err);
  397. break;
  398. end;
  399. attr := GetFileAttrFromPB(f.paramBlock);
  400. if ((Attr and not(searchAttr)) = 0) then
  401. begin
  402. name := s;
  403. UpperString(s, true);
  404. if FNMatch(F.searchFSSpec.name, s) then
  405. begin
  406. size := GetFileSizeFromPB(paramBlock);
  407. time := MacTimeToDosPackedTime(ioFlMdDat);
  408. DosError := 0;
  409. break;
  410. end;
  411. end;
  412. end;
  413. end;
  414. end;
  415. procedure FindFirst (const path: pathstr; Attr: Word; var F: SearchRec);
  416. var
  417. s: Str255;
  418. begin
  419. fillchar(f, sizeof(f), 0);
  420. if path = '' then
  421. begin
  422. DosError := 3;
  423. Exit;
  424. end;
  425. {We always also search for readonly and archive, regardless of Attr.}
  426. F.searchAttr := (Attr or (archive or readonly));
  427. DosError := PathArgToFSSpec(path, F.searchFSSpec);
  428. with F do
  429. if (DosError = 0) or (DosError = 2) then
  430. begin
  431. SearchSpec := path;
  432. NamePos := Length(path) - Length(searchFSSpec.name);
  433. if (Pos('?', searchFSSpec.name) = 0) and (Pos('*', searchFSSpec.name) = 0) then {No wildcards}
  434. begin {If exact match, we don't have to scan the directory}
  435. exactMatch := true;
  436. DosError := DoFindOne(searchFSSpec, paramBlock);
  437. if DosError = 0 then
  438. begin
  439. Attr := GetFileAttrFromPB(paramBlock);
  440. if ((Attr and not(searchAttr)) = 0) then
  441. begin
  442. name := searchFSSpec.name;
  443. size := GetFileSizeFromPB(paramBlock);
  444. time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
  445. end
  446. else
  447. DosError := 18;
  448. end
  449. else if DosError = 2 then
  450. DosError := 18;
  451. end
  452. else
  453. begin
  454. exactMatch := false;
  455. s := searchFSSpec.name;
  456. UpperString(s, true);
  457. F.searchFSSpec.name := s;
  458. DoFind(F, true);
  459. end;
  460. end;
  461. end;
  462. procedure FindNext (var f: searchRec);
  463. begin
  464. if F.exactMatch then
  465. DosError := 18
  466. else
  467. DoFind(F, false);
  468. end;
  469. procedure FindClose (var f: searchRec);
  470. {Note: Even if this routine is empty, this doesn't mean it will}
  471. {be empty in the future. Please use it.}
  472. begin
  473. end;
  474. {******************************************************************************
  475. --- File ---
  476. ******************************************************************************}
  477. function FSearch (path: pathstr; dirlist: string): pathstr;
  478. {Searches for a file 'path' in the working directory and then in the list of }
  479. {directories in 'dirlist' . Returns a valid (possibly relative) path or an }
  480. {empty string if not found . Wildcards are NOT allowed }
  481. {The dirlist can be separated with ; or , but not :}
  482. var
  483. NewDir: string[255];
  484. p1: Longint;
  485. spec: FSSpec;
  486. fpcerr: Integer;
  487. begin
  488. FSearch := '';
  489. if (Length(path) = 0) then
  490. Exit;
  491. {Check for Wild Cards}
  492. if (Pos('?', Path) <> 0) or (Pos('*', Path) <> 0) then
  493. Exit;
  494. path := TranslatePathToMac(path, false);
  495. {Search in working directory, or as full path}
  496. fpcerr := PathArgToFSSpec(path, spec);
  497. if (fpcerr = 0) and not IsDirectory(spec) then
  498. begin
  499. FSearch := path;
  500. Exit;
  501. end
  502. else if not IsMacFullPath(path) then {If full path, we do not need to continue.}
  503. begin
  504. {Replace ';' with native mac PathSeparator (',').}
  505. {Note: we cannot support unix style ':', because it is used as dir separator in MacOS}
  506. for p1 := 1 to length(dirlist) do
  507. if dirlist[p1] = ';' then
  508. dirlist[p1] := PathSeparator;
  509. repeat
  510. p1 := Pos(PathSeparator, DirList);
  511. if p1 = 0 then
  512. p1 := 255;
  513. NewDir := TranslatePathToMac(Copy(DirList, 1, P1 - 1), false);
  514. NewDir := ConcatMacPath(NewDir, Path);
  515. Delete(DirList, 1, p1);
  516. fpcerr := PathArgToFSSpec(NewDir, spec);
  517. if fpcerr = 0 then
  518. begin
  519. if IsDirectory(spec) then
  520. NewDir := '';
  521. end
  522. else
  523. NewDir := '';
  524. until (DirList = '') or (Length(NewDir) > 0);
  525. FSearch := NewDir;
  526. end;
  527. end;
  528. {$UNDEF USE_FEXPAND_INC}
  529. {$IFDEF USE_FEXPAND_INC}
  530. {$DEFINE FPC_FEXPAND_VOLUMES}
  531. {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
  532. { TODO A lot of issues before this works}
  533. {$I fexpand.inc}
  534. {$UNDEF FPC_FEXPAND_VOLUMES}
  535. {$UNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
  536. {$ELSE}
  537. { TODO nonexisting dirs in path's doesnt work (nonexisting files do work)
  538. example: Writeln('FExpand on :nisse:kalle : ', FExpand(':nisse:kalle')); }
  539. function FExpand (const path: pathstr): pathstr;
  540. var
  541. fullpath: AnsiString;
  542. begin
  543. DosError:= PathArgToFullPath(path, fullpath);
  544. FExpand:= fullpath;
  545. end;
  546. {$ENDIF}
  547. procedure FSplit (path: pathstr; var dir: dirstr; var name: namestr; var ext: extstr);
  548. var
  549. dotPos,colonPos,i : longint;
  550. begin
  551. colonPos:=0;
  552. dotPos:=256;
  553. i:=Length(path);
  554. while (i>0) and (colonPos=0) Do
  555. begin
  556. If (dotPos=256) and (path[i]='.') Then
  557. dotPos:=i;
  558. If (path[i]=':') Then
  559. colonPos:=i;
  560. Dec(i);
  561. end;
  562. ext:=Copy(path,dotPos,255);
  563. dir:=Copy(path,1,colonPos);
  564. name:=Copy(path,colonPos + 1,dotPos - colonPos - 1);
  565. end;
  566. procedure GetFTime (var f ; var time: longint);
  567. var
  568. spec: FSSpec;
  569. paramBlock: CInfoPBRec;
  570. begin
  571. DosError := PathArgToFSSpec(filerec(f).name, spec);
  572. if (DosError = 0) or (DosError = 2) then
  573. begin
  574. DosError := DoFindOne(spec, paramBlock);
  575. if DosError = 0 then
  576. time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
  577. end;
  578. end;
  579. procedure SetFTime (var f ; time: longint);
  580. var
  581. spec: FSSpec;
  582. paramBlock: CInfoPBRec;
  583. d: DateTimeRec; {Mac OS datastructure}
  584. t: datetime;
  585. macfiletime: UInt32;
  586. begin
  587. DosError := PathArgToFSSpec(filerec(f).name, spec);
  588. if (DosError = 0) or (DosError = 2) then
  589. begin
  590. DosError := DoFindOne(spec, paramBlock);
  591. if DosError = 0 then
  592. begin
  593. Unpacktime(time, t);
  594. with t do
  595. begin
  596. d.year := year;
  597. d.month := month;
  598. d.day := day;
  599. d.hour := hour;
  600. d.minute := min;
  601. d.second := sec;
  602. end;
  603. DateToSeconds(d, macfiletime);
  604. paramBlock.ioFlMdDat := macfiletime;
  605. DosError := DoSetOne(spec, paramBlock);
  606. end;
  607. end;
  608. end;
  609. procedure GetFAttr (var f ; var attr: word);
  610. var
  611. spec: FSSpec;
  612. paramBlock: CInfoPBRec;
  613. begin
  614. DosError := PathArgToFSSpec(filerec(f).name, spec);
  615. if (DosError = 0) or (DosError = 2) then
  616. begin
  617. DosError := DoFindOne(spec, paramBlock);
  618. if DosError = 0 then
  619. attr := GetFileAttrFromPB(paramBlock);
  620. end;
  621. end;
  622. procedure SetFAttr (var f ; attr: word);
  623. var
  624. spec: FSSpec;
  625. paramBlock: CInfoPBRec;
  626. begin
  627. if (attr and VolumeID) <> 0 then
  628. begin
  629. Doserror := 5;
  630. end;
  631. DosError := PathArgToFSSpec(filerec(f).name, spec);
  632. if (DosError = 0) or (DosError = 2) then
  633. begin
  634. DosError := DoFindOne(spec, paramBlock);
  635. if DosError = 0 then
  636. begin
  637. SetPBFromFileAttr(paramBlock, attr);
  638. DosError := DoSetOne(spec, paramBlock);
  639. if (paramBlock.ioFlAttrib and $10) = 0 then {check not directory}
  640. if DosError = 0 then
  641. if (attr and readonly) <> 0 then
  642. DosError := MacOSErr2RTEerr(FSpSetFLock(spec))
  643. else
  644. DosError := MacOSErr2RTEerr(FSpRstFLock(spec));
  645. end;
  646. end;
  647. end;
  648. {******************************************************************************
  649. --- Environment ---
  650. ******************************************************************************}
  651. Function EnvCount: Longint;
  652. var
  653. envcnt : longint;
  654. p : ppchar;
  655. Begin
  656. envcnt:=0;
  657. p:=envp; {defined in system}
  658. while (p^<>nil) do
  659. begin
  660. inc(envcnt);
  661. inc(p);
  662. end;
  663. EnvCount := envcnt
  664. End;
  665. Function EnvStr (Index: longint): String;
  666. Var
  667. i : longint;
  668. p : ppchar;
  669. Begin
  670. p:=envp; {defined in system}
  671. i:=1;
  672. while (i<Index) and (p^<>nil) do
  673. begin
  674. inc(i);
  675. inc(p);
  676. end;
  677. if p=nil then
  678. envstr:=''
  679. else
  680. begin
  681. envstr:=strpas(p^) + '=' + strpas(p^+strlen(p^)+1)
  682. end;
  683. End;
  684. function c_getenv(varname: PChar): PChar; {TODO perhaps move to a separate inc file.}
  685. external 'StdCLib' name 'getenv';
  686. Function GetEnv(EnvVar: String): String;
  687. var
  688. p: PChar;
  689. name: String;
  690. Begin
  691. name:= EnvVar+#0;
  692. p:= c_getenv(@name[1]);
  693. if p=nil then
  694. GetEnv:=''
  695. else
  696. GetEnv:=StrPas(p);
  697. End;
  698. {******************************************************************************
  699. --- Do Nothing Procedures/Functions ---
  700. ******************************************************************************}
  701. Procedure getintvec(intno : byte;var vector : pointer);
  702. Begin
  703. {! No MacOS equivalent !}
  704. End;
  705. Procedure setintvec(intno : byte;vector : pointer);
  706. Begin
  707. {! No MacOS equivalent !}
  708. End;
  709. Procedure SwapVectors;
  710. Begin
  711. {! No MacOS equivalent !}
  712. End;
  713. Procedure Keep(exitcode : word);
  714. Begin
  715. {! No MacOS equivalent !}
  716. End;
  717. Procedure GetCBreak(Var BreakValue: Boolean);
  718. Begin
  719. {! Might be implemented in future on MacOS to handle Cmd-. (period) key press}
  720. breakvalue:=true
  721. End;
  722. Procedure SetCBreak(BreakValue: Boolean);
  723. Begin
  724. {! Might be implemented in future on MacOS to handle Cmd-. (period) key press}
  725. End;
  726. Procedure GetVerify(Var Verify: Boolean);
  727. Begin
  728. {! Might be implemented in future on MacOS}
  729. Verify:=true;
  730. End;
  731. Procedure SetVerify(Verify: Boolean);
  732. Begin
  733. {! Might be implemented in future on MacOS}
  734. End;
  735. function GetShortName(var p : String) : boolean;
  736. begin
  737. { short=long under MacOS}
  738. GetShortName:=True;
  739. end;
  740. function GetLongName(var p : String) : boolean;
  741. begin
  742. { short=long under MacOS}
  743. GetLongName:=True;
  744. end;
  745. {******************************************************************************
  746. --- Initialization ---
  747. ******************************************************************************}
  748. End.