| /* |
| * Macintosh version of UNIX directory access package |
| * (opendir, readdir, closedir). |
| * Public domain by Guido van Rossum, CWI, Amsterdam (July 1987). |
| */ |
| |
| #include "dirent.h" |
| #include "macdefs.h" |
| |
| static DIR opened; |
| |
| /* |
| * Open a directory. This means calling PBOpenWD. |
| * The value returned is always the address of opened, or NULL. |
| * (I have as yet no use for multiple open directories; this could |
| * be implemented by allocating memory dynamically.) |
| */ |
| |
| DIR * |
| opendir(path) |
| char *path; |
| { |
| union { |
| WDPBRec d; |
| VolumeParam v; |
| } pb; |
| char ppath[MAXPATH]; |
| short err; |
| |
| if (opened.nextfile != 0) { |
| errno = EBUSY; |
| return NULL; /* A directory is already open. */ |
| } |
| strncpy(ppath+1, path, ppath[0]= strlen(path)); |
| pb.d.ioNamePtr= (unsigned char *)ppath; |
| pb.d.ioVRefNum= 0; |
| if (hfsrunning()) { |
| pb.d.ioWDProcID= 0; |
| pb.d.ioWDDirID= 0; |
| err= PBOpenWD((WDPBPtr)&pb, FALSE); |
| } |
| else { |
| pb.v.ioVolIndex= 0; |
| err= PBGetVInfo((ParmBlkPtr)&pb, FALSE); |
| } |
| if (err != noErr) { |
| errno = ENOENT; |
| return NULL; |
| } |
| opened.dirid= pb.d.ioVRefNum; |
| opened.nextfile= 1; |
| return &opened; |
| } |
| |
| /* |
| * Close a directory. |
| */ |
| |
| void |
| closedir(dirp) |
| DIR *dirp; |
| { |
| if (hfsrunning()) { |
| WDPBRec pb; |
| |
| pb.ioVRefNum= dirp->dirid; |
| (void) PBCloseWD(&pb, FALSE); |
| } |
| dirp->dirid= 0; |
| dirp->nextfile= 0; |
| } |
| |
| /* |
| * Read the next directory entry. |
| */ |
| |
| struct dirent * |
| readdir(dp) |
| DIR *dp; |
| { |
| union { |
| DirInfo d; |
| FileParam f; |
| HFileInfo hf; |
| } pb; |
| short err; |
| static struct dirent dir; |
| |
| dir.d_name[0]= 0; |
| pb.d.ioNamePtr= (unsigned char *)dir.d_name; |
| pb.d.ioVRefNum= dp->dirid; |
| pb.d.ioFDirIndex= dp->nextfile++; |
| pb.d.ioDrDirID= 0; |
| if (hfsrunning()) |
| err= PBGetCatInfo((CInfoPBPtr)&pb, FALSE); |
| else |
| err= PBGetFInfo((ParmBlkPtr)&pb, FALSE); |
| if (err != noErr) { |
| errno = EIO; |
| return NULL; |
| } |
| (void) p2cstr((unsigned char *)dir.d_name); |
| return &dir; |
| } |