appletfolder.c

Go to the documentation of this file.
00001 
00002 /*  $Id: appletfolder.c 355 2005-01-11 22:48:55Z andreradke $    */
00003 
00004 /* copyright 1991-96 UserLand Software, Inc. All Rights Reserved.*/
00005 
00006 
00007 #include <Folders.h>
00008 #include <Script.h>
00009 
00010 #include "appletdefs.h"
00011 #include "appletmemory.h"
00012 #include "appletstrings.h"
00013 #include "appletfiles.h"
00014 #include "appletfilesinternal.h"
00015 #include "appletfilealias.h"
00016 #include "appletfiledelete.h"
00017 #include "appletfolder.h"
00018 
00019 
00020 
00021 static struct {
00022     
00023     FSSpec *fsfile; 
00024     
00025     FSSpec fsalias;
00026     
00027     boolean fl;
00028 } foldercontains;
00029 
00030 
00031 boolean diskloop (tyfileloopcallback diskcallback, long refcon) {
00032     
00033     /*
00034     dmb 9/21/93: filegetvolumeinfo takes a vRefNum, not a string.
00035     */
00036     
00037     HVolumeParam pb;
00038     short ix;
00039     
00040     clearbytes (&pb, longsizeof (pb)); /*init all fields to zero*/
00041     
00042     ix = 1; /*start with file index 1*/
00043     
00044     while (true) {
00045         
00046         bigstring bsvolume;
00047         tyfileinfo info;
00048         OSErr errcode;
00049         
00050         pb.ioVolIndex = ix++;
00051         
00052         pb.ioNamePtr = bsvolume;
00053         
00054         errcode = PBHGetVInfoSync ((HParmBlkPtr) &pb);
00055         
00056         if (errcode == nsvErr) /*not an error, just ran out of volumes*/
00057             return (true);
00058             
00059         if (fileerror (nil, errcode)) 
00060             return (false);
00061         
00062         filegetvolumeinfo (pb.ioVRefNum, &info);
00063         
00064         if (!(*diskcallback) (bsvolume, &info, refcon))
00065             return (false);
00066         } /*while*/
00067     } /*diskloop*/
00068     
00069     
00070 boolean folderloop (ptrfilespec pfs, boolean flreverse, tyfileloopcallback filecallback, long refcon) {
00071     
00072     /*
00073     loop through all of the files in the folder at fs, and call filecallback 
00074     for each one.
00075     
00076     if flreverse is true, loop through files backwards to allow for deletions
00077     
00078     DW 8/28/93: inexplicably, getmacfileinfo is determining that ctfiles is 1
00079     greater than the actual number of files in our folder (it's the History
00080     folder in clayhistorymenu.c). the way the loop was structured, we visit
00081     no files in the folder in this case. changed it so that on fnfErr we 
00082     continue the loop. the next time thru it will find a file. hope this
00083     doesn't break anything else (it shouldn't).
00084     */
00085     
00086     FSSpec fs = *pfs; /*work with a copy*/
00087     CInfoPBRec pb;
00088     long dirid;
00089     bigstring bsfile;
00090     short ix;
00091     long ctfiles;
00092     tyfileinfo info;
00093     OSErr ec;
00094     
00095     setfileerrorfile (pfs); 
00096     
00097     if (!getmacfileinfo (&fs, &pb))
00098         return (false);
00099         
00100     assert (BitTst (&pb.dirInfo.ioFlAttrib, 3)); /*be sure it's a folder*/
00101     
00102     dirid = pb.dirInfo.ioDrDirID; /*must remember this for loop body*/
00103     
00104     ctfiles = pb.dirInfo.ioDrNmFls;
00105     
00106     if (flreverse)
00107         ix = ctfiles;
00108     else
00109         ix = 1; /*start with file index 1*/
00110     
00111     while (--ctfiles >= 0) {
00112         
00113         pb.dirInfo.ioDrDirID = dirid; /*may be smashed by ioFlNum on previous loop*/
00114         
00115         pb.dirInfo.ioFDirIndex = ix;
00116         
00117         if (flreverse)
00118             --ix;
00119         else
00120             ++ix;
00121         
00122         pb.dirInfo.ioNamePtr = bsfile;
00123         
00124         ec = PBGetCatInfoSync (&pb);
00125         
00126         if (ec == fnfErr) /*DW 8/28/93: continue instead of returning true*/
00127             continue; 
00128             
00129         if (fileerror (nil, ec)) 
00130             return (false);
00131         
00132         filegetinfofrompb (&pb, &info);
00133         
00134         if (!(*filecallback) (bsfile, &info, refcon))
00135             return (false);
00136         } /*while*/
00137         
00138     return (true);
00139     } /*folderloop*/
00140 
00141 
00142 static boolean foldercontainsaliascallback (bigstring fname, tyfileinfo *info, long pxinfo) {
00143     
00144     FSSpec fs, fsalias;
00145     
00146     if (!(*info).flalias) /*keep searching*/
00147         return (true);
00148         
00149     filemakespec ((*info).vnum, (*info).dirid, fname, &fs);
00150     
00151     fsalias = fs;
00152     
00153     fileresolvealias (&fs, true);
00154     
00155     if (equalfilespecs (&fs, foldercontains.fsfile)) {
00156         
00157         foldercontains.fl = true;
00158         
00159         foldercontains.fsalias = fsalias;
00160         
00161         return (false);
00162         }
00163         
00164     return (true);
00165     } /*foldercontainsaliascallback*/
00166     
00167     
00168 boolean foldercontainsalias (FSSpec *fsfolder, FSSpec *fsfile, FSSpec *fsalias) {
00169     
00170     /*
00171     return true if the folder contains an alias to the file, or if the file
00172     itself is in the folder.
00173     */
00174     
00175     clearbytes (&foldercontains, longsizeof (foldercontains));
00176     
00177     foldercontains.fl = false;
00178     
00179     foldercontains.fsfile = fsfile;
00180     
00181     folderloop (fsfolder, false, &foldercontainsaliascallback, 0);
00182     
00183     if (foldercontains.fl) {
00184     
00185         *fsalias = foldercontains.fsalias;
00186         
00187         return (true);
00188         }
00189         
00190     return (false);
00191     } /*foldercontainsalias*/
00192     
00193 
00194 boolean getfolderfilespec (short vnum, long dirid, FSSpec *fsfolder) {
00195     
00196     return (filemakespec (vnum, dirid, "\p", fsfolder));
00197     } /*getfolderfilespec*/
00198     
00199     
00200 boolean filegetparentfolderspec (FSSpec *fsfile, FSSpec *fsfolder) {
00201     
00202     return (getfolderfilespec ((*fsfile).vRefNum, (*fsfile).parID, fsfolder));
00203     } /*filegetparentfolderspec*/
00204     
00205     
00206 boolean getsystemfolderfilespec (OSType subfolderid, FSSpec *fsfolder) {
00207 
00208     OSErr ec;
00209     short vnum;
00210     long dirid;
00211     
00212     ec = FindFolder (kOnSystemDisk, subfolderid, kDontCreateFolder, &vnum, &dirid);
00213     
00214     if (fileerror (nil, ec)) 
00215         return (false);
00216         
00217     return (getfolderfilespec (vnum, dirid, fsfolder));
00218     } /*getsystemfolderfilespec*/
00219     
00220     
00221 boolean systemfoldercontainsalias (OSType subfolderid, FSSpec *fsfile) {
00222     
00223     /*
00224     return true if the specified sub-folder of the system folder contains
00225     an alias to the file or the file itself.
00226     */
00227     
00228     FSSpec fsfolder, fsalias;
00229     
00230     if (!getsystemfolderfilespec (subfolderid, &fsfolder))
00231         return (false);
00232         
00233     return (foldercontainsalias (&fsfolder, fsfile, &fsalias));
00234     } /*systemfoldercontainsalias*/
00235 
00236 
00237 boolean addaliastospecialfolder (FSSpec *fsorig, OSType subfolderid) {
00238 
00239     FSSpec fsfolder, fsalias;
00240     bigstring fname;
00241     long folderid;
00242     
00243     if (!getsystemfolderfilespec (subfolderid, &fsfolder))
00244         return (false);
00245 
00246     filegetfilename (fsorig, fname);
00247     
00248     filegetfolderid (&fsfolder, &folderid);
00249     
00250     filemakespec (fsfolder.vRefNum, folderid, fname, &fsalias);
00251         
00252     return (filemakealias (fsorig, &fsalias));
00253     } /*addaliastospecialfolder*/
00254     
00255 
00256 static boolean deletealiasescallback (bigstring fname, tyfileinfo *info, long refcon) {
00257     
00258     FSSpec *fslookfor = (FSSpec *) refcon;
00259     FSSpec fs, fsdereferenced;
00260     
00261     if (!(*info).flalias) /*keep searching*/
00262         return (true);
00263         
00264     filemakespec ((*info).vnum, (*info).dirid, fname, &fs);
00265     
00266     fsdereferenced = fs;
00267     
00268     fileresolvealias (&fsdereferenced, true);
00269     
00270     if (equalfilespecs (&fsdereferenced, fslookfor))        
00271         filedelete (&fs);
00272         
00273     return (true);
00274     } /*deletealiasescallback*/
00275     
00276     
00277 boolean deletealiasesfromfolder (FSSpec *fsorig, FSSpec *fsfolder) {
00278     
00279     /*
00280     delete all aliases that point to the file from the indicated folder.
00281     */
00282     
00283     folderloop (fsfolder, true, &deletealiasescallback, (long) fsorig);
00284     
00285     return (true);
00286     } /*deletealiasesfromfolder*/
00287 
00288     
00289 boolean deletealiasesfromspecialfolder (FSSpec *fsorig, OSType subfolderid) {
00290 
00291     FSSpec fsfolder;
00292     
00293     if (!getsystemfolderfilespec (subfolderid, &fsfolder))
00294         return (false);
00295     
00296     return (deletealiasesfromfolder (fsorig, &fsfolder));
00297     } /*deletealiasesfromspecialfolder*/
00298 
00299     
00300 boolean filecreatefolder (ptrfilespec fsfolder) {
00301     
00302     OSErr ec;
00303     long folderid;
00304     
00305     ec = FSpDirCreate (fsfolder, smSystemScript, &folderid);
00306     
00307     return (true);
00308     } /*filecreatefolder*/
00309     
00310     
00311 boolean filegetfolderid (ptrfilespec fsfolder, long *dirid) {
00312     
00313     CInfoPBRec pb;
00314 
00315     if (!getmacfileinfo (fsfolder, &pb))
00316         return (false);
00317         
00318     *dirid = pb.dirInfo.ioDrDirID; 
00319     
00320     return (true);
00321     } /*filegetfolderid*/
00322 
00323 
00324 boolean filegetsubitemspec (FSSpec *fsfolder, bigstring fname, FSSpec *fssubitem) {
00325     
00326     /*
00327     dmb 9/20/93: must return false if filemakespec returns false
00328     */
00329     
00330     long dirid;
00331     
00332     if (!filegetfolderid (fsfolder, &dirid))
00333         return (false);
00334     
00335     return (filemakespec ((*fsfolder).vRefNum, dirid, fname, fssubitem));
00336     } /*filegetsubitemspec*/
00337     
00338     
00339 boolean filesetfolderview (FSSpec *fsfolder, short folderview) {
00340     
00341     /*
00342     DW 9/6/93: the parameter is a short, to save space in clayinfowindow.c. it 
00343     allows us to use the same callback routine as for other shorts.
00344     */
00345 
00346     CInfoPBRec pb;
00347 
00348     if (!getmacfileinfo (fsfolder, &pb))
00349         return (false);
00350         
00351     pb.dirInfo.ioDrUsrWds.frView = (pb.dirInfo.ioDrUsrWds.frView & 0xFF) + (folderview << 8);
00352     
00353     return (setmacfileinfo (fsfolder, &pb));
00354     } /*filesetfolderview*/
00355     
00356     
00357 boolean fileemptyfolder (FSSpec *fsfolder) {
00358     
00359     return (folderloop (fsfolder, true, &filedeletevisit, 0));
00360     } /*fileemptyfolder*/
00361     
00362     
00363 boolean foldercontainsfile (FSSpec *fsfolder, FSSpec *fsfile) {
00364     
00365     long dirid;
00366     
00367     if ((*fsfolder).vRefNum != (*fsfile).vRefNum)
00368         return (false);
00369         
00370     filegetfolderid (fsfolder, &dirid);
00371     
00372     if ((*fsfile).parID == dirid)
00373         return (true);
00374         
00375     return (false);
00376     } /*foldercontainsfile*/
00377     
00378 
00379 static boolean flushvolumevisit (bigstring bsitem, tyfileinfo *info, long refcon) {
00380     
00381     OSErr ec;
00382     
00383     ec = FlushVol (nil, (*info).vnum);
00384     
00385     return (true); /*even if error, want to visit all the volumes*/
00386     } /*flushvolumevisit*/
00387     
00388     
00389 boolean fileflushvolumes (void) {
00390     
00391     return (diskloop (&flushvolumevisit, 0));
00392     } /*fileflushvolumes*/
00393     
00394 
00395 boolean filesurefolder (ptrfilespec pfs) {
00396     
00397     bigstring bs;
00398     extern void alertdialog (bigstring);
00399     
00400     if (fileexists (pfs))
00401         return (true);
00402     
00403     if (filecreatefolder (pfs))
00404         return (true);
00405     
00406     copystring ("\pFile system error -- can't create a folder named \"", bs);
00407     
00408     pushstring ((*pfs).name, bs);
00409     
00410     pushstring ("\p\"", bs);
00411     
00412     alertdialog (bs);
00413     
00414     return (false);
00415     } /*filesurefolder*/
00416     
00417     
00418 boolean filesuresubfolder (ptrfilespec pfsfolder, bigstring foldername, ptrfilespec pfssubfolder) {
00419 
00420     tyfilespec fsfolder = *pfsfolder; /*caller can have the two pfs's be the same thing*/
00421 
00422     if (!filegetsubitemspec (&fsfolder, foldername, pfssubfolder))
00423         return (false);
00424     
00425     return (filesurefolder (pfssubfolder));
00426     } /*filesuresubfolder*/
00427     
00428     
00429 
00430 
00431     
00432     
00433     
00434     
00435     
00436     

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