123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2004 by Olle Raab and
- members of the Free Pascal development team
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************}
- Unit Dos;
- Interface
- Uses
- macostp;
- Const
- FileNameLen = 255;
- Type
- SearchRec = packed record
- Attr: Byte; {attribute of found file}
- Time: LongInt; {last modify date of found file}
- Size: LongInt; {file size of found file}
- Reserved: Word; {future use}
- Name: string[FileNameLen]; {name of foundfile}
- SearchSpec: string[FileNameLen]; {search pattern}
- NamePos: Word; {end of path,start of name position}
- {MacOS specific params, private, do not use:}
- paramBlock: CInfoPBRec;
- searchFSSpec: FSSpec;
- searchAttr: Byte; {attribute we are searching for}
- exactMatch: Boolean;
- end;
- {$DEFINE HAS_FILENAMELEN}
- {$I dosh.inc}
- Implementation
- {TODO Obtain disk size and disk free values for volumes > 2 GB.
- For this, PBXGetVolInfoSync can be used. However, this function
- is not available on older versions of Mac OS, so the function has
- to be weak linked. An alternative is to directly look into the VCB
- (Volume Control Block), but since this is on low leveel it is a
- compatibility risque.}
- {TODO Perhaps make SearchRec.paramBlock opaque, so that uses macostp;
- is not needed in the interface part.}
- {TODO Perhaps add some kind of "Procedure AddDisk" for accessing other
- volumes. At lest accessing the possible disk drives with
- drive number 1 and 2 should be easy.}
- {TODO Perhaps use LongDateTime for time functions. But the function
- calls must then be weak linked.}
- Uses
- macutils;
- {$UNDEF USE_FEXPAND_INC}
- //{$DEFINE USE_FEXPAND_INC}
- {$IFNDEF USE_FEXPAND_INC}
- {$DEFINE HAS_FEXPAND}
- {Own implemetation of fexpand.inc}
- {$I dos.inc}
- {$ELSE}
- {$DEFINE FPC_FEXPAND_VOLUMES}
- {$DEFINE FPC_FEXPAND_NO_DEFAULT_PATHS}
- {$DEFINE FPC_FEXPAND_DRIVESEP_IS_ROOT}
- {$DEFINE FPC_FEXPAND_NO_DOTS_UPDIR}
- {$DEFINE FPC_FEXPAND_NO_CURDIR}
- { NOTE: If HAS_FEXPAND is not defined, fexpand.inc is included in dos.inc. }
- { TODO A lot of issues before this works}
- {$I dos.inc}
- {$UNDEF FPC_FEXPAND_VOLUMES}
- {$UNDEF FPC_FEXPAND_NO_DEFAULT_PATHS}
- {$UNDEF FPC_FEXPAND_DRIVESEP_IS_ROOT}
- {$UNDEF FPC_FEXPAND_NO_DOTS_UPDIR}
- {$UNDEF FPC_FEXPAND_NO_CURDIR}
- {$ENDIF}
- function MacTimeToDosPackedTime(macfiletime: UInt32): Longint;
- var
- mdt: DateTimeRec; {Mac OS datastructure}
- ddt: Datetime; {Dos OS datastructure}
- dospackedtime: Longint;
- begin
- SecondsToDate(macfiletime, mdt);
- with ddt do
- begin
- year := mdt.year;
- month := mdt.month;
- day := mdt.day;
- hour := mdt.hour;
- min := mdt.minute;
- sec := mdt.second;
- end;
- Packtime(ddt, dospackedtime);
- MacTimeToDosPackedTime:= dospackedtime;
- end;
- {******************************************************************************
- --- Info / Date / Time ---
- ******************************************************************************}
- function DosVersion:Word;
- begin
- DosVersion:=
- (macosSystemVersion and $FF00) or
- ((macosSystemVersion and $00F0) shr 4);
- end;
- procedure GetDate (var year, month, mday, wday: word);
- var
- d: DateTimeRec;
- begin
- Macostp.GetTime(d);
- year := d.year;
- month := d.month;
- mday := d.day;
- wday := d.dayOfWeek - 1; {1-based on mac}
- end;
- procedure GetTime (var hour, minute, second, sec100: word);
- var
- d: DateTimeRec;
- begin
- Macostp.GetTime(d);
- hour := d.hour;
- minute := d.minute;
- second := d.second;
- sec100 := 0;
- end;
- Procedure SetDate(Year, Month, Day: Word);
- var
- d: DateTimeRec;
- Begin
- Macostp.GetTime(d);
- d.year := year;
- d.month := month;
- d.day := day;
- Macostp.SetTime(d)
- End;
- Procedure SetTime(Hour, Minute, Second, Sec100: Word);
- var
- d: DateTimeRec;
- Begin
- Macostp.GetTime(d);
- d.hour := hour;
- d.minute := minute;
- d.second := second;
- Macostp.SetTime(d)
- End;
- {******************************************************************************
- --- Exec ---
- ******************************************************************************}
- { Create a DoScript AppleEvent that targets the given application with text as the direct object. }
- function CreateDoScriptEvent (applCreator: OSType; scriptText: PChar; var theEvent: AppleEvent): OSErr;
- var
- err: OSErr;
- targetAddress: AEDesc;
- s: signedByte;
- begin
- err := AECreateDesc(FourCharCodeToLongword(typeApplSignature), @applCreator, sizeof(applCreator), targetAddress);
- if err = noErr then
- begin
- err := AECreateAppleEvent(FourCharCodeToLongword('misc'), FourCharCodeToLongword('dosc'),
- targetAddress, kAutoGenerateReturnID, kAnyTransactionID, theEvent);
- if err = noErr then
- { Add script text as the direct object parameter. }
- err := AEPutParamPtr(theEvent, FourCharCodeToLongword('----'),
- FourCharCodeToLongword('TEXT'), scriptText, Length(scriptText));
- if err <> noErr then
- AEDisposeDesc(theEvent);
- AEDisposeDesc(targetAddress);
- end;
- CreateDoScriptEvent := err;
- end;
- Procedure Fpc_WriteBuffer(var f:Text;const b;len:longint);[external name 'FPC_WRITEBUFFER'];
- {declared in text.inc}
- procedure WriteAEDescTypeCharToFile(desc: AEDesc; var f: Text);
- begin
- if desc.descriptorType = FourCharCodeToLongword(typeChar) then
- begin
- HLock(desc.dataHandle);
- Fpc_WriteBuffer(f, PChar(desc.dataHandle^)^, GetHandleSize(desc.dataHandle));
- Flush(f);
- HUnLock(desc.dataHandle);
- end;
- end;
- function ExecuteToolserverScript(scriptText: PChar; var statusCode: Longint): OSErr;
- var
- err: OSErr;
- err2: OSErr; {Non serious error}
- theEvent: AppleEvent;
- reply: AppleEvent;
- result: AEDesc;
- applFileSpec: FSSpec;
- p: SignedByte;
- const
- applCreator = 'MPSX'; {Toolserver}
- begin
- statusCode:= 3; //3 according to MPW.
- err:= CreateDoScriptEvent (FourCharCodeToLongword(applCreator), scriptText, theEvent);
- if err = noErr then
- begin
- err := AESend(theEvent, reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeOut, nil, nil);
- if err = connectionInvalid then { Toolserver not available }
- begin
- err := FindApplication(FourCharCodeToLongword(applCreator), applFileSpec);
- if err = noErr then
- err := LaunchFSSpec(false, applFileSpec);
- if err = noErr then
- err := AESend(theEvent, reply, kAEWaitReply, kAENormalPriority, kAEDefaultTimeOut, nil, nil);
- end;
- if err = noErr then
- begin
- err:= AEGetParamDesc(reply, FourCharCodeToLongword('stat'),
- FourCharCodeToLongword(typeLongInteger), result);
- if err = noErr then
- if result.descriptorType = FourCharCodeToLongword(typeLongInteger) then
- statusCode:= LongintPtr(result.dataHandle^)^;
- {If there is no output below, we get a non zero error code}
- err2:= AEGetParamDesc(reply, FourCharCodeToLongword('----'),
- FourCharCodeToLongword(typeChar), result);
- if err2 = noErr then
- WriteAEDescTypeCharToFile(result, stdout);
- err2:= AEGetParamDesc(reply, FourCharCodeToLongword('diag'),
- FourCharCodeToLongword(typeChar), result);
- if err2 = noErr then
- WriteAEDescTypeCharToFile(result, stderr);
- AEDisposeDesc(reply);
- {$IFDEF TARGET_API_MAC_CARBON }
- {$ERROR FIXME AEDesc data is not allowed to be directly accessed}
- {$ENDIF}
- end;
- AEDisposeDesc(theEvent);
- end;
- ExecuteToolserverScript:= err;
- end;
- Procedure Exec (Const Path: PathStr; Const ComLine: ComStr);
- var
- s: AnsiString;
- err: OSErr;
- wdpath: RawByteString;
- Begin
- wdpath:='';
- {Make ToolServers working directory in sync with our working directory}
- PathArgToFullPath(':', wdpath);
- wdpath:= 'Directory ''' + wdpath + '''';
- err:= ExecuteToolserverScript(PChar(wdpath), LastDosExitCode);
- {TODO Only change path when actually needed. But this requires some
- change counter to be incremented each time wd is changed. }
- s:= path + ' ' + comline;
- err:= ExecuteToolserverScript(PChar(s), LastDosExitCode);
- if err = afpItemNotFound then
- DosError := 900
- else
- DosError := MacOSErr2RTEerr(err);
- //TODO Better dos error codes
- End;
- {******************************************************************************
- --- Disk ---
- ******************************************************************************}
- {If drive is 0 the free space on the volume of the working directory is returned.
- If drive is 1 or 2, the free space on the first or second floppy disk is returned.
- If drive is 3 the free space on the boot volume is returned.
- If the free space is > 2 GB, then 2 GB is reported.}
- Function DiskFree(drive: Byte): Int64;
- var
- myHPB: HParamBlockRec;
- myErr: OSErr;
- begin
- myHPB.ioNamePtr := NIL;
- myHPB.ioVolIndex := 0;
- case drive of
- 0: myHPB.ioVRefNum := GetWorkingDirectoryVRefNum;
- 1: myHPB.ioVRefNum := 1;
- 2: myHPB.ioVRefNum := 2;
- 3: myHPB.ioVRefNum := macosBootVolumeVRefNum;
- else
- begin
- Diskfree:= -1;
- Exit;
- end;
- end;
- myErr := PBHGetVInfoSync(@myHPB);
- if myErr = noErr then
- Diskfree := myHPB.ioVAlBlkSiz * myHPB.ioVFrBlk
- else
- Diskfree:= -1;
- End;
- {If drive is 0 the size of the volume of the working directory is returned.
- If drive is 1 or 2, the size of the first or second floppy disk is returned.
- If drive is 3 the size of the boot volume is returned.
- If the actual size is > 2 GB, then 2 GB is reported.}
- Function DiskSize(drive: Byte): Int64;
- var
- myHPB: HParamBlockRec;
- myErr: OSErr;
- Begin
- myHPB.ioNamePtr := NIL;
- myHPB.ioVolIndex := 0;
- case drive of
- 0: myHPB.ioVRefNum := GetWorkingDirectoryVRefNum;
- 1: myHPB.ioVRefNum := 1;
- 2: myHPB.ioVRefNum := 2;
- 3: myHPB.ioVRefNum := macosBootVolumeVRefNum;
- else
- begin
- DiskSize:= -1;
- Exit;
- end;
- end;
- myErr := PBHGetVInfoSync(@myHPB);
- if myErr = noErr then
- DiskSize := myHPB.ioVAlBlkSiz * myHPB.ioVNmAlBlks
- else
- DiskSize:=-1;
- End;
- {******************************************************************************
- --- Findfirst FindNext ---
- ******************************************************************************}
- function FNMatch (const Pattern, Name: string): Boolean;
- var
- LenPat, LenName: longint;
- function DoFNMatch (i, j: longint): Boolean;
- var
- Found: boolean;
- begin
- Found := true;
- while Found and (i <= LenPat) do
- begin
- case Pattern[i] of
- '?':
- Found := (j <= LenName);
- '*':
- begin
- {find the next character in pattern, different of ? and *}
- while Found and (i < LenPat) do
- begin
- i := i + 1;
- case Pattern[i] of
- '*':
- ;
- '?':
- begin
- j := j + 1;
- Found := (j <= LenName);
- end;
- otherwise
- Found := false;
- end;
- end;
- {Now, find in name the character which i points to, if the * or ?}
- {wasn 't the last character in the pattern, else, use up all the}
- {chars in name }
- Found := true;
- if (i <= LenPat) then
- begin
- repeat
- {find a letter (not only first !) which maches pattern[i]}
- while (j <= LenName) and (name[j] <> pattern[i]) do
- j := j + 1;
- if (j < LenName) then
- begin
- if DoFnMatch(i + 1, j + 1) then
- begin
- i := LenPat;
- j := LenName;{we can stop}
- Found := true;
- end
- else
- j := j + 1;{We didn't find one, need to look further}
- end;
- until (j >= LenName);
- end
- else
- j := LenName;{we can stop}
- end;
- otherwise {not a wildcard character in pattern}
- Found := (j <= LenName) and (pattern[i] = name[j]);
- end;
- i := i + 1;
- j := j + 1;
- end;
- DoFnMatch := Found and (j > LenName);
- end;
- begin {start FNMatch}
- LenPat := Length(Pattern);
- LenName := Length(Name);
- FNMatch := DoFNMatch(1, 1);
- end;
- function GetFileAttrFromPB (var paramBlock: CInfoPBRec): Word;
- var
- isLocked, isInvisible, isDirectory, isNameLocked: Boolean;
- attr: Word;
- {NOTE "nameLocked" was in pre-System 7 called "isSystem".
- It is used for files whose name and icon cannot be changed by the user,
- that is essentially system files. However in System 9 the folder
- "Applications (Mac OS 9)" also has this attribute, and since this is
- not a system file in traditional meaning, we will not use this attribute
- as the "sysfile" attribute.}
- begin
- with paramBlock do
- begin
- attr := 0;
- isDirectory := (ioFlAttrib and $10) <> 0;
- if isDirectory then
- attr := (attr or directory);
- isLocked := (ioFlAttrib and $01) <> 0;
- if isLocked then
- attr := (attr or readonly);
- if not isDirectory then
- begin
- isInvisible := (ioFlFndrInfo.fdFlags and 16384) <> 0;
- (* isNameLocked := (ioFlFndrInfo.fdFlags and 4096) <> 0; *)
- end
- else
- begin
- isInvisible := (ioDrUsrWds.frFlags and 16384) <> 0;
- (* isNameLocked := (ioDrUsrWds.frFlags and 4096) <> 0; *)
- end;
- if isInvisible then
- attr := (attr or hidden);
- (*
- if isNameLocked then
- attr := (attr or sysfile);
- *)
- GetFileAttrFromPB := attr;
- end;
- end;
- procedure SetPBFromFileAttr (var paramBlock: CInfoPBRec; attr: Word);
- begin
- with paramBlock do
- begin
- (*
- {Doesn't seem to work, despite the documentation.}
- {Can instead be set by FSpSetFLock/FSpRstFLock}
- if (attr and readonly) <> 0 then
- ioFlAttrib := (ioFlAttrib or $01)
- else
- ioFlAttrib := (ioFlAttrib and not($01));
- *)
- if (attr and hidden) <> 0 then
- ioFlFndrInfo.fdFlags := (ioFlFndrInfo.fdFlags or 16384)
- else
- ioFlFndrInfo.fdFlags := (ioFlFndrInfo.fdFlags and not(16384))
- end;
- end;
- function GetFileSizeFromPB (var paramBlock: CInfoPBRec): Longint;
- begin
- with paramBlock do
- if ((ioFlAttrib and $10) <> 0) then {if directory}
- GetFileSizeFromPB := 0
- else
- GetFileSizeFromPB := ioFlLgLen + ioFlRLgLen; {Add length of both forks}
- end;
- function DoFindOne (var spec: FSSpec; var paramBlock: CInfoPBRec): Integer;
- var
- err: OSErr;
- begin
- with paramBlock do
- begin
- ioVRefNum := spec.vRefNum;
- ioDirID := spec.parID;
- ioNamePtr := @spec.name;
- ioFDirIndex := 0;
- err := PBGetCatInfoSync(@paramBlock);
- DoFindOne := MacOSErr2RTEerr(err);
- end;
- end;
- {To be used after a call to DoFindOne, with the same spec and paramBlock.}
- {Change those parameters in paramBlock, which is to be changed.}
- function DoSetOne (var spec: FSSpec; var paramBlock: CInfoPBRec): Integer;
- var
- err: OSErr;
- begin
- with paramBlock do
- begin
- ioVRefNum := spec.vRefNum;
- ioDirID := spec.parID;
- ioNamePtr := @spec.name;
- err := PBSetCatInfoSync(@paramBlock);
- DoSetOne := MacOSErr2RTEerr(err);
- end;
- end;
- procedure DoFind (var F: SearchRec; firstTime: Boolean);
- var
- err: OSErr;
- s: Str255;
- begin
- with F, paramBlock do
- begin
- ioVRefNum := searchFSSpec.vRefNum;
- if firstTime then
- ioFDirIndex := 0;
- while true do
- begin
- s := '';
- ioDirID := searchFSSpec.parID;
- ioFDirIndex := ioFDirIndex + 1;
- ioNamePtr := @s;
- err := PBGetCatInfoSync(@paramBlock);
- if err <> noErr then
- begin
- if err = fnfErr then
- DosError := 18
- else
- DosError := MacOSErr2RTEerr(err);
- break;
- end;
- attr := GetFileAttrFromPB(f.paramBlock);
- if ((Attr and not(searchAttr)) = 0) then
- begin
- name := s;
- UpperString(s, true);
- if FNMatch(F.searchFSSpec.name, s) then
- begin
- size := GetFileSizeFromPB(paramBlock);
- time := MacTimeToDosPackedTime(ioFlMdDat);
- DosError := 0;
- break;
- end;
- end;
- end;
- end;
- end;
- procedure FindFirst (const path: pathstr; Attr: Word; var F: SearchRec);
- var
- s: Str255;
- begin
- fillchar(f, sizeof(f), 0);
- if path = '' then
- begin
- DosError := 3;
- Exit;
- end;
- {We always also search for readonly and archive, regardless of Attr.}
- F.searchAttr := (Attr or (archive or readonly));
- DosError := PathArgToFSSpec(path, F.searchFSSpec);
- with F do
- if (DosError = 0) or (DosError = 2) then
- begin
- SearchSpec := path;
- NamePos := Length(path) - Length(searchFSSpec.name);
- if (Pos('?', searchFSSpec.name) = 0) and (Pos('*', searchFSSpec.name) = 0) then {No wildcards}
- begin {If exact match, we don't have to scan the directory}
- exactMatch := true;
- DosError := DoFindOne(searchFSSpec, paramBlock);
- if DosError = 0 then
- begin
- Attr := GetFileAttrFromPB(paramBlock);
- if ((Attr and not(searchAttr)) = 0) then
- begin
- name := searchFSSpec.name;
- size := GetFileSizeFromPB(paramBlock);
- time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
- end
- else
- DosError := 18;
- end
- else if DosError = 2 then
- DosError := 18;
- end
- else
- begin
- exactMatch := false;
- s := searchFSSpec.name;
- UpperString(s, true);
- F.searchFSSpec.name := s;
- DoFind(F, true);
- end;
- end;
- end;
- procedure FindNext (var f: searchRec);
- begin
- if F.exactMatch then
- DosError := 18
- else
- DoFind(F, false);
- end;
- procedure FindClose (var f: searchRec);
- {Note: Even if this routine is empty, this doesn't mean it will}
- {be empty in the future. Please use it.}
- begin
- end;
- {******************************************************************************
- --- File ---
- ******************************************************************************}
- function FSearch (path: pathstr; dirlist: string): pathstr;
- {Searches for a file 'path' in the working directory and then in the list of }
- {directories in 'dirlist' . Returns a valid (possibly relative) path or an }
- {empty string if not found . Wildcards are NOT allowed }
- {The dirlist can be separated with ; or , but not :}
- var
- NewDir: string[255];
- p1: Longint;
- spec: FSSpec;
- fpcerr: Integer;
- begin
- FSearch := '';
- if (Length(path) = 0) then
- Exit;
- {Check for Wild Cards}
- if (Pos('?', Path) <> 0) or (Pos('*', Path) <> 0) then
- Exit;
- if pathTranslation then
- path := TranslatePathToMac(path, false);
- {Search in working directory, or as full path}
- fpcerr := PathArgToFSSpec(path, spec);
- if (fpcerr = 0) and not IsDirectory(spec) then
- begin
- FSearch := path;
- Exit;
- end
- else if not IsMacFullPath(path) then {If full path, we do not need to continue.}
- begin
- {Replace ';' with native mac PathSeparator (',').}
- {Note: we cannot support unix style ':', because it is used as dir separator in MacOS}
- for p1 := 1 to length(dirlist) do
- if dirlist[p1] = ';' then
- dirlist[p1] := PathSeparator;
- repeat
- p1 := Pos(PathSeparator, DirList);
- if p1 = 0 then
- p1 := 255;
- if pathTranslation then
- NewDir := TranslatePathToMac(Copy(DirList, 1, P1 - 1), false)
- else
- NewDir := Copy(DirList, 1, P1 - 1);
- NewDir := ConcatMacPath(NewDir, Path);
- Delete(DirList, 1, p1);
- fpcerr := PathArgToFSSpec(NewDir, spec);
- if fpcerr = 0 then
- begin
- if IsDirectory(spec) then
- NewDir := '';
- end
- else
- NewDir := '';
- until (DirList = '') or (Length(NewDir) > 0);
- FSearch := NewDir;
- end;
- end;
- {$IFNDEF USE_FEXPAND_INC}
- { TODO nonexisting dirs in path's doesnt work (nonexisting files do work)
- example: Writeln('FExpand on :nisse:kalle : ', FExpand(':nisse:kalle')); }
- function FExpand (const path: pathstr): pathstr;
- var
- fullpath: RawByteString;
- begin
- fullpath:='';
- DosError:= PathArgToFullPath(path, fullpath);
- FExpand:= fullpath;
- end;
- {$ENDIF USE_FEXPAND_INC}
- procedure GetFTime (var f ; var time: longint);
- var
- spec: FSSpec;
- paramBlock: CInfoPBRec;
- begin
- {$ifdef FPC_ANSI_TEXTFILEREC}
- DosError := PathArgToFSSpec(filerec(f).name, spec);
- {$else}
- DosError := PathArgToFSSpec(ToSingleByteFileSystemEncodedFileName(filerec(f).name), spec);
- {$endif}
- if (DosError = 0) or (DosError = 2) then
- begin
- DosError := DoFindOne(spec, paramBlock);
- if DosError = 0 then
- time := MacTimeToDosPackedTime(paramBlock.ioFlMdDat);
- end;
- end;
- procedure SetFTime (var f ; time: longint);
- var
- spec: FSSpec;
- paramBlock: CInfoPBRec;
- d: DateTimeRec; {Mac OS datastructure}
- t: datetime;
- macfiletime: UInt32;
- begin
- {$ifdef FPC_ANSI_TEXTFILEREC}
- DosError := PathArgToFSSpec(filerec(f).name, spec);
- {$else}
- DosError := PathArgToFSSpec(ToSingleByteFileSystemEncodedFileName(filerec(f).name), spec);
- {$endif}
- if (DosError = 0) or (DosError = 2) then
- begin
- DosError := DoFindOne(spec, paramBlock);
- if DosError = 0 then
- begin
- Unpacktime(time, t);
- with t do
- begin
- d.year := year;
- d.month := month;
- d.day := day;
- d.hour := hour;
- d.minute := min;
- d.second := sec;
- end;
- DateToSeconds(d, macfiletime);
- paramBlock.ioFlMdDat := macfiletime;
- DosError := DoSetOne(spec, paramBlock);
- end;
- end;
- end;
- procedure GetFAttr (var f ; var attr: word);
- var
- spec: FSSpec;
- paramBlock: CInfoPBRec;
- begin
- DosError := PathArgToFSSpec(StrPas(filerec(f).name), spec);
- if (DosError = 0) or (DosError = 2) then
- begin
- DosError := DoFindOne(spec, paramBlock);
- if DosError = 0 then
- attr := GetFileAttrFromPB(paramBlock);
- end;
- end;
- procedure SetFAttr (var f ; attr: word);
- var
- spec: FSSpec;
- paramBlock: CInfoPBRec;
- begin
- if (attr and VolumeID) <> 0 then
- begin
- Doserror := 5;
- Exit;
- end;
- DosError := PathArgToFSSpec(StrPas(filerec(f).name), spec);
- if (DosError = 0) or (DosError = 2) then
- begin
- DosError := DoFindOne(spec, paramBlock);
- if DosError = 0 then
- begin
- SetPBFromFileAttr(paramBlock, attr);
- DosError := DoSetOne(spec, paramBlock);
- if (paramBlock.ioFlAttrib and $10) = 0 then {check not directory}
- if DosError = 0 then
- if (attr and readonly) <> 0 then
- DosError := MacOSErr2RTEerr(FSpSetFLock(spec))
- else
- DosError := MacOSErr2RTEerr(FSpRstFLock(spec));
- end;
- end;
- end;
- {******************************************************************************
- --- Environment ---
- ******************************************************************************}
- Function EnvCount: Longint;
- var
- envcnt : longint;
- p : ppchar;
- Begin
- envcnt:=0;
- p:=envp; {defined in system}
- while (p^<>nil) do
- begin
- inc(envcnt);
- inc(p);
- end;
- EnvCount := envcnt
- End;
- Function EnvStr (Index: longint): String;
- Var
- i : longint;
- p : ppchar;
- Begin
- if Index <= 0 then
- envstr:=''
- else
- begin
- p:=envp; {defined in system}
- i:=1;
- while (i<Index) and (p^<>nil) do
- begin
- inc(i);
- inc(p);
- end;
- if p=nil then
- envstr:=''
- else
- envstr:=strpas(p^) + '=' + strpas(p^+strlen(p^)+1);
- end;
- end;
- function c_getenv(varname: PChar): PChar; {TODO perhaps move to a separate inc file.}
- external 'StdCLib' name 'getenv';
- Function GetEnv(EnvVar: String): String;
- var
- p: PChar;
- name: String;
- Begin
- name:= EnvVar+#0;
- p:= c_getenv(@name[1]);
- if p=nil then
- GetEnv:=''
- else
- GetEnv:=StrPas(p);
- End;
- {
- Procedure GetCBreak(Var BreakValue: Boolean);
- Begin
- -- Might be implemented in future on MacOS to handle Cmd-. (period) key press
- End;
- Procedure SetCBreak(BreakValue: Boolean);
- Begin
- -- Might be implemented in future on MacOS to handle Cmd-. (period) key press
- End;
- Procedure GetVerify(Var Verify: Boolean);
- Begin
- -- Might be implemented in future on MacOS
- End;
- Procedure SetVerify(Verify: Boolean);
- Begin
- -- Might be implemented in future on MacOS
- End;
- }
- {******************************************************************************
- --- Initialization ---
- ******************************************************************************}
- End.
|