Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * old (V6 and before) PDP-11 Unix filesystem
3
 */
4
#include <u.h>
5
#include <libc.h>
6
#include <auth.h>
7
#include <fcall.h>
8
#include "tapefs.h"
9
 
10
/*
11
 * v6 disk inode
12
 */
13
#define	V6NADDR	8
14
#define	V6FMT	0160000
15
#define	V6IFREG	0100000
16
#define	V6IFDIR	0140000
17
#define	V6IFCHR	0120000
18
#define	V6IFBLK	0160000
19
#define	V6MODE	0777
20
#define	V6LARGE	010000
21
#define	V6SUPERB	1
22
#define	V6ROOT		1	/* root inode */
23
#define	V6NAMELEN	14
24
#define	BLSIZE	512
25
#define	LINOPB	(BLSIZE/sizeof(struct v6dinode))
26
#define	LNINDIR	(BLSIZE/sizeof(unsigned short))
27
 
28
struct v6dinode {
29
	unsigned char flags[2];
30
	unsigned char nlinks;
31
	unsigned char uid;
32
	unsigned char gid;
33
	unsigned char hisize;
34
	unsigned char losize[2];
35
	unsigned char addr[V6NADDR][2];
36
	unsigned char atime[4];	/* pdp-11 order */
37
	unsigned char mtime[4];	/* pdp-11 order */
38
};
39
 
40
struct	v6dir {
41
	uchar	ino[2];
42
	char	name[V6NAMELEN];
43
};
44
 
45
int	tapefile;
46
Fileinf	iget(int ino);
47
long	bmap(Ram *r, long bno);
48
void	getblk(Ram *r, long bno, char *buf);
49
 
50
void
51
populate(char *name)
52
{
53
	Fileinf f;
54
 
55
	replete = 0;
56
	tapefile = open(name, OREAD);
57
	if (tapefile<0)
58
		error("Can't open argument file");
59
	f = iget(V6ROOT);
60
	ram->perm = f.mode;
61
	ram->mtime = f.mdate;
62
	ram->addr = f.addr;
63
	ram->data = f.data;
64
	ram->ndata = f.size;
65
}
66
 
67
void
68
popdir(Ram *r)
69
{
70
	int i, ino;
71
	char *cp;
72
	struct v6dir *dp;
73
	Fileinf f;
74
	char name[V6NAMELEN+1];
75
 
76
	cp = 0;
77
	for (i=0; i<r->ndata; i+=sizeof(struct v6dir)) {
78
		if (i%BLSIZE==0)
79
			cp = doread(r, i, BLSIZE);
80
		dp = (struct v6dir *)(cp+i%BLSIZE);
81
		ino = dp->ino[0] + (dp->ino[1]<<8);
82
		if (strcmp(dp->name, ".")==0 || strcmp(dp->name, "..")==0)
83
			continue;
84
		if (ino==0)
85
			continue;
86
		f = iget(ino);
87
		strncpy(name, dp->name, V6NAMELEN);
88
		name[V6NAMELEN] = '\0';
89
		f.name = name;
90
		popfile(r, f);
91
	}
92
	r->replete = 1;
93
}
94
 
95
void
96
dotrunc(Ram *r)
97
{
98
	USED(r);
99
}
100
 
101
void
102
docreate(Ram *r)
103
{
104
	USED(r);
105
}
106
 
107
char *
108
doread(Ram *r, vlong off, long cnt)
109
{
110
	static char buf[Maxbuf+BLSIZE];
111
	int bno, i;
112
 
113
	bno = off/BLSIZE;
114
	off -= bno*BLSIZE;
115
	if (cnt>Maxbuf)
116
		error("count too large");
117
	if (off)
118
		cnt += off;
119
	i = 0;
120
	while (cnt>0) {
121
		getblk(r, bno, &buf[i*BLSIZE]);
122
		cnt -= BLSIZE;
123
		bno++;
124
		i++;
125
	}
126
	return buf;
127
}
128
 
129
void
130
dowrite(Ram *r, char *buf, long off, long cnt)
131
{
132
	USED(r); USED(buf); USED(off); USED(cnt);
133
}
134
 
135
int
136
dopermw(Ram *r)
137
{
138
	USED(r);
139
	return 0;
140
}
141
 
142
/*
143
 * fetch an i-node
144
 * -- no sanity check for now
145
 * -- magic inode-to-disk-block stuff here
146
 */
147
 
148
Fileinf
149
iget(int ino)
150
{
151
	char buf[BLSIZE];
152
	struct v6dinode *dp;
153
	long flags, i;
154
	Fileinf f;
155
 
156
	seek(tapefile, BLSIZE*((ino-1)/LINOPB + V6SUPERB + 1), 0);
157
	if (read(tapefile, buf, BLSIZE) != BLSIZE)
158
		error("Can't read inode");
159
	dp = ((struct v6dinode *)buf) + ((ino-1)%LINOPB);
160
	flags = (dp->flags[1]<<8) + dp->flags[0];
161
	f.size = (dp->hisize << 16) + (dp->losize[1]<<8) + dp->losize[0];
162
	if ((flags&V6FMT)==V6IFCHR || (flags&V6FMT)==V6IFBLK)
163
		f.size = 0;
164
	f.data = emalloc(V6NADDR*sizeof(ushort));
165
	for (i = 0; i < V6NADDR; i++)
166
		((ushort*)f.data)[i] = (dp->addr[i][1]<<8) + dp->addr[i][0];
167
	f.mode = flags & V6MODE;
168
	if ((flags&V6FMT)==V6IFDIR)
169
		f.mode |= DMDIR;
170
	f.uid = dp->uid;
171
	f.gid = dp->gid;	
172
	f.mdate = (dp->mtime[2]<<0) + (dp->mtime[3]<<8)
173
	     +(dp->mtime[0]<<16) + (dp->mtime[1]<<24);
174
	return f;
175
}
176
 
177
void
178
getblk(Ram *r, long bno, char *buf)
179
{
180
	long dbno;
181
 
182
	if ((dbno = bmap(r, bno)) == 0) {
183
		memset(buf, 0, BLSIZE);
184
		return;
185
	}
186
	seek(tapefile, dbno*BLSIZE, 0);
187
	if (read(tapefile, buf, BLSIZE) != BLSIZE)
188
		error("bad read");
189
}
190
 
191
/*
192
 * logical to physical block
193
 * only singly-indirect files for now
194
 */
195
 
196
long
197
bmap(Ram *r, long bno)
198
{
199
	unsigned char indbuf[LNINDIR][2];
200
 
201
	if (r->ndata <= V6NADDR*BLSIZE) {	/* assume size predicts largeness of file */
202
		if (bno < V6NADDR)
203
			return ((ushort*)r->data)[bno];
204
		return 0;
205
	}
206
	if (bno < V6NADDR*LNINDIR) {
207
		seek(tapefile, ((ushort *)r->data)[bno/LNINDIR]*BLSIZE, 0);
208
		if (read(tapefile, (char *)indbuf, BLSIZE) != BLSIZE)
209
			return 0;
210
		return ((indbuf[bno%LNINDIR][1]<<8) + indbuf[bno%LNINDIR][0]);
211
	}
212
	return 0;
213
}