/*----------------------------------------------------------------------*\ | Macintosh-specific I/O routines. These require System 7.0 or later. | | | | Peter N. Schweitzer (U.S. Geological Survey, Reston, VA 22092) | \*----------------------------------------------------------------------*/ #include #include extern int search; static void PtoCstrcpy (char *dst, Str255 src) { memcpy (dst,src+1,*src); dst[*src] = 0; } static void CtoPstrcpy (Str255 dst, char *src) { strcpy ((char *)dst+1,src); *dst = strlen (src); } static void Pstrcpy (Str255 dst, Str255 src) { memcpy (dst+1,src+1,*src); *dst = *src; } #define MAX_HITS 1 #define BUFFER_SIZE 16384 #define MAX_DRIVES 16 static FSSpec first_match; static FSSpec *find_file (Str255 name) { CSParam pb; FSSpec hit[MAX_HITS]; CInfoPBRec SearchInfo1,SearchInfo2; OSErr err; short theVolume; FSSpec *result = NULL; short volume_count = 0; struct { short vRefNum; Str255 name; } volume[MAX_DRIVES]; Ptr buffer; long buffer_size = 0; short done = 0; if (buffer = NewPtr (BUFFER_SIZE)) buffer_size = BUFFER_SIZE; if (volume_count == 0) { /*--------------------------------------------------*\ | Make a list of drives on the system by VRefNums. | \*--------------------------------------------------*/ short i,j = 0; Str255 volName; long freeBytes; OSErr err; short v; for (i=0; i < MAX_DRIVES; i++) { err = GetVInfo (i,volName,&v,&freeBytes); switch (err) { case noErr: volume[j].vRefNum = v; Pstrcpy (volume[j].name,volName); j++; break; case nsvErr: break; case paramErr: break; default: break; } } volume_count = j; theVolume = 0; } if (volume_count == 0) return (NULL); do { SearchInfo1.hFileInfo.ioNamePtr = name; SearchInfo2.hFileInfo.ioNamePtr = 0; SearchInfo1.hFileInfo.ioFlAttrib = 0x00; SearchInfo2.hFileInfo.ioFlAttrib = 0x10; pb.ioCompletion = 0L; pb.ioMatchPtr = hit; pb.ioReqMatchCount = MAX_HITS; pb.ioOptBuffer = buffer; pb.ioOptBufSize = buffer_size; pb.ioSearchTime = 5000L; pb.ioSearchInfo1 = &SearchInfo1; pb.ioSearchInfo2 = &SearchInfo2; pb.ioSearchBits = fsSBPartialName | fsSBFlAttrib; pb.ioVRefNum = volume[theVolume].vRefNum; pb.ioNamePtr = 0L; pb.ioCatPosition.initialize = 0; err = PBCatSearch (&pb,false); switch (err) { case noErr: case eofErr: case nsvErr: if (pb.ioActMatchCount > 0) { result = &first_match; *result = hit[0]; done = 1; } else { /*------------------------------------------------------*\ | Run the search again with the next drive in the list | \*------------------------------------------------------*/ theVolume++; if (theVolume >= volume_count) done = 1; } break; default: done = 1; break; } } while (!done); if (buffer) DisposePtr (buffer); return (result); } FILE *Mac_fopen (char *name, char *mode) { FILE *fp = NULL; Str255 pname; FSSpec *fsspec; short oldWDVol, oldTrueVol; long oldDir, oldProc; if (!search) { fp = fopen (name,mode); return (fp); } CtoPstrcpy (pname,name); if (fsspec = find_file (pname)) { /* save current working directory */ if (GetVol (0,&oldWDVol)) return (NULL); /* save current default volume info */ if (GetWDInfo (oldWDVol,&oldTrueVol,&oldDir,&oldProc)) return (NULL); /* set selected info as default */ if (HSetVol (0,fsspec->vRefNum,fsspec->parID)) return (NULL); fflush (NULL); /* flush all buffers */ fp = fopen (name,mode); /* open the file */ HSetVol (0,oldTrueVol,oldDir); /* restore default volume info */ SetVol (0,oldWDVol); /* restore working directory */ } return (fp); } /*----------------------------------------------------------------------*\ \*----------------------------------------------------------------------*/