olausson@chalmers.UUCP (Stefan Olausson) (05/04/88)
Given the information in a SFReply, how do I construct the full path name of a file (as a string), i e "disk:dir1:dir2:...:filename" ? Stefan Olausson ========================================================================= E-mail: olausson@cs.chalmers.se
guido@cwi.nl (Guido van Rossum) (05/06/88)
In article <2532@chalmers.UUCP> olausson@chalmers.UUCP (Stefan Olausson) writes: >Given the information in a SFReply, how do I construct the full path name >of a file (as a string), i e "disk:dir1:dir2:...:filename" ? Here's my code. I am not posting the header file "macdefs.h" or the "dprintf" routine but you should be able to gues what's in them.; or ask me to mail them. This was tested with MPW. /* GET FULL PATHNAME OF A FILE. Public Domain by Guido van Rossum, CWI, Amsterdam. May 1988. */ #include "macwin.h" /* Mac file system parameters */ #define MAXPATH 256 /* Max path name length+1 */ #define SEP ':' /* Separator in path names */ #define ROOTID 2 /* DirID of a volume's root directory */ /* Macro to find out whether we can do HFS-only calls: */ #define FSFCBLen (* (short *) 0x3f6) #define hfsrunning() (FSFCBLen > 0) char * getdirname(dir) long dir; /* WDRefNum */ { union { HFileInfo f; DirInfo d; WDPBRec w; VolumeParam v; } pb; static char cwd[2*MAXPATH]; char namebuf[MAXPATH]; short err; long dirid= 0; char *next= cwd + sizeof cwd - 1; int len; if (!hfsrunning()) return ""; for (;;) { pb.d.ioNamePtr= namebuf; pb.d.ioVRefNum= dir; pb.d.ioFDirIndex= -1; pb.d.ioDrDirID= dirid; err= PBGetCatInfo(&pb.d, FALSE); if (err != noErr) { dprintf("PBCatInfo err %d", err); return NULL; } *--next= SEP; len= namebuf[0]; /* There is no overflow check on cwd here! */ strncpy(next -= len, namebuf+1, len); if (pb.d.ioDrDirID == ROOTID) break; dirid= pb.d.ioDrParID; } return next; } void fullpath(buf, wdrefnum, file) char *buf; int wdrefnum; char *file; { strcpy(buf, getdirname(wdrefnum)); strcat(buf, file); } -- Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam guido@piring.cwi.nl or mcvax!piring!guido or guido%piring.cwi.nl@uunet.uu.net
dorourke@polyslo.UUCP (David M. O'Rourke) (05/07/88)
In article <2532@chalmers.UUCP> olausson@chalmers.UUCP (Stefan Olausson) writes: >Given the information in a SFReply, how do I construct the full path name >of a file (as a string), i e "disk:dir1:dir2:...:filename" ? I'm not sure which one, if any, of the following tech notes gives you the information necessary. I think you need to read all of them, and then build a composit tech note yourself. Tech Note 68 Searching all directories on an HFS volume. Tech Note 69 Setting ioFDirIndex in PBGetCatInfo Calls Tech Note 107 Nulls in FileNames. Some of these tech notes might help. I've been wanting to do the same thing for a long time, but haven't had the time to wade thru the information. David M. O'Rourke +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | dorourke@polyslo | Disclaimer: All opinions in this message are mine, but | | | if you like them they can be yours too. | | | Besides I'm just a student so what do I | | | know! | |-----------------------------------------------------------------------------| | When you have to place a disclaimer in your mail you know it's a sign | | that there are TOO many Lawyer's. | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
km@cadre.dsl.PITTSBURGH.EDU (Ken Mitchum) (05/07/88)
In article <2532@chalmers.UUCP> olausson@chalmers.UUCP (Stefan Olausson) writes: >Given the information in a SFReply, how do I construct the full path name >of a file (as a string), i e "disk:dir1:dir2:...:filename" ? Be certain that you understand the difference between "working directory reference numbers", which SFReply returns, and directory ID numbers, which you will use to find the path name. (I only had to read the file manager chapter in Inside Mac Volume IV about ten times before understanding this!). Basically, you want to know the "real" volume (NOT the working directory reference number) and the "real" directory ID, which are two different things, neither of which being the working directory reference number. While you can take the "working directory reference number" from the SFReply structure and convert it into both volume and directory ID numbers, it is easier to take advantage of two global variables, CurDirStore and SFSaveDisk (see insert on page 72 of Inside Macintosh Vol IV). After any of the SF routines, these global variables are set as follows, REGARDLESS OF WHETHER THE USER CHOSE A FILE OR CANCELLED: CurDirStore = directoryID (long int) SFSaveDisk = 0 - volume (int) Thus, if the user changed directories but cancelled the operation, the above variables are set the way the user left them (to the new directory). It is convenient to keep track of these separately. The following code from MacJove shows a simple way to recover the path using these. In this case, the current directory is stored in cur_dir and current volume in cur_vol, which are set elsewhere (cur_dir - CurDirStore; cur_vol = 0 - SFSaveDisk. (This routine returns a "unix-style" path rather than a Mac-style path, using "/"). char *getwd() { DirInfo d; static char ret[255]; char nm[50], tmp[255]; ret[0] = '\0'; d.ioDrDirID = cur_dir; for(;;) { d.ioCompletion = 0; d.ioNamePtr = (StringPtr) nm; d.ioVRefNum = cur_vol; d.ioFDirIndex = -1; PBGetCatInfo(&d,0); if(d.ioResult != noErr) return(0); PtoCstr((char *) nm); strcpy(tmp,ret); strcpy(ret,"/"); strcat(ret,nm); strcat(ret,tmp); if(d.ioDrDirID == 2) break; /* home directory */ d.ioDrDirID = d.ioDrParID; } return(ret); } -Ken Mitchum Decision Systems Laboratories University of Pittsburgh km@cadre.dsl.pittsburgh.edu
guido@cwi.nl (Guido van Rossum) (05/08/88)
I posted a routine to get the full pathname of a file. It had been working for some months. But it still contained a bug, which became apparent when I switched from MPW to LightspeedC this weekend. The parameter to getdirname should be an int, not a long! Also I can now tell you what include files you need for LSC: #include <HFS.h> #define NULL 0 Note that it is perfectly legal for a Macintosh owner to create a directory hierarchy where the length of full path names of the deepest files exceeds 255 bytes; since the file system never manipulates full pathnames internally (it only ever sees them when passed as parameters), it doesn't and needn't check. However, this poses an ethical problem if you are constructing full pathnames: my code simply bombs if it would construct a pathname >255 bytes, and if I increased the buffer size, the resulting pathnames are useless except for documentation purposes (since the file system can't have string parameters >255 bytes). -- Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam guido@piring.cwi.nl or mcvax!piring!guido or guido%piring.cwi.nl@uunet.uu.net
wetter@tybalt.caltech.edu (Pierce T. Wetter) (05/09/88)
>it doesn't and needn't check. However, this poses an ethical problem if >you are constructing full pathnames: my code simply bombs if it would >construct a pathname >255 bytes, and if I increased the buffer size, the >resulting pathnames are useless except for documentation purposes (since >the file system can't have string parameters >255 bytes). I'm assuming you have some special file your application needs to look at which for some reason you don't want to save with your application in the data fork. You want this file to be located somewhere other then the same folder as the application or the system folder. Two ways to do this: If you can't find the file put up an sfgetfile box and ask the user where it is. Then save the pathname in a str resource. If its longer then 255 bytes, your application will just keep making the user find it each time. Or, if the pathname is longer then 255 bytes, save it in pieces and wander down the heiarchy each time you need to find the file. Pierce Wetter. ---------------------------------------------------------------- wetter@tybalt.caltech.edu Race For Space Grand Prize Winner. ----------------------------------------------------------------- Useless Advice #986: Never sit on a Tack.
guido@cwi.nl (Guido van Rossum) (05/10/88)
In article <6464@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes: >[replying to what I wrote about full path names >255 bytes:] > I'm assuming you have some special file your application needs to look at >which for some reason you don't want to save with your application in the >data fork. You want this file to be located somewhere other then the same >folder as the application or the system folder. >[tricks how to do it right omitted] In fact I was just replying to somebody asking "how do I compute the full path name of a file?". God knows why they need it. I know several programs which put the full path name of a file in the window title when editing it (however they usually replace the middle with "..." if it becomes too large). Personally, I use the code because I am porting non-Mac programs to the Mac; these programs ask the user for a file name and then open it using fopen(3). I replace the piece of code that asks for a file name with a routine call which uses SF{Get,Put}File and converts the file found to an absolute path name. I can't return the relative path name and set the default directory because the program will remember the file name for a very long time. -- Guido van Rossum, Centre for Mathematics and Computer Science (CWI), Amsterdam guido@piring.cwi.nl or mcvax!piring!guido or guido%piring.cwi.nl@uunet.uu.net
darin@Apple.COM (Darin Adler) (05/10/88)
In article <6464@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes: > I'm assuming you have some special file your application needs to look at > which for some reason you don't want to save with your application in the > data fork. You want this file to be located somewhere other then the same > folder as the application or the system folder. > > Two ways to do this: If you can't find the file put up an sfgetfile box > and ask the user where it is. Then save the pathname in a str resource. If its > longer then 255 bytes, your application will just keep making the user find > it each time. > > Or, if the pathname is longer then 255 bytes, save it in pieces and wander > down the heiarchy each time you need to find the file. Developer Technical Support recommends this solution: Save the volume name, dirID of the directory containing the file, and file name. If the file is not where you expect it, use SFGetFile to have the user find it. This has a number of advantages. First of all, dirIDs are guaranteed to be unique for a volume. No dirID is ever reused. DirIDs also remain the same, even if one of the directories in the path down to the file is renamed. I can't really think of ANY good reason to calculate the full path name, except perhaps to display on the screen for some advanced users. -- Darin Adler AppleLink:Adler4 UUCP: {sun,voder,nsc,mtxinu,dual}!apple!darin CSNET: darin@Apple.com
lsr@Apple.COM (Larry Rosenstein) (05/17/88)
In article <6464@cit-vax.Caltech.Edu> wetter@tybalt.caltech.edu.UUCP (Pierce T. Wetter) writes: > > Two ways to do this: If you can't find the file put up an sfgetfile box >and ask the user where it is. Then save the pathname in a str resource. If its >longer then 255 bytes, your application will just keep making the user find >it each time. The problem with saving a pathname is that it is very easy for the user to change one folder along the path. An alternative is to save the dirID of the folder. The dirID is unique and won't change unless the disk is reformatted, which is hopefully less often than a folder changes name. If you can't find the file, then put up the sfgetfile box. (The program might first look in some standard places such as the same folder as the application and the system folder.) (I have heard that some implementations of AppleTalk Filing Protocol on non-Macs don't save unique dirIDs on the server. They create dirIDs as needed, and these are only valid as long as you are logged in. If this is true, then my idea won't work well to locate files on those kinds of servers.) -- Larry Rosenstein, Object Specialist Apple Computer, Inc. 20525 Mariani Ave, MS 27-AJ Cupertino, CA 95014 AppleLink:Rosenstein1 domain:lsr@Apple.COM UUCP:{sun,voder,nsc,decwrl}!apple!lsr