filepath.c

Go to the documentation of this file.
00001 
00002 /*  $Id: filepath.c 1208 2006-04-05 23:51:45Z karstenw $    */
00003 
00004 /******************************************************************************
00005 
00006     UserLand Frontier(tm) -- High performance Web content management,
00007     object database, system-level and Internet scripting environment,
00008     including source code editing and debugging.
00009 
00010     Copyright (C) 1992-2004 UserLand Software, Inc.
00011 
00012     This program is free software; you can redistribute it and/or modify
00013     it under the terms of the GNU General Public License as published by
00014     the Free Software Foundation; either version 2 of the License, or
00015     (at your option) any later version.
00016 
00017     This program is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020     GNU General Public License for more details.
00021 
00022     You should have received a copy of the GNU General Public License
00023     along with this program; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 
00026 ******************************************************************************/
00027 
00028 #include "frontier.h"
00029 #include "standard.h"
00030 
00031 #include "error.h"
00032 #include "memory.h"
00033 #include "strings.h"
00034 #include "ops.h"
00035 #include "file.h"
00036 #include "launch.h" /* 2005-07-18 creedon */ 
00037 
00038 
00039 #define flaux false /*if true, we're running under the A/UX operating system*/
00040 
00041 
00042 #ifdef MACVERSION
00043 
00044 static FSSpec fsdefault = {0}; /*we maintain our own default directory*/
00045 
00046 boolean directorytopath (long DirID, short vnum, bigstring path) {
00047     
00048     CInfoPBRec block;
00049     bigstring bsdirectory;
00050     OSErr errcode;
00051     
00052     setemptystring (path);
00053     
00054     clearbytes (&block, longsizeof (block));
00055     
00056     block.dirInfo.ioNamePtr = bsdirectory;
00057     
00058     block.dirInfo.ioDrParID = DirID;
00059     
00060     do {
00061         block.dirInfo.ioVRefNum = vnum;
00062         
00063         block.dirInfo.ioFDirIndex = -1;
00064         
00065         block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
00066         
00067         errcode = PBGetCatInfoSync (&block);
00068         
00069         if (errcode != noErr)
00070             return (false);
00071         
00072         if (flaux) {
00073             if (bsdirectory[1] != '/')
00074                 if (!pushchar ('/', bsdirectory))
00075                     return (false);
00076             } 
00077         else 
00078             if (!pushchar (':', bsdirectory))
00079                 return (false);
00080             
00081         if (!pushstring (path, bsdirectory))
00082             return (false);
00083         
00084         copystring (bsdirectory, path);
00085         } while (block.dirInfo.ioDrDirID != fsRtDirID);
00086     
00087     return (true);
00088     } /*directorytopath*/
00089 
00090 #endif
00091 
00092 boolean filegetdefaultpath (tyfilespec *fs) {
00093     
00094     #ifdef MACVERSION
00095         return (!oserror (FSMakeFSSpec (fsdefault.vRefNum, fsdefault.parID, nil, fs)));
00096     #endif
00097 
00098     #ifdef WIN95VERSION
00099         DWORD sz;
00100 
00101         sz = GetCurrentDirectory (257, stringbaseaddress (fsname (fs)));
00102         
00103         if (sz == 0) {
00104             
00105             oserror (GetLastError ());
00106             
00107             return (false);
00108             }
00109         
00110         strcat (stringbaseaddress (fsname (fs)), "\\");
00111 
00112         setstringlength(fsname (fs), sz + 1);
00113         
00114         return (true);
00115     #endif      
00116     } /*filegetdefaultpath*/
00117 
00118 
00119 boolean filesetdefaultpath (const tyfilespec *fs) {
00120     
00121     #ifdef MACVERSION
00122         CInfoPBRec pb;
00123         
00124         clearbytes (&fsdefault, longsizeof (fsdefault));
00125         
00126         if (isemptystring ((*fs).name))
00127             return (true);
00128         
00129         setoserrorparam ((ptrstring) (*fs).name);
00130         
00131         clearbytes (&pb, longsizeof (pb));
00132         
00133         pb.dirInfo.ioNamePtr = (StringPtr) (*fs).name;
00134         
00135         pb.dirInfo.ioVRefNum = (*fs).vRefNum;
00136         
00137         pb.dirInfo.ioDrDirID = (*fs).parID;
00138         
00139         if (oserror (PBGetCatInfoSync (&pb)))
00140             return (false);
00141         
00142         fsdefault.vRefNum = pb.dirInfo.ioVRefNum;
00143         
00144         fsdefault.parID = pb.dirInfo.ioDrDirID;
00145 
00146         return (true);
00147     #endif
00148 
00149     #ifdef WIN95VERSION
00150         if (isemptystring (fsname (fs)))
00151             return (true);
00152         
00153         if (!SetCurrentDirectory (stringbaseaddress(fsname (fs)))) {
00154             
00155             oserror (GetLastError ());
00156             
00157             return (false);
00158             }
00159 
00160         return (true);
00161     #endif
00162     } /*filesetdefaultpath*/
00163 
00164 
00165 boolean filespectopath (const tyfilespec *fs, bigstring bspath) {
00166     
00167     /*
00168     6/28/91 dmb: when you resolve an alias of a volume, the fsspec has a 
00169     parent dirid of 1.  we catch this as a special case here, and return 
00170     the empty string as the path
00171     
00172     10/14/91 dmb: make sure folder paths end in :
00173     
00174     12/17/91 dmb: don't check for folderness if file doesn't exist-- we 
00175     dont want to generate any errors here
00176     
00177     2.1a7 dmb: if it's a null filespec, return the empty string
00178     */
00179     
00180     #ifdef MACVERSION
00181         boolean flfolder;
00182         
00183         if ((*fs).parID == fsRtParID) { /*it's a volume*/
00184             
00185             copystring ((ptrstring) (*fs).name, bspath);
00186             
00187             pushchar (':', bspath);
00188             
00189             return (true);
00190             }
00191         
00192         setemptystring (bspath);
00193         
00194         if (((*fs).parID == 0) && ((*fs).vRefNum == 0) && (isemptystring ((*fs).name)))
00195             return (true);
00196         
00197         if (!directorytopath ((*fs).parID, (*fs).vRefNum, bspath))
00198             return (false);
00199         
00200         pushstring ((ptrstring) (*fs).name, bspath);
00201         
00202         if (fileexists (fs, &flfolder))
00203             if (flfolder)
00204                 assurelastchariscolon (bspath);
00205         
00206         return (true);
00207     #endif
00208 
00209     #ifdef WIN95VERSION
00210         // 5.0d12 dmb: use GetFullPath to clean up 8.3 names
00211         char * fileptr;
00212         
00213         copyptocstring (fsname (fs), bspath);
00214         
00215         GetFullPathName (bspath, lenbigstring, bspath, &fileptr);
00216 
00217         convertcstring (bspath);
00218         
00219         nullterminate (bspath);
00220 
00221         return (true);
00222     #endif
00223     } /*filespectopath*/
00224 
00225 
00226 boolean pathtofilespec (bigstring bspath, tyfilespec *fs) {
00227     
00228     /*
00229     7/5/91 dmb: use FSMakeFSSpec if it's available.  since it only returns 
00230     noErr if the file exists, and we want to handle non-existant files, we 
00231     don't give up right away.
00232     
00233     12/17/91 dmb: dont append path to default directory if it's a full path
00234     
00235     6/11/93 dmb: if FSMakeFSSpec returns fnfErr, the spec is cool (but file 
00236     doesn't exist)
00237     
00238     2.1b2 dmb: added special case for empty string.  also, added drive number 
00239     interpretation here.
00240     
00241     2.1b2 dmb: use new fsdefault for building filespec. note that if bspath 
00242     isn't a partial path, the vref and dirid will be ignored.
00243     */
00244     
00245     bigstring bsfolder;
00246     #ifdef MACVERSION
00247     OSErr errcode;
00248     short ix = 1;
00249     #endif
00250 
00251     clearbytes (fs, sizeof (tyfilespec));   // 5,0d8 dmb
00252 
00253     if (isemptystring (bspath))
00254         return (true);
00255     
00256     #ifdef MACVERSION
00257         errcode = FSMakeFSSpec (fsdefault.vRefNum, fsdefault.parID, bspath, fs);
00258         
00259         //for some reason if there is a trailing : you get a dirNFErr and it doesn't work
00260         //This little hack saves us. It still is a fnfErr, but it works.
00261         #if TARGET_API_MAC_CARBON
00262         if(errcode == dirNFErr)
00263         {
00264             poptrailingchars(bspath, ':');
00265             errcode = FSMakeFSSpec (fsdefault.vRefNum, fsdefault.parID, bspath, fs);
00266         }
00267         #endif  
00268         if ((errcode == noErr) || (errcode == fnfErr))
00269             return (true);
00270         
00271         if (scanstring (':', bspath, &ix) && (ix > 1)) { /*includes a colon, not the first thing*/
00272             
00273             short drivenum;
00274             
00275             midstring (bspath, 1, ix - 1, bsfolder); /*pull out volume name*/
00276             
00277             if (isallnumeric (bsfolder) && stringtoshort (bsfolder, &drivenum)) { /*it's a number*/
00278                 
00279                 midstring (bspath, ix, stringlength (bspath) - ix + 1, bsfolder);
00280                 
00281                 errcode = FSMakeFSSpec (drivenum, 0, bsfolder, fs);
00282                 
00283                 if ((errcode == noErr) || (errcode == fnfErr))
00284                     return (true);
00285                 }
00286             }   
00287         
00288         return (false);
00289     #endif
00290 
00291     #ifdef WIN95VERSION
00292         copystring (bspath, fsname (fs));
00293 
00294         folderfrompath (bspath, bsfolder);
00295 
00296         if ((isemptystring (bsfolder)) && (! fileisvolume(fs))) {
00297 
00298             filegetdefaultpath (fs);
00299 
00300             pushstring (bspath, fsname (fs));
00301             }
00302         
00303         nullterminate (fsname (fs));
00304         
00305         return (true);
00306     #endif
00307 
00308     } /*pathtofilespec*/
00309 
00310 
00311 boolean setfsfile (tyfilespec *fs, bigstring bsfile) {
00312 
00313     /*
00314     2004-10-26 aradke: Since the getmacfileinfo/foldertest gymnastics do not
00315     seem to fit any particular purpose and since none of our callers
00316     seem to rely it since they usually pass in a file rather than a directory,
00317     I commented it out.
00318         
00319     The only time we get called with a directory is apparently by
00320     shellopendefaultfile on startup in the Carbon/Mach-O build.
00321     getapplicationfilespec returns a directory in that case and
00322     the code below somehow screwed up when called to set the
00323     filename to Frontier.root so that it wouldn't be found.
00324     */
00325     
00326     #ifdef MACVERSION
00327         /*
00328         CInfoPBRec pb;
00329 
00330         if (getmacfileinfo (fs, &pb) && foldertest (&pb)) {
00331         
00332             FSMakeFSSpec ((*fs).vRefNum, pb.dirInfo.ioDrDirID, bsfile, fs);
00333             
00334             return (false);
00335             }
00336         */
00337         
00338         copystring (bsfile, (*fs).name);
00339 
00340         return (true);
00341     #endif
00342 
00343     #ifdef WIN95VERSION
00344         bigstring bsfolder;
00345         
00346         folderfrompath (fsname (fs), bsfolder);
00347         
00348         pushstring (bsfile, bsfolder);
00349 
00350         copystring (bsfolder, fsname (fs));
00351 
00352         nullterminate (fsname (fs));
00353 
00354         return (true);
00355     #endif
00356     } /*setfsfile*/
00357 
00358 
00359 boolean getfsfile (const tyfilespec *fs, bigstring bsfile) {
00360     
00361     /*
00362     5.0b9 dmb: we're needing this in a few places. better late
00363     than never
00364     */
00365     
00366     #ifdef WIN95VERSION
00367         bigstring bspath;
00368 
00369         filespectopath (fs, bspath);
00370         
00371         filefrompath (bspath, bsfile);
00372 
00373         return (true);
00374     #endif
00375     
00376     #ifdef MACVERSION
00377         copystring (fsname (fs), bsfile);
00378 
00379         return (true);
00380     #endif
00381     } /*getfsfile*/
00382 
00383 
00384 boolean getfsvolume (const tyfilespec *fs, long *vnum) {
00385     
00386     /*
00387     5.1.5b11 dmb: get the volume that is actually specified in the fspec.
00388 
00389     don't expand partial paths using the default directory.
00390     */
00391 
00392     #ifdef WIN95VERSION
00393         return (fileparsevolname ((ptrstring) fsname (fs), vnum, nil));
00394     #endif
00395     
00396     #ifdef MACVERSION
00397         HVolumeParam pb;
00398         
00399         *vnum = (*fs).vRefNum;
00400         
00401         if (*vnum == 0)
00402             return (false);
00403         
00404         clearbytes (&pb, sizeof (pb)); /*init all fields to zero*/
00405         
00406         pb.ioVRefNum = *vnum;
00407         
00408         return (PBHGetVInfoSync ((HParmBlkPtr) &pb) == noErr);
00409     #endif
00410     } /*getfsvolume*/
00411 
00412 
00413 void initfsdefault (void) {
00414     #ifdef MACVERSION
00415     /* 2005-07-18 creedon, karstenw */
00416     getapplicationfilespec (nil, &fsdefault);
00417     #endif
00418     } /* initfsdefault */
00419 

Generated on Wed May 31 18:19:47 2006 for frontierkernel 10.1.10a by  doxygen 1.4.6