summaryrefslogtreecommitdiffstats
path: root/Mac/Compat/opendir.c
blob: 74b89842ec6f5493550f65cb44a58cdb7fde708e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * 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;
}