fryd@g.gp.cs.cmu.edu (Michael Fryd) (10/10/89)
I am in the process of getting Scribe to run under MPW on the Mac. One of the problems I am trying to solve is how to get the full pathname from a user specified partial pathname that starts with multiple ':'s? The syntax "::folderb:filename" is like the Unix "../folderb/filename", it means go up one level from the current directory, and then get filename from folderb. The standard solutions that have been posted all work in the normal case of the user specifying a simple filename of the form "filename" or ":subfolder1:subfolder2:filename", but they give strange results when the user tries "::folderb:filename". The file manager understands this syntax. If the default directory is "HD:foldera" then a filename of "::folderb:filename" correctly gets the file "HD:folderb:filename", however all of the standard routines for getting the full pathname return "HD:foldera::folderb:filename". Although "HD:foldera::folderb:filename" is a correct path to the file, I would like to supply the more compact "HD:Folderb:filename". Is there any way to get the real filename and directory name for an open file? I would like to avoid trying to parse the filename myself, If I can get the Mac to tell me where the file is, Scribe will have a better chance of working when system 7 comes out. Thanks Michael Fryd (412) 751-5557 MEFCO, Inc. Fax: (412) 751-8403 2401 Coulter Road Arpa: Michael.Fryd@cs.cmu.edu McKeesport, PA 15131-4251
chewy@apple.com (Paul Snively) (10/11/89)
In article <6464@pt.cs.cmu.edu> fryd@g.gp.cs.cmu.edu (Michael Fryd) writes: > Is there any way to get the real filename and directory name for an open > file? I would like to avoid trying to parse the filename myself, If > I can get the Mac to tell me where the file is, Scribe will have a better > chance of working when system 7 comes out. > > Thanks > Michael Fryd (412) 751-5557 > MEFCO, Inc. Fax: (412) 751-8403 > 2401 Coulter Road Arpa: Michael.Fryd@cs.cmu.edu > McKeesport, PA 15131-4251 If you really want the best chance of working properly in the future, don't use pathnames internally; convert them to volumename/dirID/filename form and use that internally. And if you know you're running under System 7 or later, you may or may not wish to use the fileID. __________________________________________________________________________ Just because I work for Apple Computer, Inc. doesn't mean that they believe what I believe or vice-versa. __________________________________________________________________________
zebolskyd@yvax.byu.edu (10/14/89)
In article <4665@internal.Apple.COM>, chewy@apple.com (Paul Snively) writes: >In article <6464@pt.cs.cmu.edu> fryd@g.gp.cs.cmu.edu (Michael Fryd) writes: >> Is there any way to get the real filename and directory name for an open >> file? I would like to avoid trying to parse the filename myself, If >> I can get the Mac to tell me where the file is, Scribe will have a better >> chance of working when system 7 comes out. >> >> Thanks >> Michael Fryd (412) 751-5557 >> MEFCO, Inc. Fax: (412) 751-8403 >> 2401 Coulter Road Arpa: Michael.Fryd@cs.cmu.edu >> McKeesport, PA 15131-4251 > >If you really want the best chance of working properly in the future, >don't use pathnames internally; convert them to volumename/dirID/filename >form and use that internally. And if you know you're running under System 7 >or later, you may or may not wish to use the fileID. If you want the _user_ to be able to see the pathname (and find their way to the file) you can use PBGetWDInfo to get the dirID from your working directory, then PBGetCatInfo to get that directory's parent's dirID, and so on until to get to dirID=2, which will be the root. You get the names along the way from ioNamePtr. That's also how I get the volume name for the volumename/dirID/filename resource I use to save a file's location for future _machine_ use. I can send you Modula-2 source code if you want, but you would probably be better off making your _own_ mistakes instead of trying to find mine. --Lyle D. Gunderson zebolskyd@yvax.byu.edu CIS: 73760,2354
al@crucible.UUCP (Al Evans) (10/16/89)
In article <850zebolskyd@yvax.byu.edu> zebolskyd@yvax.byu.edu writes: >If you want the _user_ to be able to see the pathname (and find their way to >the file) you can use PBGetWDInfo to get the dirID from your working >directory, then PBGetCatInfo to get that directory's parent's dirID, and >so on until to get to dirID=2, which will be the root. You get the names ^^^^^^^ Although this seems to be true, it doesn't seem to be documented :-( >along the way from ioNamePtr. That's also how I get the volume name for >the volumename/dirID/filename resource I use to save a file's location >for future _machine_ use. I can send you Modula-2 source code if you want, >but you would probably be better off making your _own_ mistakes instead >of trying to find mine. > >--Lyle D. Gunderson zebolskyd@yvax.byu.edu CIS: 73760,2354 There are MANY good reasons for never using full pathnames in a Mac application. But I, too, have stumbled across situations where it was absolutely necessary. I found that the technique recommended above works, but was unable to find any guarantee that the root directory would ALWAYS have dirID=2. As far as I can tell, the following routine does not rely upon anything undocumented: -----cut about here-------- { Returns full pathname to folder specified by startID in thePath, where startID is the vRefNum/wdRefNum returned by SFGetFile or SFPutFile } PROCEDURE GetCurrentPath (startID : INTEGER; VAR thePath : Str255); VAR tempName : Str255; vParams : CInfoPBRec; theError : OSErr; BEGIN thePath := ''; tempName := ''; WITH vParams DO BEGIN ioCompletion := NIL; ioNamePtr := @tempName; ioVRefNum := startID; ioFDirIndex := -1; ioDrDirID := 0; REPEAT theError := PBGetCatInfo(@vParams, FALSE); IF (theError = noErr) THEN BEGIN ioDRDirID := ioDRParID; thePath := concat(tempName, ':', thePath); tempName := ''; END; UNTIL (theError <> noErr); END; END; --------cut somewhere near here, too------------- --Al Evans-- -- Al Evans "You'd grep to know what ...uunet!execu!sequoia!crucible!al you really sed." --Referent Blob
keith@Apple.COM (Keith Rollin) (10/16/89)
In article <111@crucible.UUCP> al@crucible.UUCP (Al Evans) writes: >In article <850zebolskyd@yvax.byu.edu> zebolskyd@yvax.byu.edu writes: > >>If you want the _user_ to be able to see the pathname (and find their way to >>the file) you can use PBGetWDInfo to get the dirID from your working >>directory, then PBGetCatInfo to get that directory's parent's dirID, and >>so on until to get to dirID=2, which will be the root. You get the names > ^^^^^^^ > Although this seems to be true, it doesn't seem to be documented :-( This *IS* documented. Check out the top of page 92 of Inside Mac IV. In add- ition, this is the technique used in Technote #238 and DTS Sample Code #18: Standard File. Finally, there is a constant defined in the MPW headers (fsRtDirID) that identifies the root as 2. On the other hand, I, too, have a hard time relying on this bit of information. Your alternate technique may have merit; I'll have to take a look at it. I'd probably base my exit condition on a specific error rather than just any old error, but so far it looks pretty good. -- ------------------------------------------------------------------------------ Keith Rollin --- Apple Computer, Inc. --- Developer Technical Support INTERNET: keith@apple.com UUCP: {decwrl, hoptoad, nsc, sun, amdahl}!apple!keith "Argue for your Apple, and sure enough, it's yours" - Keith Rollin, Contusions
spencer@heinlein.osc.edu (Stephen N. Spencer) (10/16/89)
In article <111@crucible.UUCP> al@crucible.UUCP (Al Evans) writes: >In article <850zebolskyd@yvax.byu.edu> zebolskyd@yvax.byu.edu writes: > >>If you want the _user_ to be able to see the pathname (and find their way to >>the file) you can use PBGetWDInfo to get the dirID from your working >>directory, then PBGetCatInfo to get that directory's parent's dirID, and >>so on until to get to dirID=2, which will be the root. You get the names > ^^^^^^^ > Although this seems to be true, it doesn't seem to be documented :-( > Apple seems to use it (the dirID == 2 test for checking for root directory): look at their sample code concering the Standard File Package. While not hard documentation, it does lend some validity to the test. -=- Stephen N. Spencer |"For a successful technology, reality must take ACCAD, 1224 Kinnear Rd. | precedence over public relations, for Nature Columbus OH 43212 | cannot be fooled." - Richard P. Feynman spencer@heinlein.cgrg.ohio-state.edu OR spencer@cis.ohio-state.edu
al@crucible.UUCP (Al Evans) (10/16/89)
In article <35671@apple.Apple.COM> keith@Apple.COM (Keith Rollin) writes: >In article <111@crucible.UUCP> al@crucible.UUCP (Al Evans) writes: >>In article <850zebolskyd@yvax.byu.edu> zebolskyd@yvax.byu.edu writes: >> >>>so on until to get to dirID=2, which will be the root. You get the names >> ^^^^^^^ >> Although this seems to be true, it doesn't seem to be documented :-( > >This *IS* documented. Check out the top of page 92 of Inside Mac IV. In add- >ition, this is the technique used in Technote #238 and DTS Sample Code #18: >Standard File. Finally, there is a constant defined in the MPW headers >(fsRtDirID) that identifies the root as 2. You're right on all counts. Shows how much Mac programming I've been doing recently. But STILL, I don't trust magic numbers, and prefer to find alternate solutions -- while I can imagine the dirID of the root directory changing, I suspect that trying to get information about its parent will ALWAYS return an error. >I'd probably base my exit condition on a specific error rather >than just any old error, but so far it looks pretty good. That's probably a good plan -- though if the routine fails for any reason OTHER than reaching the top of the directory tree, your application is in REALLY serious trouble. --Al Evans-- -- Al Evans "You'd grep to know what ...uunet!execu!sequoia!crucible!al you really sed." --Referent Blob
zben@umd5.umd.edu (Ben Cranston) (10/17/89)
In article <6464@pt.cs.cmu.edu> fryd@g.gp.cs.cmu.edu (Michael Fryd) writes: > ... any way to get the real filename and directory name for an open file. Emphasis added ^^^^ Cleaning up my desk last week I came upon a printed listing of the attached subroutine. It occurs to me that this could also be an answer to the question often asked on this forum "how can I get back to the DATA FORK of the file in whose RESOURCE FORK the currently executing program lives?". I guess you could apply this routine to the current resource file path reference number (hopefully before ever opening any OTHER resource files :-). Extend this program to (if HFS is running) utilize the fcbDirID field which should contain the long word directory ID of the directory in which the open file exists, and fcbCName which contains the file name. Please see diagram on page IV-180 for these fields. The program, as stands, makes use of the fcbVPtr field which is there in both HFS and MFS FCBs. Please note also that the volume name is available at vcbVN in the volume control block. * Err = GetVRefNum(PathRef, Var VolRef); * Given a path reference number, return reference number for the volume * on which the file resides. * * This code KNOWS that the path reference number is really an offset into a * system heap block containing the File Control Blocks. It performs a few * sanity checks (detailed below). * * Examines incore FCB (II-127) and VCB (II-125). * GetVRefNum Entry ; Move.L (A7)+,A1 ; Pop return address * * Two sanity checks are performed on the PathRefNum. One, the modulo residue * should be 2 (because of the length word at the beginning). Two, the RefNum * should be less than the length of the FCB buffer. * Move.L #0,D1 ; Clear slack bits Move.W 4(A7),D1 ; Get PathRefNum argument Move.L FCBSPtr,A0 ; Get pointer to FCB block Move.W FSFCBLen,D0 ; HFS flag/length of entry BMi.S @010 ; If MFS go use constant DivU.W D0,D1 ; Compute mod of pointer Bra.S @020 ; Go check remainder @010 ; DivU.W #94,D1 ; MFS constant FCB size ??? @020 ; Swap D1 ; Get remainder of division Sub.W #2,D1 ; Allow for length word BNE.S @030 ; If not zero then error * Move.W 4(A7),D0 ; Get PathRefNum argument Cmp.W (A0),D0 ; Within size of buffer? BHS.S @030 ; If not then error * * Sanity checks passed, link to FCB and VCB. * Move.L fcbVPtr(A0,D0.W),A0 ; Link to volume control block Move.W vcbVRefNum(A0),D0 ; Get Volume RefNum Move.L #0,D1 ; Clear error code Bra.S @040 ; Return to caller * * Error in input PathRefNum. * @030 ; Move.L #0,D0 ; Return zero to caller Move.W #$FFCD,D1 ; Get error code * @040 ; Move.L (A7),A0 ; Get address of VRefNum argument Move.W D0,(A0) ; Set vRefNum argument Add.W #6,A7 ; Pop arguments Move.W D1,(A7) ; Set function result Jmp (A1) ; Return to caller * End ; GetVRefNum I probably disassembled this from some program. I have no idea what the #94 is all about, according to II-127 the number should be 30!!! Could anybody who knows the right number correct this? It wouldn't be that hard to do this in either Pascal or C... -- Sig DS.L ('ZBen') ; Ben Cranston <zben@Trantor.UMD.EDU> * Computer Science Center Network Infrastructures Group * University of Maryland at College Park
zebolskyd@yvax.byu.edu (10/18/89)
In article <111@crucible.UUCP> al@crucible.UUCP (Al Evans) writes: >In article <850zebolskyd@yvax.byu.edu> zebolskyd@yvax.byu.edu writes: > >>If you want the _user_ to be able to see the pathname (and find their way to >>the file) you can use PBGetWDInfo to get the dirID from your working >>directory, then PBGetCatInfo to get that directory's parent's dirID, and >>so on until to get to dirID=2, which will be the root. You get the names > ^^^^^^^ > Although this seems to be true, it doesn't seem to be documented :-( > This _is_ documented, Al, old chum. In IM vol. IV. Where else would a rank amateur like myself get such information? The reference to the dirID=2 included the word "always" so I thought it sounded safe to use. The information was somewhere in the introductory description of HFS, where paths, etc., are discussed. Page IV-92, line 2. Still, the algorithm presented earlier, which watched for errors instead, has the merit that if Apple does not define "always" as I do, it will still work. Thanks for the information, people! --Lyle D. Gunderson zebolskyd@yvax.byu.edu