[net.sources.mac] Example code to get at all files on a disk

guido@boring.UUCP (09/01/85)

Here is an isolated piece of example code which shows how to read the
directory of a disk (actually, of a "volume" which is usually but not always
a whole disk).

All you have to do is get file info for file i, for i from 1 to the number
of files on the disk.  You can do it for i from 1 to infinity and break
out of the loop as soon as a stat fails; files are numbered contiguously
and there really is no other good reason why a stat would fail except the
disk being broken.  If you want you can do a PBGetVInfo first to get at the
number of files on the volume.

The code shown here is a routine which returns various bits of info about
a file which is either given by file number (the i above) or by "refnum"
(what you get after you open a file).  All info is returned in the structure
shown first.

Note that this was written for SUMacC, but it shouldn't be too different
for other C compilers.  p2cstr converts a Pascal string in place to a C
string.

One final remark.  Someone asked for a "wildcard open".  One reason why
this isn't a good concept is that *all* characters (except ":", which
is the volume delimiter) can occur in a file name, so there would be
no good choice for wildcard characters.  As an example, however, I
have included a routine which returns the name of the first file with
a given suffix.  This code was never tried so there might be bugs, but
it shows how to do it.

Veel plezier ermee!

	Guido van Rossum, CWI, Amsterdam (guido@mcvax.UUCP)


/*
 * Structure where 'getfilestats' returns its info.
 */

struct filestats {
	int refnum;
	int flags;
	int version;
	long datasize;
	long rsrcsize;
	long modtime;
	OsType filetype;
	OsType signature;
	int finderflags;
	char name[256];
};


/*
 * Get directory information for a file on volume 'vrefnum'.
 * When index > 0, information for the index'th file is returned;
 * otherwise information for the file referred by 'refnum' is returned.
 * (No, this routine can't get info about a file by name.
 * My program didn't need that.)
 * Return the error number of the operation, noErr if successful.
 */

getfilestats(vref, index, refnum, stats)
	struct filestats *stats;
{
	FileParam fp;
	int err;

	stats->name[0]= '\0';
	fp.ioCompletion= NIL;
	fp.ioNamePtr= stats->name;
	fp.ioFVersNum= 0;
	fp.ioVRefNum= vref;
	fp.ioFDirIndex= index;
	fp.ioFRefNum= refnum;
	err= PBGetFInfo(&fp, FALSE);
	if (err != noErr)
		return err;
	stats->refnum= fp.ioFRefNum;
	stats->flags= fp.ioFlAttrib;
	stats->version= fp.ioFVersNum;
	stats->datasize= fp.ioFlLgLen;
	stats->rsrcsize= fp.ioFlRLgLen;
	stats->modtime= fp.ioFlMdDat;
	stats->filetype= fp.ioFlFndrInfo.fdType;
	stats->signature= fp.ioFlFndrInfo.fdCreator;
	stats->finderflags= fp.ioFlFndrInfo.fdFlags;
	p2cstr(stats->name);
	return noErr;
}


/*
 * Find the first file on the given volume whose name ends in the given suffix.
 * The file name is copied to the buffer.
 * Return TRUE (1) if one is found, FALSE (0) otherwise.
 */

suffile(vref, suffix, filename)
	int vref;
	char *suffix;
	char filename[256];
{
	struct filestats stats;
	int suflen;
	int len;
	int i;

	suflen= strlen(suffix);
	for (i= 1; TRUE; ++i) {
		if (getfilestats(vref, i, 0, &stats) != noErr)
			return FALSE;
		len= strlen(stats.name);
		if (len >= suflen &&
		    Equalstring(stats.name+len-suflen, suffix, FALSE, FALSE))
			break;
		}
	}
	strcpy(filename, stats.name);
	retutn TRUE;
}