home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Snippets / File Access Examples 1.0 / Scanner.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-25  |  5.2 KB  |  147 lines  |  [TEXT/KAHL]

  1. /* Scanner.c
  2.  *
  3.  * This file contains two routines which, used together, will scan
  4.  * through all files/folders on all mounted volumes on your Mac and
  5.  * take some sort of action for each file/folder found. If you
  6.  * only want to scan one volume, call ScanFolders with a volume
  7.  * reference number and a directory ID of zero.
  8.  *
  9.  * If you wanted to search a volume for a small number of files
  10.  * based on their characteristics, this is the WRONG way to do it.
  11.  * Use PBCatSearch for that purpose.
  12.  *
  13.  * If, on the other hand, you need to find ALL of the files and/or
  14.  * folders on a volume, or need to examine each (as in a virus
  15.  * scanning program), these routines can handle that just fine.
  16.  * Also, if you definitely want to scan files in alphabetical
  17.  * order (as they appear in the finder), that's the way these
  18.  * routines scan.
  19.  *
  20.  * All Macintosh files are indexed (have an index number) within
  21.  * their directory/folder. If there are five files in a folder,
  22.  * they will always have index numbers one through five. Folders
  23.  * have indexes just as files do. If the third file in the folder
  24.  * was a subfolder rather than a file, it would still have index
  25.  * number three. The routines in this file work by starting at
  26.  * the root folder of a volume and simply counting the index up
  27.  * from one getting file information based on each index number.
  28.  * Whenever a subfolder is found, the routine recurses and
  29.  * counts through the files in that subfolder.
  30.  *
  31.  * NOTE that the routines here do NOT take into account the fact
  32.  * that the indexes of files can change within a directory between
  33.  * calls to PBGetCatInfo if another process adds or deletes a file
  34.  * during that time. There are ways to get around that which
  35.  * usually involve rescanning the same directory, but the way
  36.  * you handle it depends on your purpose for scanning. For
  37.  * example, it wouldn't matter a whole lot if you scanned a few
  38.  * files twice with a virus scanner.
  39.  *
  40.  * By the way, you can tell if indexes have shifted within a
  41.  * directory by calling PBGetCatInfo a second time with the same
  42.  * index number just before moving to the next index number.
  43.  * Compare the file name returned with the file name you got
  44.  * last time you called PBGetCatInfo with that index to make
  45.  * sure they're the same. If they are, then immediately call
  46.  * PBGetCatInfo for the next index number. If they're not,
  47.  * that's when you need to rescan or whatever.
  48.  */
  49.  
  50. #include "Scanner.h"
  51.  
  52. #include "ActionRoutines.h"        /* This file contains the routines   */
  53.                                 /* FolderAction and FileAction       */
  54.                                 /* which are simply example routines */
  55.                                 /* that write to a file opened in    */
  56.                                 /* the main routine. */
  57.  
  58. /* ScanVolumes loops and finds all mounted volumes (up to 256) and
  59.  * calls ScanFolders to scan all files and folders on each volume
  60.  * found.
  61.  */
  62. void    ScanVolumes( void )
  63. {
  64.     HParamBlockRec    pb;        /* an HFS parameter block */
  65.     short    x;
  66.     Str31    volumeName;
  67.     
  68.     pb.volumeParam.ioCompletion = NULL;        /* no completion routine */
  69.     pb.volumeParam.ioNamePtr = volumeName;    /* assign storage for name */
  70.     pb.volumeParam.ioVRefNum = 0;
  71.     
  72.     for ( x=1; x<=256; x++ )        /* loop through volume indexes */
  73.     {
  74.         pb.volumeParam.ioVolIndex = x;
  75.         PBHGetVInfo( &pb, false );
  76.         if ( pb.volumeParam.ioResult != noErr )
  77.         {
  78.             /* Error means no more mounted volumes */
  79.             
  80.             break;    /* break out of the for loop */
  81.         }
  82.         else
  83.         {
  84.             /* Found a valid volume. Call FolderAction with the */
  85.             /* volume name to record it in the file, then call  */
  86.             /* ScanFolders to scan all files and folders on the */
  87.             /* volume. */
  88.             
  89.             FolderAction( volumeName, 0 );
  90.             
  91.             ScanFolders( pb.volumeParam.ioVRefNum, 0, 1 );
  92.         }
  93.     }
  94. }
  95.  
  96. /* ScanFolders scans through all the files and/or folders in the
  97.  * folder specified. If dirID is zero, it scans the root
  98.  * folder of the volume specified. When scanning the folder,
  99.  * if a sub-folder is found, ScanFolders recurses (calls itself)
  100.  * to scan that folder. This behavior causes ALL the files and
  101.  * folders on the volume to be scanned. When ScanFolders is
  102.  * called to scan the root folder of a volume, the value 1
  103.  * should be sent for levels.
  104.  */
  105. void    ScanFolders( short vRefNum, long dirID, short levels )
  106. {
  107.     CInfoPBRec        pb;            /* a Catalog Info parameter block */
  108.     short            index;
  109.     Str31            dirName;
  110.     
  111.     pb.hFileInfo.ioCompletion = NULL;    /* no completion routine */
  112.     pb.hFileInfo.ioNamePtr = dirName;    /* storage for filename */
  113.     pb.hFileInfo.ioVRefNum = vRefNum;    /* the volume reference # */
  114.     
  115.     index = 1;        /* first file in the directory */
  116.     
  117.     while( true )
  118.     {
  119.         pb.hFileInfo.ioFDirIndex = index;    /* file index w/in the dir */
  120.         pb.hFileInfo.ioDirID = dirID;        /* directory ID # */
  121.         PBGetCatInfo( &pb, false );        /* get catalog info for file */
  122.         
  123.         /* If there was an error, quit scanning this folder by */
  124.         /* breaking out of the while loop. */
  125.         
  126.             if ( pb.hFileInfo.ioResult != noErr )
  127.                 break;
  128.         
  129.         /* If the file is actually a folder, recurse to scan it */
  130.         /* Otherwise, just call FileAction */
  131.         
  132.             if ( pb.hFileInfo.ioFlAttrib & 0x10 )    /* subfolder? */
  133.             {
  134.                 FolderAction( dirName, levels );
  135.                 
  136.                 ScanFolders( vRefNum, pb.dirInfo.ioDrDirID, levels+1 );
  137.             }
  138.             else
  139.                 FileAction();
  140.         
  141.         /* Increase the index by one to move to the next file */
  142.         
  143.             index++;
  144.     }
  145. }
  146.  
  147.