Blame


1 78a779a3 2008-07-20 rsc #include <u.h>
2 78a779a3 2008-07-20 rsc #include <libc.h>
3 78a779a3 2008-07-20 rsc #include <auth.h>
4 78a779a3 2008-07-20 rsc #include <fcall.h>
5 78a779a3 2008-07-20 rsc #include "dat.h"
6 78a779a3 2008-07-20 rsc #include "fns.h"
7 78a779a3 2008-07-20 rsc #include "iso9660.h"
8 78a779a3 2008-07-20 rsc
9 78a779a3 2008-07-20 rsc static void ireset(void);
10 78a779a3 2008-07-20 rsc static int iattach(Xfile*);
11 78a779a3 2008-07-20 rsc static void iclone(Xfile*, Xfile*);
12 78a779a3 2008-07-20 rsc static void iwalkup(Xfile*);
13 78a779a3 2008-07-20 rsc static void iwalk(Xfile*, char*);
14 78a779a3 2008-07-20 rsc static void iopen(Xfile*, int);
15 78a779a3 2008-07-20 rsc static void icreate(Xfile*, char*, long, int);
16 78a779a3 2008-07-20 rsc static long ireaddir(Xfile*, uchar*, long, long);
17 78a779a3 2008-07-20 rsc static long iread(Xfile*, char*, vlong, long);
18 78a779a3 2008-07-20 rsc static long iwrite(Xfile*, char*, vlong, long);
19 78a779a3 2008-07-20 rsc static void iclunk(Xfile*);
20 78a779a3 2008-07-20 rsc static void iremove(Xfile*);
21 78a779a3 2008-07-20 rsc static void istat(Xfile*, Dir*);
22 78a779a3 2008-07-20 rsc static void iwstat(Xfile*, Dir*);
23 78a779a3 2008-07-20 rsc
24 78a779a3 2008-07-20 rsc static char* nstr(uchar*, int);
25 78a779a3 2008-07-20 rsc static char* rdate(uchar*, int);
26 78a779a3 2008-07-20 rsc static int getcontin(Xdata*, uchar*, uchar**);
27 78a779a3 2008-07-20 rsc static int getdrec(Xfile*, void*);
28 78a779a3 2008-07-20 rsc static void ungetdrec(Xfile*);
29 78a779a3 2008-07-20 rsc static int opendotdot(Xfile*, Xfile*);
30 78a779a3 2008-07-20 rsc static int showdrec(int, int, void*);
31 78a779a3 2008-07-20 rsc static long gtime(uchar*);
32 78a779a3 2008-07-20 rsc static long l16(void*);
33 78a779a3 2008-07-20 rsc static long l32(void*);
34 78a779a3 2008-07-20 rsc static void newdrec(Xfile*, Drec*);
35 78a779a3 2008-07-20 rsc static int rzdir(Xfs*, Dir*, int, Drec*);
36 78a779a3 2008-07-20 rsc
37 78a779a3 2008-07-20 rsc Xfsub isosub =
38 78a779a3 2008-07-20 rsc {
39 78a779a3 2008-07-20 rsc ireset, iattach, iclone, iwalkup, iwalk, iopen, icreate,
40 78a779a3 2008-07-20 rsc ireaddir, iread, iwrite, iclunk, iremove, istat, iwstat
41 78a779a3 2008-07-20 rsc };
42 78a779a3 2008-07-20 rsc
43 78a779a3 2008-07-20 rsc static void
44 78a779a3 2008-07-20 rsc ireset(void)
45 78a779a3 2008-07-20 rsc {}
46 78a779a3 2008-07-20 rsc
47 78a779a3 2008-07-20 rsc static int
48 78a779a3 2008-07-20 rsc iattach(Xfile *root)
49 78a779a3 2008-07-20 rsc {
50 78a779a3 2008-07-20 rsc Xfs *cd = root->xf;
51 78a779a3 2008-07-20 rsc Iobuf *p; Voldesc *v; Isofile *fp; Drec *dp;
52 78a779a3 2008-07-20 rsc int fmt, blksize, i, n, l, haveplan9;
53 78a779a3 2008-07-20 rsc Iobuf *dirp;
54 78a779a3 2008-07-20 rsc uchar dbuf[256];
55 78a779a3 2008-07-20 rsc Drec *rd = (Drec *)dbuf;
56 78a779a3 2008-07-20 rsc uchar *q, *s;
57 78a779a3 2008-07-20 rsc
58 78a779a3 2008-07-20 rsc dirp = nil;
59 78a779a3 2008-07-20 rsc blksize = 0;
60 78a779a3 2008-07-20 rsc fmt = 0;
61 78a779a3 2008-07-20 rsc dp = nil;
62 78a779a3 2008-07-20 rsc haveplan9 = 0;
63 78a779a3 2008-07-20 rsc for(i=VOLDESC;i<VOLDESC+100; i++){ /* +100 for sanity */
64 78a779a3 2008-07-20 rsc p = getbuf(cd->d, i);
65 78a779a3 2008-07-20 rsc v = (Voldesc*)(p->iobuf);
66 78a779a3 2008-07-20 rsc if(memcmp(v->byte, "\01CD001\01", 7) == 0){ /* iso */
67 78a779a3 2008-07-20 rsc if(dirp)
68 78a779a3 2008-07-20 rsc putbuf(dirp);
69 78a779a3 2008-07-20 rsc dirp = p;
70 78a779a3 2008-07-20 rsc fmt = 'z';
71 78a779a3 2008-07-20 rsc dp = (Drec*)v->z.desc.rootdir;
72 78a779a3 2008-07-20 rsc blksize = l16(v->z.desc.blksize);
73 78a779a3 2008-07-20 rsc chat("iso, blksize=%d...", blksize);
74 78a779a3 2008-07-20 rsc
75 78a779a3 2008-07-20 rsc v = (Voldesc*)(dirp->iobuf);
76 78a779a3 2008-07-20 rsc haveplan9 = (strncmp((char*)v->z.boot.sysid, "PLAN 9", 6)==0);
77 78a779a3 2008-07-20 rsc if(haveplan9){
78 78a779a3 2008-07-20 rsc if(noplan9) {
79 78a779a3 2008-07-20 rsc chat("ignoring plan9");
80 78a779a3 2008-07-20 rsc haveplan9 = 0;
81 78a779a3 2008-07-20 rsc } else {
82 78a779a3 2008-07-20 rsc fmt = '9';
83 78a779a3 2008-07-20 rsc chat("plan9 iso...");
84 78a779a3 2008-07-20 rsc }
85 78a779a3 2008-07-20 rsc }
86 78a779a3 2008-07-20 rsc continue;
87 78a779a3 2008-07-20 rsc }
88 78a779a3 2008-07-20 rsc
89 78a779a3 2008-07-20 rsc if(memcmp(&v->byte[8], "\01CDROM\01", 7) == 0){ /* high sierra */
90 78a779a3 2008-07-20 rsc if(dirp)
91 78a779a3 2008-07-20 rsc putbuf(dirp);
92 78a779a3 2008-07-20 rsc dirp = p;
93 78a779a3 2008-07-20 rsc fmt = 'r';
94 78a779a3 2008-07-20 rsc dp = (Drec*)v->r.desc.rootdir;
95 78a779a3 2008-07-20 rsc blksize = l16(v->r.desc.blksize);
96 78a779a3 2008-07-20 rsc chat("high sierra, blksize=%d...", blksize);
97 78a779a3 2008-07-20 rsc continue;
98 78a779a3 2008-07-20 rsc }
99 78a779a3 2008-07-20 rsc
100 78a779a3 2008-07-20 rsc if(haveplan9==0 && !nojoliet
101 78a779a3 2008-07-20 rsc && memcmp(v->byte, "\02CD001\01", 7) == 0){
102 78a779a3 2008-07-20 rsc chat("%d %d\n", haveplan9, nojoliet);
103 78a779a3 2008-07-20 rsc /*
104 78a779a3 2008-07-20 rsc * The right thing to do is walk the escape sequences looking
105 78a779a3 2008-07-20 rsc * for one of 25 2F 4[035], but Microsoft seems to not honor
106 78a779a3 2008-07-20 rsc * the format, which makes it hard to walk over.
107 78a779a3 2008-07-20 rsc */
108 78a779a3 2008-07-20 rsc q = v->z.desc.escapes;
109 78a779a3 2008-07-20 rsc if(q[0] == 0x25 && q[1] == 0x2F && (q[2] == 0x40 || q[2] == 0x43 || q[2] == 0x45)){ /* Joliet, it appears */
110 78a779a3 2008-07-20 rsc if(dirp)
111 78a779a3 2008-07-20 rsc putbuf(dirp);
112 78a779a3 2008-07-20 rsc dirp = p;
113 78a779a3 2008-07-20 rsc fmt = 'J';
114 78a779a3 2008-07-20 rsc dp = (Drec*)v->z.desc.rootdir;
115 78a779a3 2008-07-20 rsc if(blksize != l16(v->z.desc.blksize))
116 78a779a3 2008-07-20 rsc fprint(2, "warning: suspicious Joliet blocksize\n");
117 78a779a3 2008-07-20 rsc chat("joliet...");
118 78a779a3 2008-07-20 rsc continue;
119 78a779a3 2008-07-20 rsc }
120 78a779a3 2008-07-20 rsc }
121 78a779a3 2008-07-20 rsc putbuf(p);
122 78a779a3 2008-07-20 rsc if(v->byte[0] == 0xFF)
123 78a779a3 2008-07-20 rsc break;
124 78a779a3 2008-07-20 rsc }
125 78a779a3 2008-07-20 rsc
126 78a779a3 2008-07-20 rsc if(fmt == 0){
127 78a779a3 2008-07-20 rsc if(dirp)
128 78a779a3 2008-07-20 rsc putbuf(dirp);
129 78a779a3 2008-07-20 rsc return -1;
130 78a779a3 2008-07-20 rsc }
131 78a779a3 2008-07-20 rsc assert(dirp != nil);
132 78a779a3 2008-07-20 rsc
133 78a779a3 2008-07-20 rsc if(chatty)
134 78a779a3 2008-07-20 rsc showdrec(2, fmt, dp);
135 78a779a3 2008-07-20 rsc if(blksize > Sectorsize){
136 78a779a3 2008-07-20 rsc chat("blksize too big...");
137 78a779a3 2008-07-20 rsc putbuf(dirp);
138 78a779a3 2008-07-20 rsc return -1;
139 78a779a3 2008-07-20 rsc }
140 78a779a3 2008-07-20 rsc if(waserror()){
141 78a779a3 2008-07-20 rsc putbuf(dirp);
142 78a779a3 2008-07-20 rsc nexterror();
143 78a779a3 2008-07-20 rsc }
144 13c28c2c 2008-12-02 trisk root->len = sizeof(Isofile) - sizeof(Drec) + dp->z.reclen;
145 78a779a3 2008-07-20 rsc root->ptr = fp = ealloc(root->len);
146 78a779a3 2008-07-20 rsc
147 78a779a3 2008-07-20 rsc if(haveplan9)
148 78a779a3 2008-07-20 rsc root->xf->isplan9 = 1;
149 78a779a3 2008-07-20 rsc
150 78a779a3 2008-07-20 rsc fp->fmt = fmt;
151 78a779a3 2008-07-20 rsc fp->blksize = blksize;
152 78a779a3 2008-07-20 rsc fp->offset = 0;
153 78a779a3 2008-07-20 rsc fp->doffset = 0;
154 13c28c2c 2008-12-02 trisk memmove(&fp->d, dp, dp->z.reclen);
155 13c28c2c 2008-12-02 trisk root->qid.path = l32(dp->z.addr);
156 78a779a3 2008-07-20 rsc root->qid.type = QTDIR;
157 78a779a3 2008-07-20 rsc putbuf(dirp);
158 78a779a3 2008-07-20 rsc poperror();
159 78a779a3 2008-07-20 rsc if(getdrec(root, rd) >= 0){
160 13c28c2c 2008-12-02 trisk n = rd->z.reclen-(34+rd->z.namelen);
161 13c28c2c 2008-12-02 trisk s = (uchar*)rd->z.name + rd->z.namelen;
162 78a779a3 2008-07-20 rsc if((uintptr)s & 1){
163 78a779a3 2008-07-20 rsc s++;
164 78a779a3 2008-07-20 rsc n--;
165 78a779a3 2008-07-20 rsc }
166 78a779a3 2008-07-20 rsc if(n >= 7 && s[0] == 'S' && s[1] == 'P' && s[2] == 7 &&
167 78a779a3 2008-07-20 rsc s[3] == 1 && s[4] == 0xBE && s[5] == 0xEF){
168 78a779a3 2008-07-20 rsc root->xf->issusp = 1;
169 78a779a3 2008-07-20 rsc root->xf->suspoff = s[6];
170 78a779a3 2008-07-20 rsc n -= root->xf->suspoff;
171 78a779a3 2008-07-20 rsc s += root->xf->suspoff;
172 78a779a3 2008-07-20 rsc for(; n >= 4; s += l, n -= l){
173 78a779a3 2008-07-20 rsc l = s[2];
174 78a779a3 2008-07-20 rsc if(s[0] == 'E' && s[1] == 'R'){
175 78a779a3 2008-07-20 rsc if(!norock && s[4] == 10 && memcmp(s+8, "RRIP_1991A", 10) == 0)
176 78a779a3 2008-07-20 rsc root->xf->isrock = 1;
177 78a779a3 2008-07-20 rsc break;
178 78a779a3 2008-07-20 rsc } else if(s[0] == 'C' && s[1] == 'E' && s[2] >= 28){
179 78a779a3 2008-07-20 rsc n = getcontin(root->xf->d, s, &s);
180 78a779a3 2008-07-20 rsc continue;
181 78a779a3 2008-07-20 rsc } else if(s[0] == 'R' && s[1] == 'R'){
182 78a779a3 2008-07-20 rsc if(!norock)
183 78a779a3 2008-07-20 rsc root->xf->isrock = 1;
184 78a779a3 2008-07-20 rsc break;
185 78a779a3 2008-07-20 rsc } else if(s[0] == 'S' && s[1] == 'T')
186 78a779a3 2008-07-20 rsc break;
187 78a779a3 2008-07-20 rsc }
188 78a779a3 2008-07-20 rsc }
189 78a779a3 2008-07-20 rsc }
190 78a779a3 2008-07-20 rsc if(root->xf->isrock)
191 78a779a3 2008-07-20 rsc chat("Rock Ridge...");
192 78a779a3 2008-07-20 rsc fp->offset = 0;
193 78a779a3 2008-07-20 rsc fp->doffset = 0;
194 78a779a3 2008-07-20 rsc return 0;
195 78a779a3 2008-07-20 rsc }
196 78a779a3 2008-07-20 rsc
197 78a779a3 2008-07-20 rsc static void
198 78a779a3 2008-07-20 rsc iclone(Xfile *of, Xfile *nf)
199 78a779a3 2008-07-20 rsc {
200 78a779a3 2008-07-20 rsc USED(of);
201 78a779a3 2008-07-20 rsc USED(nf);
202 78a779a3 2008-07-20 rsc }
203 78a779a3 2008-07-20 rsc
204 78a779a3 2008-07-20 rsc static void
205 78a779a3 2008-07-20 rsc iwalkup(Xfile *f)
206 78a779a3 2008-07-20 rsc {
207 78a779a3 2008-07-20 rsc long paddr;
208 78a779a3 2008-07-20 rsc uchar dbuf[256];
209 78a779a3 2008-07-20 rsc Drec *d = (Drec *)dbuf;
210 78a779a3 2008-07-20 rsc Xfile pf, ppf;
211 78a779a3 2008-07-20 rsc Isofile piso, ppiso;
212 78a779a3 2008-07-20 rsc
213 78a779a3 2008-07-20 rsc memset(&pf, 0, sizeof pf);
214 78a779a3 2008-07-20 rsc memset(&ppf, 0, sizeof ppf);
215 78a779a3 2008-07-20 rsc pf.ptr = &piso;
216 78a779a3 2008-07-20 rsc ppf.ptr = &ppiso;
217 78a779a3 2008-07-20 rsc if(opendotdot(f, &pf) < 0)
218 78a779a3 2008-07-20 rsc error("can't open pf");
219 13c28c2c 2008-12-02 trisk paddr = l32(pf.ptr->d.z.addr);
220 13c28c2c 2008-12-02 trisk if(l32(f->ptr->d.z.addr) == paddr)
221 78a779a3 2008-07-20 rsc return;
222 78a779a3 2008-07-20 rsc if(opendotdot(&pf, &ppf) < 0)
223 78a779a3 2008-07-20 rsc error("can't open ppf");
224 78a779a3 2008-07-20 rsc while(getdrec(&ppf, d) >= 0){
225 13c28c2c 2008-12-02 trisk if(l32(d->z.addr) == paddr){
226 78a779a3 2008-07-20 rsc newdrec(f, d);
227 78a779a3 2008-07-20 rsc f->qid.path = paddr;
228 78a779a3 2008-07-20 rsc f->qid.type = QTDIR;
229 78a779a3 2008-07-20 rsc return;
230 78a779a3 2008-07-20 rsc }
231 78a779a3 2008-07-20 rsc }
232 78a779a3 2008-07-20 rsc error("can't find addr of ..");
233 78a779a3 2008-07-20 rsc }
234 78a779a3 2008-07-20 rsc
235 78a779a3 2008-07-20 rsc static int
236 78a779a3 2008-07-20 rsc casestrcmp(int isplan9, char *a, char *b)
237 78a779a3 2008-07-20 rsc {
238 78a779a3 2008-07-20 rsc int ca, cb;
239 78a779a3 2008-07-20 rsc
240 78a779a3 2008-07-20 rsc if(isplan9)
241 78a779a3 2008-07-20 rsc return strcmp(a, b);
242 78a779a3 2008-07-20 rsc for(;;) {
243 78a779a3 2008-07-20 rsc ca = *a++;
244 78a779a3 2008-07-20 rsc cb = *b++;
245 78a779a3 2008-07-20 rsc if(ca >= 'A' && ca <= 'Z')
246 78a779a3 2008-07-20 rsc ca += 'a' - 'A';
247 78a779a3 2008-07-20 rsc if(cb >= 'A' && cb <= 'Z')
248 78a779a3 2008-07-20 rsc cb += 'a' - 'A';
249 78a779a3 2008-07-20 rsc if(ca != cb) {
250 78a779a3 2008-07-20 rsc if(ca > cb)
251 78a779a3 2008-07-20 rsc return 1;
252 78a779a3 2008-07-20 rsc return -1;
253 78a779a3 2008-07-20 rsc }
254 78a779a3 2008-07-20 rsc if(ca == 0)
255 78a779a3 2008-07-20 rsc return 0;
256 78a779a3 2008-07-20 rsc }
257 78a779a3 2008-07-20 rsc }
258 78a779a3 2008-07-20 rsc
259 78a779a3 2008-07-20 rsc static void
260 78a779a3 2008-07-20 rsc iwalk(Xfile *f, char *name)
261 78a779a3 2008-07-20 rsc {
262 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr;
263 78a779a3 2008-07-20 rsc uchar dbuf[256];
264 78a779a3 2008-07-20 rsc char nbuf[4*Maxname];
265 78a779a3 2008-07-20 rsc Drec *d = (Drec*)dbuf;
266 78a779a3 2008-07-20 rsc Dir dir;
267 78a779a3 2008-07-20 rsc char *p;
268 78a779a3 2008-07-20 rsc int len, vers, dvers;
269 78a779a3 2008-07-20 rsc
270 78a779a3 2008-07-20 rsc vers = -1;
271 78a779a3 2008-07-20 rsc if(p = strchr(name, ';')) { /* assign = */
272 78a779a3 2008-07-20 rsc len = p-name;
273 78a779a3 2008-07-20 rsc if(len >= Maxname)
274 78a779a3 2008-07-20 rsc len = Maxname-1;
275 78a779a3 2008-07-20 rsc memmove(nbuf, name, len);
276 78a779a3 2008-07-20 rsc vers = strtoul(p+1, 0, 10);
277 78a779a3 2008-07-20 rsc name = nbuf;
278 78a779a3 2008-07-20 rsc }
279 78a779a3 2008-07-20 rsc /*
280 78a779a3 2008-07-20 rsc len = strlen(name);
281 78a779a3 2008-07-20 rsc if(len >= Maxname){
282 78a779a3 2008-07-20 rsc len = Maxname-1;
283 78a779a3 2008-07-20 rsc if(name != nbuf){
284 78a779a3 2008-07-20 rsc memmove(nbuf, name, len);
285 78a779a3 2008-07-20 rsc name = nbuf;
286 78a779a3 2008-07-20 rsc }
287 78a779a3 2008-07-20 rsc name[len] = 0;
288 78a779a3 2008-07-20 rsc }
289 78a779a3 2008-07-20 rsc */
290 78a779a3 2008-07-20 rsc
291 78a779a3 2008-07-20 rsc chat("%d \"%s\"...", strlen(name), name);
292 78a779a3 2008-07-20 rsc ip->offset = 0;
293 78a779a3 2008-07-20 rsc setnames(&dir, nbuf);
294 78a779a3 2008-07-20 rsc while(getdrec(f, d) >= 0) {
295 78a779a3 2008-07-20 rsc dvers = rzdir(f->xf, &dir, ip->fmt, d);
296 78a779a3 2008-07-20 rsc if(casestrcmp(f->xf->isplan9||f->xf->isrock, name, dir.name) != 0)
297 78a779a3 2008-07-20 rsc continue;
298 78a779a3 2008-07-20 rsc newdrec(f, d);
299 78a779a3 2008-07-20 rsc f->qid.path = dir.qid.path;
300 78a779a3 2008-07-20 rsc f->qid.type = dir.qid.type;
301 78a779a3 2008-07-20 rsc USED(dvers);
302 78a779a3 2008-07-20 rsc return;
303 78a779a3 2008-07-20 rsc }
304 78a779a3 2008-07-20 rsc USED(vers);
305 78a779a3 2008-07-20 rsc error(Enonexist);
306 78a779a3 2008-07-20 rsc }
307 78a779a3 2008-07-20 rsc
308 78a779a3 2008-07-20 rsc static void
309 78a779a3 2008-07-20 rsc iopen(Xfile *f, int mode)
310 78a779a3 2008-07-20 rsc {
311 78a779a3 2008-07-20 rsc mode &= ~OCEXEC;
312 78a779a3 2008-07-20 rsc if(mode != OREAD && mode != OEXEC)
313 78a779a3 2008-07-20 rsc error(Eperm);
314 78a779a3 2008-07-20 rsc f->ptr->offset = 0;
315 78a779a3 2008-07-20 rsc f->ptr->doffset = 0;
316 78a779a3 2008-07-20 rsc }
317 78a779a3 2008-07-20 rsc
318 78a779a3 2008-07-20 rsc static void
319 78a779a3 2008-07-20 rsc icreate(Xfile *f, char *name, long perm, int mode)
320 78a779a3 2008-07-20 rsc {
321 78a779a3 2008-07-20 rsc USED(f);
322 78a779a3 2008-07-20 rsc USED(name);
323 78a779a3 2008-07-20 rsc USED(perm);
324 78a779a3 2008-07-20 rsc USED(mode);
325 78a779a3 2008-07-20 rsc error(Eperm);
326 78a779a3 2008-07-20 rsc }
327 78a779a3 2008-07-20 rsc
328 78a779a3 2008-07-20 rsc static long
329 78a779a3 2008-07-20 rsc ireaddir(Xfile *f, uchar *buf, long offset, long count)
330 78a779a3 2008-07-20 rsc {
331 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr;
332 78a779a3 2008-07-20 rsc Dir d;
333 78a779a3 2008-07-20 rsc char names[4*Maxname];
334 78a779a3 2008-07-20 rsc uchar dbuf[256];
335 78a779a3 2008-07-20 rsc Drec *drec = (Drec *)dbuf;
336 78a779a3 2008-07-20 rsc int n, rcnt;
337 78a779a3 2008-07-20 rsc
338 78a779a3 2008-07-20 rsc if(offset==0){
339 78a779a3 2008-07-20 rsc ip->offset = 0;
340 78a779a3 2008-07-20 rsc ip->doffset = 0;
341 78a779a3 2008-07-20 rsc }else if(offset != ip->doffset)
342 78a779a3 2008-07-20 rsc error("seek in directory not allowed");
343 78a779a3 2008-07-20 rsc
344 78a779a3 2008-07-20 rsc rcnt = 0;
345 78a779a3 2008-07-20 rsc setnames(&d, names);
346 78a779a3 2008-07-20 rsc while(rcnt < count && getdrec(f, drec) >= 0){
347 13c28c2c 2008-12-02 trisk if(drec->z.namelen == 1){
348 13c28c2c 2008-12-02 trisk if(drec->z.name[0] == 0)
349 78a779a3 2008-07-20 rsc continue;
350 13c28c2c 2008-12-02 trisk if(drec->z.name[0] == 1)
351 78a779a3 2008-07-20 rsc continue;
352 78a779a3 2008-07-20 rsc }
353 78a779a3 2008-07-20 rsc rzdir(f->xf, &d, ip->fmt, drec);
354 78a779a3 2008-07-20 rsc d.qid.vers = f->qid.vers;
355 78a779a3 2008-07-20 rsc if((n = convD2M(&d, buf+rcnt, count-rcnt)) <= BIT16SZ){
356 78a779a3 2008-07-20 rsc ungetdrec(f);
357 78a779a3 2008-07-20 rsc break;
358 78a779a3 2008-07-20 rsc }
359 78a779a3 2008-07-20 rsc rcnt += n;
360 78a779a3 2008-07-20 rsc }
361 78a779a3 2008-07-20 rsc ip->doffset += rcnt;
362 78a779a3 2008-07-20 rsc return rcnt;
363 78a779a3 2008-07-20 rsc }
364 78a779a3 2008-07-20 rsc
365 78a779a3 2008-07-20 rsc static long
366 78a779a3 2008-07-20 rsc iread(Xfile *f, char *buf, vlong offset, long count)
367 78a779a3 2008-07-20 rsc {
368 78a779a3 2008-07-20 rsc int n, o, rcnt = 0;
369 78a779a3 2008-07-20 rsc long size;
370 78a779a3 2008-07-20 rsc vlong addr;
371 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr;
372 78a779a3 2008-07-20 rsc Iobuf *p;
373 78a779a3 2008-07-20 rsc
374 13c28c2c 2008-12-02 trisk size = l32(ip->d.z.size);
375 78a779a3 2008-07-20 rsc if(offset >= size)
376 78a779a3 2008-07-20 rsc return 0;
377 78a779a3 2008-07-20 rsc if(offset+count > size)
378 78a779a3 2008-07-20 rsc count = size - offset;
379 13c28c2c 2008-12-02 trisk addr = ((vlong)l32(ip->d.z.addr) + ip->d.z.attrlen)*ip->blksize + offset;
380 78a779a3 2008-07-20 rsc o = addr % Sectorsize;
381 78a779a3 2008-07-20 rsc addr /= Sectorsize;
382 13c28c2c 2008-12-02 trisk /*chat("d.addr=%ld, addr=%lld, o=%d...", l32(ip->d.z.addr), addr, o);*/
383 78a779a3 2008-07-20 rsc n = Sectorsize - o;
384 78a779a3 2008-07-20 rsc
385 78a779a3 2008-07-20 rsc while(count > 0){
386 78a779a3 2008-07-20 rsc if(n > count)
387 78a779a3 2008-07-20 rsc n = count;
388 78a779a3 2008-07-20 rsc p = getbuf(f->xf->d, addr);
389 78a779a3 2008-07-20 rsc memmove(&buf[rcnt], &p->iobuf[o], n);
390 78a779a3 2008-07-20 rsc putbuf(p);
391 78a779a3 2008-07-20 rsc count -= n;
392 78a779a3 2008-07-20 rsc rcnt += n;
393 78a779a3 2008-07-20 rsc ++addr;
394 78a779a3 2008-07-20 rsc o = 0;
395 78a779a3 2008-07-20 rsc n = Sectorsize;
396 78a779a3 2008-07-20 rsc }
397 78a779a3 2008-07-20 rsc return rcnt;
398 78a779a3 2008-07-20 rsc }
399 78a779a3 2008-07-20 rsc
400 78a779a3 2008-07-20 rsc static long
401 78a779a3 2008-07-20 rsc iwrite(Xfile *f, char *buf, vlong offset, long count)
402 78a779a3 2008-07-20 rsc {
403 78a779a3 2008-07-20 rsc USED(f);
404 78a779a3 2008-07-20 rsc USED(buf);
405 78a779a3 2008-07-20 rsc USED(offset);
406 78a779a3 2008-07-20 rsc USED(count);
407 78a779a3 2008-07-20 rsc error(Eperm);
408 78a779a3 2008-07-20 rsc return 0;
409 78a779a3 2008-07-20 rsc }
410 78a779a3 2008-07-20 rsc
411 78a779a3 2008-07-20 rsc static void
412 78a779a3 2008-07-20 rsc iclunk(Xfile *f)
413 78a779a3 2008-07-20 rsc {
414 78a779a3 2008-07-20 rsc USED(f);
415 78a779a3 2008-07-20 rsc }
416 78a779a3 2008-07-20 rsc
417 78a779a3 2008-07-20 rsc static void
418 78a779a3 2008-07-20 rsc iremove(Xfile *f)
419 78a779a3 2008-07-20 rsc {
420 78a779a3 2008-07-20 rsc USED(f);
421 78a779a3 2008-07-20 rsc error(Eperm);
422 78a779a3 2008-07-20 rsc }
423 78a779a3 2008-07-20 rsc
424 78a779a3 2008-07-20 rsc static void
425 78a779a3 2008-07-20 rsc istat(Xfile *f, Dir *d)
426 78a779a3 2008-07-20 rsc {
427 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr;
428 78a779a3 2008-07-20 rsc
429 78a779a3 2008-07-20 rsc rzdir(f->xf, d, ip->fmt, &ip->d);
430 78a779a3 2008-07-20 rsc d->qid.vers = f->qid.vers;
431 78a779a3 2008-07-20 rsc if(d->qid.path==f->xf->rootqid.path){
432 78a779a3 2008-07-20 rsc d->qid.path = 0;
433 78a779a3 2008-07-20 rsc d->qid.type = QTDIR;
434 78a779a3 2008-07-20 rsc }
435 78a779a3 2008-07-20 rsc }
436 78a779a3 2008-07-20 rsc
437 78a779a3 2008-07-20 rsc static void
438 78a779a3 2008-07-20 rsc iwstat(Xfile *f, Dir *d)
439 78a779a3 2008-07-20 rsc {
440 78a779a3 2008-07-20 rsc USED(f);
441 78a779a3 2008-07-20 rsc USED(d);
442 78a779a3 2008-07-20 rsc error(Eperm);
443 78a779a3 2008-07-20 rsc }
444 78a779a3 2008-07-20 rsc
445 78a779a3 2008-07-20 rsc static int
446 78a779a3 2008-07-20 rsc showdrec(int fd, int fmt, void *x)
447 78a779a3 2008-07-20 rsc {
448 78a779a3 2008-07-20 rsc Drec *d = (Drec *)x;
449 78a779a3 2008-07-20 rsc int namelen;
450 78a779a3 2008-07-20 rsc int syslen;
451 78a779a3 2008-07-20 rsc
452 13c28c2c 2008-12-02 trisk if(d->z.reclen == 0)
453 78a779a3 2008-07-20 rsc return 0;
454 78a779a3 2008-07-20 rsc fprint(fd, "%d %d %ld %ld ",
455 13c28c2c 2008-12-02 trisk d->z.reclen, d->z.attrlen, l32(d->z.addr), l32(d->z.size));
456 78a779a3 2008-07-20 rsc fprint(fd, "%s 0x%2.2x %d %d %ld ",
457 13c28c2c 2008-12-02 trisk rdate(d->z.date, fmt), (fmt=='z' ? d->z.flags : d->r.flags),
458 13c28c2c 2008-12-02 trisk d->z.unitsize, d->z.gapsize, l16(d->z.vseqno));
459 13c28c2c 2008-12-02 trisk fprint(fd, "%d %s", d->z.namelen, nstr(d->z.name, d->z.namelen));
460 78a779a3 2008-07-20 rsc if(fmt != 'J'){
461 13c28c2c 2008-12-02 trisk namelen = d->z.namelen + (1-(d->z.namelen&1));
462 13c28c2c 2008-12-02 trisk syslen = d->z.reclen - 33 - namelen;
463 78a779a3 2008-07-20 rsc if(syslen != 0)
464 13c28c2c 2008-12-02 trisk fprint(fd, " %s", nstr(&d->z.name[namelen], syslen));
465 78a779a3 2008-07-20 rsc }
466 78a779a3 2008-07-20 rsc fprint(fd, "\n");
467 13c28c2c 2008-12-02 trisk return d->z.reclen + (d->z.reclen&1);
468 78a779a3 2008-07-20 rsc }
469 78a779a3 2008-07-20 rsc
470 78a779a3 2008-07-20 rsc static void
471 78a779a3 2008-07-20 rsc newdrec(Xfile *f, Drec *dp)
472 78a779a3 2008-07-20 rsc {
473 78a779a3 2008-07-20 rsc Isofile *x = f->ptr;
474 78a779a3 2008-07-20 rsc Isofile *n;
475 78a779a3 2008-07-20 rsc int len;
476 78a779a3 2008-07-20 rsc
477 13c28c2c 2008-12-02 trisk len = sizeof(Isofile) - sizeof(Drec) + dp->z.reclen;
478 78a779a3 2008-07-20 rsc n = ealloc(len);
479 78a779a3 2008-07-20 rsc n->fmt = x->fmt;
480 78a779a3 2008-07-20 rsc n->blksize = x->blksize;
481 78a779a3 2008-07-20 rsc n->offset = 0;
482 78a779a3 2008-07-20 rsc n->doffset = 0;
483 13c28c2c 2008-12-02 trisk memmove(&n->d, dp, dp->z.reclen);
484 78a779a3 2008-07-20 rsc free(x);
485 78a779a3 2008-07-20 rsc f->ptr = n;
486 78a779a3 2008-07-20 rsc f->len = len;
487 78a779a3 2008-07-20 rsc }
488 78a779a3 2008-07-20 rsc
489 78a779a3 2008-07-20 rsc static void
490 78a779a3 2008-07-20 rsc ungetdrec(Xfile *f)
491 78a779a3 2008-07-20 rsc {
492 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr;
493 78a779a3 2008-07-20 rsc
494 78a779a3 2008-07-20 rsc if(ip->offset >= ip->odelta){
495 78a779a3 2008-07-20 rsc ip->offset -= ip->odelta;
496 78a779a3 2008-07-20 rsc ip->odelta = 0;
497 78a779a3 2008-07-20 rsc }
498 78a779a3 2008-07-20 rsc }
499 78a779a3 2008-07-20 rsc
500 78a779a3 2008-07-20 rsc static int
501 78a779a3 2008-07-20 rsc getdrec(Xfile *f, void *buf)
502 78a779a3 2008-07-20 rsc {
503 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr;
504 78a779a3 2008-07-20 rsc int len = 0, boff = 0;
505 78a779a3 2008-07-20 rsc ulong size;
506 78a779a3 2008-07-20 rsc vlong addr;
507 78a779a3 2008-07-20 rsc Iobuf *p = 0;
508 78a779a3 2008-07-20 rsc
509 78a779a3 2008-07-20 rsc if(!ip)
510 78a779a3 2008-07-20 rsc return -1;
511 13c28c2c 2008-12-02 trisk size = l32(ip->d.z.size);
512 78a779a3 2008-07-20 rsc while(ip->offset < size){
513 13c28c2c 2008-12-02 trisk addr = (l32(ip->d.z.addr)+ip->d.z.attrlen)*ip->blksize + ip->offset;
514 78a779a3 2008-07-20 rsc boff = addr % Sectorsize;
515 78a779a3 2008-07-20 rsc if(boff > Sectorsize-34){
516 78a779a3 2008-07-20 rsc ip->offset += Sectorsize-boff;
517 78a779a3 2008-07-20 rsc continue;
518 78a779a3 2008-07-20 rsc }
519 78a779a3 2008-07-20 rsc p = getbuf(f->xf->d, addr/Sectorsize);
520 78a779a3 2008-07-20 rsc len = p->iobuf[boff];
521 78a779a3 2008-07-20 rsc if(len >= 34)
522 78a779a3 2008-07-20 rsc break;
523 78a779a3 2008-07-20 rsc putbuf(p);
524 78a779a3 2008-07-20 rsc p = 0;
525 78a779a3 2008-07-20 rsc ip->offset += Sectorsize-boff;
526 78a779a3 2008-07-20 rsc }
527 78a779a3 2008-07-20 rsc if(p) {
528 78a779a3 2008-07-20 rsc memmove(buf, &p->iobuf[boff], len);
529 78a779a3 2008-07-20 rsc putbuf(p);
530 78a779a3 2008-07-20 rsc ip->odelta = len + (len&1);
531 78a779a3 2008-07-20 rsc ip->offset += ip->odelta;
532 78a779a3 2008-07-20 rsc return 0;
533 78a779a3 2008-07-20 rsc }
534 78a779a3 2008-07-20 rsc return -1;
535 78a779a3 2008-07-20 rsc }
536 78a779a3 2008-07-20 rsc
537 78a779a3 2008-07-20 rsc static int
538 78a779a3 2008-07-20 rsc opendotdot(Xfile *f, Xfile *pf)
539 78a779a3 2008-07-20 rsc {
540 78a779a3 2008-07-20 rsc uchar dbuf[256];
541 78a779a3 2008-07-20 rsc Drec *d = (Drec *)dbuf;
542 78a779a3 2008-07-20 rsc Isofile *ip = f->ptr, *pip = pf->ptr;
543 78a779a3 2008-07-20 rsc
544 78a779a3 2008-07-20 rsc ip->offset = 0;
545 78a779a3 2008-07-20 rsc if(getdrec(f, d) < 0){
546 78a779a3 2008-07-20 rsc chat("opendotdot: getdrec(.) failed...");
547 78a779a3 2008-07-20 rsc return -1;
548 78a779a3 2008-07-20 rsc }
549 13c28c2c 2008-12-02 trisk if(d->z.namelen != 1 || d->z.name[0] != 0){
550 78a779a3 2008-07-20 rsc chat("opendotdot: no . entry...");
551 78a779a3 2008-07-20 rsc return -1;
552 78a779a3 2008-07-20 rsc }
553 13c28c2c 2008-12-02 trisk if(l32(d->z.addr) != l32(ip->d.z.addr)){
554 78a779a3 2008-07-20 rsc chat("opendotdot: bad . address...");
555 78a779a3 2008-07-20 rsc return -1;
556 78a779a3 2008-07-20 rsc }
557 78a779a3 2008-07-20 rsc if(getdrec(f, d) < 0){
558 78a779a3 2008-07-20 rsc chat("opendotdot: getdrec(..) failed...");
559 78a779a3 2008-07-20 rsc return -1;
560 78a779a3 2008-07-20 rsc }
561 13c28c2c 2008-12-02 trisk if(d->z.namelen != 1 || d->z.name[0] != 1){
562 78a779a3 2008-07-20 rsc chat("opendotdot: no .. entry...");
563 78a779a3 2008-07-20 rsc return -1;
564 78a779a3 2008-07-20 rsc }
565 78a779a3 2008-07-20 rsc
566 78a779a3 2008-07-20 rsc pf->xf = f->xf;
567 78a779a3 2008-07-20 rsc pip->fmt = ip->fmt;
568 78a779a3 2008-07-20 rsc pip->blksize = ip->blksize;
569 78a779a3 2008-07-20 rsc pip->offset = 0;
570 78a779a3 2008-07-20 rsc pip->doffset = 0;
571 78a779a3 2008-07-20 rsc pip->d = *d;
572 78a779a3 2008-07-20 rsc return 0;
573 78a779a3 2008-07-20 rsc }
574 78a779a3 2008-07-20 rsc
575 78a779a3 2008-07-20 rsc enum {
576 78a779a3 2008-07-20 rsc Hname = 1,
577 78a779a3 2008-07-20 rsc Hmode = 2,
578 78a779a3 2008-07-20 rsc };
579 78a779a3 2008-07-20 rsc
580 78a779a3 2008-07-20 rsc static int
581 78a779a3 2008-07-20 rsc rzdir(Xfs *fs, Dir *d, int fmt, Drec *dp)
582 78a779a3 2008-07-20 rsc {
583 78a779a3 2008-07-20 rsc int n, flags, i, j, lj, nl, vers, sysl, mode, l, have;
584 78a779a3 2008-07-20 rsc uchar *s;
585 78a779a3 2008-07-20 rsc char *p;
586 78a779a3 2008-07-20 rsc char buf[Maxname+UTFmax+1];
587 78a779a3 2008-07-20 rsc uchar *q;
588 78a779a3 2008-07-20 rsc Rune r;
589 78a779a3 2008-07-20 rsc enum { ONAMELEN = 28 }; /* old Plan 9 directory name length */
590 78a779a3 2008-07-20 rsc
591 78a779a3 2008-07-20 rsc have = 0;
592 78a779a3 2008-07-20 rsc flags = 0;
593 78a779a3 2008-07-20 rsc vers = -1;
594 13c28c2c 2008-12-02 trisk d->qid.path = l32(dp->z.addr);
595 78a779a3 2008-07-20 rsc d->qid.type = 0;
596 78a779a3 2008-07-20 rsc d->qid.vers = 0;
597 13c28c2c 2008-12-02 trisk n = dp->z.namelen;
598 78a779a3 2008-07-20 rsc memset(d->name, 0, Maxname);
599 78a779a3 2008-07-20 rsc if(n == 1) {
600 13c28c2c 2008-12-02 trisk switch(dp->z.name[0]){
601 78a779a3 2008-07-20 rsc case 1:
602 78a779a3 2008-07-20 rsc d->name[1] = '.';
603 78a779a3 2008-07-20 rsc /* fall through */
604 78a779a3 2008-07-20 rsc case 0:
605 78a779a3 2008-07-20 rsc d->name[0] = '.';
606 78a779a3 2008-07-20 rsc have = Hname;
607 78a779a3 2008-07-20 rsc break;
608 78a779a3 2008-07-20 rsc default:
609 13c28c2c 2008-12-02 trisk d->name[0] = tolower(dp->z.name[0]);
610 78a779a3 2008-07-20 rsc }
611 78a779a3 2008-07-20 rsc } else {
612 78a779a3 2008-07-20 rsc if(fmt == 'J'){ /* Joliet, 16-bit Unicode */
613 13c28c2c 2008-12-02 trisk q = (uchar*)dp->z.name;
614 78a779a3 2008-07-20 rsc for(i=j=lj=0; i<n && j<Maxname; i+=2){
615 78a779a3 2008-07-20 rsc lj = j;
616 78a779a3 2008-07-20 rsc r = (q[i]<<8)|q[i+1];
617 78a779a3 2008-07-20 rsc j += runetochar(buf+j, &r);
618 78a779a3 2008-07-20 rsc }
619 78a779a3 2008-07-20 rsc if(j >= Maxname)
620 78a779a3 2008-07-20 rsc j = lj;
621 78a779a3 2008-07-20 rsc memmove(d->name, buf, j);
622 78a779a3 2008-07-20 rsc }else{
623 78a779a3 2008-07-20 rsc if(n >= Maxname)
624 78a779a3 2008-07-20 rsc n = Maxname-1;
625 78a779a3 2008-07-20 rsc for(i=0; i<n; i++)
626 13c28c2c 2008-12-02 trisk d->name[i] = tolower(dp->z.name[i]);
627 78a779a3 2008-07-20 rsc }
628 78a779a3 2008-07-20 rsc }
629 78a779a3 2008-07-20 rsc
630 13c28c2c 2008-12-02 trisk sysl = dp->z.reclen-(34+dp->z.namelen);
631 13c28c2c 2008-12-02 trisk s = (uchar*)dp->z.name + dp->z.namelen;
632 78a779a3 2008-07-20 rsc if(((uintptr)s) & 1) {
633 78a779a3 2008-07-20 rsc s++;
634 78a779a3 2008-07-20 rsc sysl--;
635 78a779a3 2008-07-20 rsc }
636 78a779a3 2008-07-20 rsc if(fs->isplan9 && sysl > 0) {
637 78a779a3 2008-07-20 rsc /*
638 78a779a3 2008-07-20 rsc * get gid, uid, mode and possibly name
639 78a779a3 2008-07-20 rsc * from plan9 directory extension
640 78a779a3 2008-07-20 rsc */
641 78a779a3 2008-07-20 rsc nl = *s;
642 78a779a3 2008-07-20 rsc if(nl >= ONAMELEN)
643 78a779a3 2008-07-20 rsc nl = ONAMELEN-1;
644 78a779a3 2008-07-20 rsc if(nl) {
645 78a779a3 2008-07-20 rsc memset(d->name, 0, ONAMELEN);
646 78a779a3 2008-07-20 rsc memmove(d->name, s+1, nl);
647 78a779a3 2008-07-20 rsc }
648 78a779a3 2008-07-20 rsc s += 1 + *s;
649 78a779a3 2008-07-20 rsc nl = *s;
650 78a779a3 2008-07-20 rsc if(nl >= ONAMELEN)
651 78a779a3 2008-07-20 rsc nl = ONAMELEN-1;
652 78a779a3 2008-07-20 rsc memset(d->uid, 0, ONAMELEN);
653 78a779a3 2008-07-20 rsc memmove(d->uid, s+1, nl);
654 78a779a3 2008-07-20 rsc s += 1 + *s;
655 78a779a3 2008-07-20 rsc nl = *s;
656 78a779a3 2008-07-20 rsc if(nl >= ONAMELEN)
657 78a779a3 2008-07-20 rsc nl = ONAMELEN-1;
658 78a779a3 2008-07-20 rsc memset(d->gid, 0, ONAMELEN);
659 78a779a3 2008-07-20 rsc memmove(d->gid, s+1, nl);
660 78a779a3 2008-07-20 rsc s += 1 + *s;
661 78a779a3 2008-07-20 rsc if(((uintptr)s) & 1)
662 78a779a3 2008-07-20 rsc s++;
663 78a779a3 2008-07-20 rsc d->mode = l32(s);
664 78a779a3 2008-07-20 rsc if(d->mode & DMDIR)
665 78a779a3 2008-07-20 rsc d->qid.type |= QTDIR;
666 78a779a3 2008-07-20 rsc } else {
667 78a779a3 2008-07-20 rsc d->mode = 0444;
668 78a779a3 2008-07-20 rsc switch(fmt) {
669 78a779a3 2008-07-20 rsc case 'z':
670 78a779a3 2008-07-20 rsc if(fs->isrock)
671 78a779a3 2008-07-20 rsc strcpy(d->gid, "ridge");
672 78a779a3 2008-07-20 rsc else
673 78a779a3 2008-07-20 rsc strcpy(d->gid, "iso9660");
674 13c28c2c 2008-12-02 trisk flags = dp->z.flags;
675 78a779a3 2008-07-20 rsc break;
676 78a779a3 2008-07-20 rsc case 'r':
677 78a779a3 2008-07-20 rsc strcpy(d->gid, "sierra");
678 13c28c2c 2008-12-02 trisk flags = dp->r.flags;
679 78a779a3 2008-07-20 rsc break;
680 78a779a3 2008-07-20 rsc case 'J':
681 78a779a3 2008-07-20 rsc strcpy(d->gid, "joliet");
682 13c28c2c 2008-12-02 trisk flags = dp->z.flags;
683 78a779a3 2008-07-20 rsc break;
684 78a779a3 2008-07-20 rsc case '9':
685 78a779a3 2008-07-20 rsc strcpy(d->gid, "plan9");
686 13c28c2c 2008-12-02 trisk flags = dp->z.flags;
687 78a779a3 2008-07-20 rsc break;
688 78a779a3 2008-07-20 rsc }
689 78a779a3 2008-07-20 rsc if(flags & 0x02){
690 78a779a3 2008-07-20 rsc d->qid.type |= QTDIR;
691 78a779a3 2008-07-20 rsc d->mode |= DMDIR|0111;
692 78a779a3 2008-07-20 rsc }
693 78a779a3 2008-07-20 rsc strcpy(d->uid, "cdrom");
694 78a779a3 2008-07-20 rsc if(fmt!='9' && !(d->mode&DMDIR)){
695 78a779a3 2008-07-20 rsc /*
696 78a779a3 2008-07-20 rsc * ISO 9660 actually requires that you always have a . and a ;,
697 78a779a3 2008-07-20 rsc * even if there is no version and no extension. Very few writers
698 78a779a3 2008-07-20 rsc * do this. If the version is present, we use it for qid.vers.
699 78a779a3 2008-07-20 rsc * If there is no extension but there is a dot, we strip it off.
700 78a779a3 2008-07-20 rsc * (VMS heads couldn't comprehend the dot as a file name character
701 78a779a3 2008-07-20 rsc * rather than as just a separator between name and extension.)
702 78a779a3 2008-07-20 rsc *
703 78a779a3 2008-07-20 rsc * We don't do this for directory names because directories are
704 78a779a3 2008-07-20 rsc * not allowed to have extensions and versions.
705 78a779a3 2008-07-20 rsc */
706 78a779a3 2008-07-20 rsc if((p=strchr(d->name, ';')) != nil){
707 78a779a3 2008-07-20 rsc vers = strtoul(p+1, 0, 0);
708 78a779a3 2008-07-20 rsc d->qid.vers = vers;
709 78a779a3 2008-07-20 rsc *p = '\0';
710 78a779a3 2008-07-20 rsc }
711 78a779a3 2008-07-20 rsc if((p=strchr(d->name, '.')) != nil && *(p+1)=='\0')
712 78a779a3 2008-07-20 rsc *p = '\0';
713 78a779a3 2008-07-20 rsc }
714 78a779a3 2008-07-20 rsc if(fs->issusp){
715 78a779a3 2008-07-20 rsc nl = 0;
716 78a779a3 2008-07-20 rsc s += fs->suspoff;
717 78a779a3 2008-07-20 rsc sysl -= fs->suspoff;
718 78a779a3 2008-07-20 rsc for(; sysl >= 4 && have != (Hname|Hmode); sysl -= l, s += l){
719 78a779a3 2008-07-20 rsc if(s[0] == 0 && ((uintptr)s & 1)){
720 78a779a3 2008-07-20 rsc /* MacOS pads individual entries, contrary to spec */
721 78a779a3 2008-07-20 rsc s++;
722 78a779a3 2008-07-20 rsc sysl--;
723 78a779a3 2008-07-20 rsc }
724 78a779a3 2008-07-20 rsc l = s[2];
725 78a779a3 2008-07-20 rsc if(s[0] == 'P' && s[1] == 'X' && s[3] == 1){
726 78a779a3 2008-07-20 rsc /* posix file attributes */
727 78a779a3 2008-07-20 rsc mode = l32(s+4);
728 78a779a3 2008-07-20 rsc d->mode = mode & 0777;
729 78a779a3 2008-07-20 rsc if((mode & 0170000) == 040000){
730 78a779a3 2008-07-20 rsc d->mode |= DMDIR;
731 78a779a3 2008-07-20 rsc d->qid.type |= QTDIR;
732 78a779a3 2008-07-20 rsc }
733 78a779a3 2008-07-20 rsc have |= Hmode;
734 78a779a3 2008-07-20 rsc } else if(s[0] == 'N' && s[1] == 'M' && s[3] == 1){
735 78a779a3 2008-07-20 rsc /* alternative name */
736 78a779a3 2008-07-20 rsc if((s[4] & ~1) == 0){
737 78a779a3 2008-07-20 rsc i = nl+l-5;
738 78a779a3 2008-07-20 rsc if(i >= Maxname)
739 78a779a3 2008-07-20 rsc i = Maxname-1;
740 78a779a3 2008-07-20 rsc if((i -= nl) > 0){
741 78a779a3 2008-07-20 rsc memmove(d->name+nl, s+5, i);
742 78a779a3 2008-07-20 rsc nl += i;
743 78a779a3 2008-07-20 rsc }
744 78a779a3 2008-07-20 rsc if(s[4] == 0)
745 78a779a3 2008-07-20 rsc have |= Hname;
746 78a779a3 2008-07-20 rsc }
747 78a779a3 2008-07-20 rsc } else if(s[0] == 'C' && s[1] == 'E' && s[2] >= 28){
748 78a779a3 2008-07-20 rsc sysl = getcontin(fs->d, s, &s);
749 78a779a3 2008-07-20 rsc continue;
750 78a779a3 2008-07-20 rsc } else if(s[0] == 'S' && s[1] == 'T')
751 78a779a3 2008-07-20 rsc break;
752 78a779a3 2008-07-20 rsc }
753 78a779a3 2008-07-20 rsc }
754 78a779a3 2008-07-20 rsc }
755 78a779a3 2008-07-20 rsc d->length = 0;
756 78a779a3 2008-07-20 rsc if((d->mode & DMDIR) == 0)
757 13c28c2c 2008-12-02 trisk d->length = l32(dp->z.size);
758 78a779a3 2008-07-20 rsc d->type = 0;
759 78a779a3 2008-07-20 rsc d->dev = 0;
760 13c28c2c 2008-12-02 trisk d->atime = gtime(dp->z.date);
761 78a779a3 2008-07-20 rsc d->mtime = d->atime;
762 78a779a3 2008-07-20 rsc return vers;
763 78a779a3 2008-07-20 rsc }
764 78a779a3 2008-07-20 rsc
765 78a779a3 2008-07-20 rsc static int
766 78a779a3 2008-07-20 rsc getcontin(Xdata *dev, uchar *p, uchar **s)
767 78a779a3 2008-07-20 rsc {
768 78a779a3 2008-07-20 rsc long bn, off, len;
769 78a779a3 2008-07-20 rsc Iobuf *b;
770 78a779a3 2008-07-20 rsc
771 78a779a3 2008-07-20 rsc bn = l32(p+4);
772 78a779a3 2008-07-20 rsc off = l32(p+12);
773 78a779a3 2008-07-20 rsc len = l32(p+20);
774 78a779a3 2008-07-20 rsc chat("getcontin %d...", bn);
775 78a779a3 2008-07-20 rsc b = getbuf(dev, bn);
776 78a779a3 2008-07-20 rsc if(b == 0){
777 78a779a3 2008-07-20 rsc *s = 0;
778 78a779a3 2008-07-20 rsc return 0;
779 78a779a3 2008-07-20 rsc }
780 78a779a3 2008-07-20 rsc *s = b->iobuf+off;
781 78a779a3 2008-07-20 rsc putbuf(b);
782 78a779a3 2008-07-20 rsc return len;
783 78a779a3 2008-07-20 rsc }
784 78a779a3 2008-07-20 rsc
785 78a779a3 2008-07-20 rsc static char *
786 78a779a3 2008-07-20 rsc nstr(uchar *p, int n)
787 78a779a3 2008-07-20 rsc {
788 78a779a3 2008-07-20 rsc static char buf[132];
789 78a779a3 2008-07-20 rsc char *q = buf;
790 78a779a3 2008-07-20 rsc
791 78a779a3 2008-07-20 rsc while(--n >= 0){
792 78a779a3 2008-07-20 rsc if(*p == '\\')
793 78a779a3 2008-07-20 rsc *q++ = '\\';
794 78a779a3 2008-07-20 rsc if(' ' <= *p && *p <= '~')
795 78a779a3 2008-07-20 rsc *q++ = *p++;
796 78a779a3 2008-07-20 rsc else
797 78a779a3 2008-07-20 rsc q += sprint(q, "\\%2.2ux", *p++);
798 78a779a3 2008-07-20 rsc }
799 78a779a3 2008-07-20 rsc *q = 0;
800 78a779a3 2008-07-20 rsc return buf;
801 78a779a3 2008-07-20 rsc }
802 78a779a3 2008-07-20 rsc
803 78a779a3 2008-07-20 rsc static char *
804 78a779a3 2008-07-20 rsc rdate(uchar *p, int fmt)
805 78a779a3 2008-07-20 rsc {
806 78a779a3 2008-07-20 rsc static char buf[64];
807 78a779a3 2008-07-20 rsc int htz, s, n;
808 78a779a3 2008-07-20 rsc
809 78a779a3 2008-07-20 rsc n = sprint(buf, "%2.2d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d",
810 78a779a3 2008-07-20 rsc p[0], p[1], p[2], p[3], p[4], p[5]);
811 78a779a3 2008-07-20 rsc if(fmt == 'z'){
812 78a779a3 2008-07-20 rsc htz = p[6];
813 78a779a3 2008-07-20 rsc if(htz >= 128){
814 78a779a3 2008-07-20 rsc htz = 256-htz;
815 78a779a3 2008-07-20 rsc s = '-';
816 78a779a3 2008-07-20 rsc }else
817 78a779a3 2008-07-20 rsc s = '+';
818 78a779a3 2008-07-20 rsc sprint(&buf[n], " (%c%.1f)", s, (float)htz/2);
819 78a779a3 2008-07-20 rsc }
820 78a779a3 2008-07-20 rsc return buf;
821 78a779a3 2008-07-20 rsc }
822 78a779a3 2008-07-20 rsc
823 78a779a3 2008-07-20 rsc static char
824 78a779a3 2008-07-20 rsc dmsize[12] =
825 78a779a3 2008-07-20 rsc {
826 78a779a3 2008-07-20 rsc 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
827 78a779a3 2008-07-20 rsc };
828 78a779a3 2008-07-20 rsc
829 78a779a3 2008-07-20 rsc #define dysize mydysize
830 78a779a3 2008-07-20 rsc
831 78a779a3 2008-07-20 rsc static int
832 78a779a3 2008-07-20 rsc dysize(int y)
833 78a779a3 2008-07-20 rsc {
834 78a779a3 2008-07-20 rsc
835 78a779a3 2008-07-20 rsc if((y%4) == 0)
836 78a779a3 2008-07-20 rsc return 366;
837 78a779a3 2008-07-20 rsc return 365;
838 78a779a3 2008-07-20 rsc }
839 78a779a3 2008-07-20 rsc
840 78a779a3 2008-07-20 rsc static long
841 78a779a3 2008-07-20 rsc gtime(uchar *p) /* yMdhmsz */
842 78a779a3 2008-07-20 rsc {
843 78a779a3 2008-07-20 rsc long t;
844 78a779a3 2008-07-20 rsc int i, y, M, d, h, m, s, tz;
845 78a779a3 2008-07-20 rsc
846 78a779a3 2008-07-20 rsc y=p[0]; M=p[1]; d=p[2];
847 78a779a3 2008-07-20 rsc h=p[3]; m=p[4]; s=p[5]; tz=p[6];
848 78a779a3 2008-07-20 rsc USED(tz);
849 78a779a3 2008-07-20 rsc y += 1900;
850 78a779a3 2008-07-20 rsc if (y < 1970)
851 78a779a3 2008-07-20 rsc return 0;
852 78a779a3 2008-07-20 rsc if (M < 1 || M > 12)
853 78a779a3 2008-07-20 rsc return 0;
854 78a779a3 2008-07-20 rsc if (d < 1 || d > dmsize[M-1])
855 78a779a3 2008-07-20 rsc if (!(M == 2 && d == 29 && dysize(y) == 366))
856 78a779a3 2008-07-20 rsc return 0;
857 78a779a3 2008-07-20 rsc if (h > 23)
858 78a779a3 2008-07-20 rsc return 0;
859 78a779a3 2008-07-20 rsc if (m > 59)
860 78a779a3 2008-07-20 rsc return 0;
861 78a779a3 2008-07-20 rsc if (s > 59)
862 78a779a3 2008-07-20 rsc return 0;
863 78a779a3 2008-07-20 rsc t = 0;
864 78a779a3 2008-07-20 rsc for(i=1970; i<y; i++)
865 78a779a3 2008-07-20 rsc t += dysize(i);
866 78a779a3 2008-07-20 rsc if (dysize(y)==366 && M >= 3)
867 78a779a3 2008-07-20 rsc t++;
868 78a779a3 2008-07-20 rsc while(--M)
869 78a779a3 2008-07-20 rsc t += dmsize[M-1];
870 78a779a3 2008-07-20 rsc t += d-1;
871 78a779a3 2008-07-20 rsc t = 24*t + h;
872 78a779a3 2008-07-20 rsc t = 60*t + m;
873 78a779a3 2008-07-20 rsc t = 60*t + s;
874 78a779a3 2008-07-20 rsc return t;
875 78a779a3 2008-07-20 rsc }
876 78a779a3 2008-07-20 rsc
877 78a779a3 2008-07-20 rsc #define p ((uchar*)arg)
878 78a779a3 2008-07-20 rsc
879 78a779a3 2008-07-20 rsc static long
880 78a779a3 2008-07-20 rsc l16(void *arg)
881 78a779a3 2008-07-20 rsc {
882 78a779a3 2008-07-20 rsc long v;
883 78a779a3 2008-07-20 rsc
884 78a779a3 2008-07-20 rsc v = ((long)p[1]<<8)|p[0];
885 78a779a3 2008-07-20 rsc if (v >= 0x8000L)
886 78a779a3 2008-07-20 rsc v -= 0x10000L;
887 78a779a3 2008-07-20 rsc return v;
888 78a779a3 2008-07-20 rsc }
889 78a779a3 2008-07-20 rsc
890 78a779a3 2008-07-20 rsc static long
891 78a779a3 2008-07-20 rsc l32(void *arg)
892 78a779a3 2008-07-20 rsc {
893 78a779a3 2008-07-20 rsc return ((((((long)p[3]<<8)|p[2])<<8)|p[1])<<8)|p[0];
894 78a779a3 2008-07-20 rsc }
895 78a779a3 2008-07-20 rsc
896 78a779a3 2008-07-20 rsc #undef p