1*41084Swilliam /*-
2*41084Swilliam * Copyright (c) 1990 The Regents of the University of California.
3*41084Swilliam * All rights reserved.
4*41084Swilliam *
5*41084Swilliam * This code is derived from software contributed to Berkeley by
6*41084Swilliam * William Jolitz.
7*41084Swilliam *
8*41084Swilliam * %sccs.include.noredist.c%
9*41084Swilliam *
10*41084Swilliam * @(#)sys.c 7.1 (Berkeley) 04/24/90
11*41084Swilliam */
12*41084Swilliam
13*41084Swilliam #include "../h/param.h"
14*41084Swilliam #include "../h/inode.h"
15*41084Swilliam #include "../h/fs.h"
16*41084Swilliam #undef KERNEL
17*41084Swilliam #include "../h/dir.h"
18*41084Swilliam #include "saio.h"
19*41084Swilliam
20*41084Swilliam #define DEV_IOSIZE 1024
21*41084Swilliam
22*41084Swilliam #define DB printf("%s:%d\n",__FILE__,__LINE__)
23*41084Swilliam ino_t dlook();
24*41084Swilliam
25*41084Swilliam struct dirstuff {
26*41084Swilliam int loc;
27*41084Swilliam struct iob *io;
28*41084Swilliam };
29*41084Swilliam
30*41084Swilliam #undef register
31*41084Swilliam
32*41084Swilliam static
openi(n,io)33*41084Swilliam openi(n, io)
34*41084Swilliam register struct iob *io;
35*41084Swilliam {
36*41084Swilliam register struct dinode *dp;
37*41084Swilliam int cc;
38*41084Swilliam
39*41084Swilliam io->i_offset = 0;
40*41084Swilliam io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
41*41084Swilliam io->i_cc = io->i_fs.fs_bsize;
42*41084Swilliam io->i_ma = io->i_buf;
43*41084Swilliam cc = devread(io);
44*41084Swilliam dp = (struct dinode *)io->i_buf;
45*41084Swilliam io->i_ino.i_ic = dp[itoo(&io->i_fs, n)].di_ic;
46*41084Swilliam return (cc);
47*41084Swilliam }
48*41084Swilliam
49*41084Swilliam static
find(path,file)50*41084Swilliam find(path, file)
51*41084Swilliam register char *path;
52*41084Swilliam struct iob *file;
53*41084Swilliam {
54*41084Swilliam register char *q;
55*41084Swilliam char c;
56*41084Swilliam int n;
57*41084Swilliam
58*41084Swilliam if (path==NULL || *path=='\0') {
59*41084Swilliam printf("null path\n");
60*41084Swilliam return (0);
61*41084Swilliam }
62*41084Swilliam
63*41084Swilliam if (openi((ino_t) ROOTINO, file) < 0) {
64*41084Swilliam printf("can't read root inode\n");
65*41084Swilliam return (0);
66*41084Swilliam }
67*41084Swilliam while (*path) {
68*41084Swilliam while (*path == '/')
69*41084Swilliam path++;
70*41084Swilliam q = path;
71*41084Swilliam while(*q != '/' && *q != '\0')
72*41084Swilliam q++;
73*41084Swilliam c = *q;
74*41084Swilliam *q = '\0';
75*41084Swilliam if (path == q) path = "." ; /* / means /. */
76*41084Swilliam
77*41084Swilliam if ((n = dlook(path, file)) != 0) {
78*41084Swilliam if (c == '\0')
79*41084Swilliam break;
80*41084Swilliam if (openi(n, file) < 0)
81*41084Swilliam return (0);
82*41084Swilliam *q = c;
83*41084Swilliam path = q;
84*41084Swilliam continue;
85*41084Swilliam } else {
86*41084Swilliam printf("%s: not found\n", path);
87*41084Swilliam return (0);
88*41084Swilliam }
89*41084Swilliam }
90*41084Swilliam return (n);
91*41084Swilliam }
92*41084Swilliam
93*41084Swilliam char b[MAXBSIZE];
94*41084Swilliam daddr_t blkno;
95*41084Swilliam
96*41084Swilliam static daddr_t
sbmap(io,bn)97*41084Swilliam sbmap(io, bn)
98*41084Swilliam register struct iob *io;
99*41084Swilliam daddr_t bn;
100*41084Swilliam {
101*41084Swilliam register struct inode *ip;
102*41084Swilliam int i, j, sh;
103*41084Swilliam daddr_t nb, *bap;
104*41084Swilliam
105*41084Swilliam ip = &io->i_ino;
106*41084Swilliam if (bn < 0) {
107*41084Swilliam printf("bn negative\n");
108*41084Swilliam return ((daddr_t)0);
109*41084Swilliam }
110*41084Swilliam
111*41084Swilliam /*
112*41084Swilliam * blocks 0..NDADDR are direct blocks
113*41084Swilliam */
114*41084Swilliam if(bn < NDADDR) {
115*41084Swilliam nb = ip->i_db[bn];
116*41084Swilliam return (nb);
117*41084Swilliam }
118*41084Swilliam
119*41084Swilliam /*
120*41084Swilliam * addresses NIADDR have single and double indirect blocks.
121*41084Swilliam * the first step is to determine how many levels of indirection.
122*41084Swilliam */
123*41084Swilliam sh = 1;
124*41084Swilliam bn -= NDADDR;
125*41084Swilliam for (j = NIADDR; j > 0; j--) {
126*41084Swilliam sh *= NINDIR(&io->i_fs);
127*41084Swilliam if (bn < sh)
128*41084Swilliam break;
129*41084Swilliam bn -= sh;
130*41084Swilliam }
131*41084Swilliam if (j == 0) {
132*41084Swilliam printf("bn ovf %D\n", bn);
133*41084Swilliam return ((daddr_t)0);
134*41084Swilliam }
135*41084Swilliam
136*41084Swilliam /*
137*41084Swilliam * fetch the first indirect block address from the inode
138*41084Swilliam */
139*41084Swilliam nb = ip->i_ib[NIADDR - j];
140*41084Swilliam if (nb == 0) {
141*41084Swilliam printf("bn void %D\n",bn);
142*41084Swilliam return ((daddr_t)0);
143*41084Swilliam }
144*41084Swilliam
145*41084Swilliam /*
146*41084Swilliam * fetch through the indirect blocks
147*41084Swilliam */
148*41084Swilliam for (; j <= NIADDR; j++) {
149*41084Swilliam if (blkno != nb) {
150*41084Swilliam io->i_bn = fsbtodb(&io->i_fs, nb) + io->i_boff;
151*41084Swilliam io->i_ma = b;
152*41084Swilliam io->i_cc = io->i_fs.fs_bsize;
153*41084Swilliam if (devread(io) != io->i_fs.fs_bsize) {
154*41084Swilliam if (io->i_error)
155*41084Swilliam errno = io->i_error;
156*41084Swilliam printf("bn %D: read error\n", io->i_bn);
157*41084Swilliam return ((daddr_t)0);
158*41084Swilliam }
159*41084Swilliam blkno = nb;
160*41084Swilliam }
161*41084Swilliam bap = (daddr_t *)b;
162*41084Swilliam sh /= NINDIR(&io->i_fs);
163*41084Swilliam i = (bn / sh) % NINDIR(&io->i_fs);
164*41084Swilliam nb = bap[i];
165*41084Swilliam if(nb == 0) {
166*41084Swilliam printf("bn void %D\n",bn);
167*41084Swilliam return ((daddr_t)0);
168*41084Swilliam }
169*41084Swilliam }
170*41084Swilliam return (nb);
171*41084Swilliam }
172*41084Swilliam
173*41084Swilliam static ino_t
dlook(s,io)174*41084Swilliam dlook(s, io)
175*41084Swilliam char *s;
176*41084Swilliam register struct iob *io;
177*41084Swilliam {
178*41084Swilliam register struct direct *dp;
179*41084Swilliam register struct inode *ip;
180*41084Swilliam struct dirstuff dirp;
181*41084Swilliam int len;
182*41084Swilliam
183*41084Swilliam if (s == NULL || *s == '\0')
184*41084Swilliam return (0);
185*41084Swilliam ip = &io->i_ino;
186*41084Swilliam if ((ip->i_mode&IFMT) != IFDIR) {
187*41084Swilliam printf("%s: not a directory\n", s);
188*41084Swilliam return (0);
189*41084Swilliam }
190*41084Swilliam if (ip->i_size == 0) {
191*41084Swilliam printf("%s: zero length directory\n", s);
192*41084Swilliam return (0);
193*41084Swilliam }
194*41084Swilliam len = strlen(s);
195*41084Swilliam dirp.loc = 0;
196*41084Swilliam dirp.io = io;
197*41084Swilliam for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
198*41084Swilliam if(dp->d_ino == 0)
199*41084Swilliam continue;
200*41084Swilliam if (dp->d_namlen == len && !strcmp(s, dp->d_name))
201*41084Swilliam return (dp->d_ino);
202*41084Swilliam }
203*41084Swilliam return (0);
204*41084Swilliam }
205*41084Swilliam
206*41084Swilliam /*
207*41084Swilliam * get next entry in a directory.
208*41084Swilliam */
209*41084Swilliam struct direct *
readdir(dirp)210*41084Swilliam readdir(dirp)
211*41084Swilliam register struct dirstuff *dirp;
212*41084Swilliam {
213*41084Swilliam register struct direct *dp;
214*41084Swilliam register struct iob *io;
215*41084Swilliam daddr_t lbn, d;
216*41084Swilliam int off;
217*41084Swilliam
218*41084Swilliam io = dirp->io;
219*41084Swilliam for(;;) {
220*41084Swilliam if (dirp->loc >= io->i_ino.i_size)
221*41084Swilliam return (NULL);
222*41084Swilliam off = blkoff(&io->i_fs, dirp->loc);
223*41084Swilliam if (off == 0) {
224*41084Swilliam lbn = lblkno(&io->i_fs, dirp->loc);
225*41084Swilliam d = sbmap(io, lbn);
226*41084Swilliam if(d == 0)
227*41084Swilliam return NULL;
228*41084Swilliam io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
229*41084Swilliam io->i_ma = io->i_buf;
230*41084Swilliam io->i_cc = blksize(&io->i_fs, &io->i_ino, lbn);
231*41084Swilliam if (devread(io) < 0) {
232*41084Swilliam errno = io->i_error;
233*41084Swilliam printf("bn %D: directory read error\n",
234*41084Swilliam io->i_bn);
235*41084Swilliam return (NULL);
236*41084Swilliam }
237*41084Swilliam }
238*41084Swilliam dp = (struct direct *)(io->i_buf + off);
239*41084Swilliam dirp->loc += dp->d_reclen;
240*41084Swilliam if (dp->d_ino == 0)
241*41084Swilliam continue;
242*41084Swilliam return (dp);
243*41084Swilliam }
244*41084Swilliam }
245*41084Swilliam
lseek(fdesc,addr,ptr)246*41084Swilliam lseek(fdesc, addr, ptr)
247*41084Swilliam int fdesc, ptr;
248*41084Swilliam off_t addr;
249*41084Swilliam {
250*41084Swilliam register struct iob *io;
251*41084Swilliam
252*41084Swilliam if (ptr != 0) {
253*41084Swilliam printf("seek not from beginning of file\n");
254*41084Swilliam errno = EOFFSET;
255*41084Swilliam return (-1);
256*41084Swilliam }
257*41084Swilliam fdesc -= 3;
258*41084Swilliam if (fdesc < 0 || fdesc >= NFILES ||
259*41084Swilliam ((io = &iob[fdesc])->i_flgs & F_ALLOC) == 0) {
260*41084Swilliam errno = EBADF;
261*41084Swilliam return (-1);
262*41084Swilliam }
263*41084Swilliam io->i_offset = addr;
264*41084Swilliam io->i_cc = 0;
265*41084Swilliam return (0);
266*41084Swilliam }
267*41084Swilliam
getc(fdesc)268*41084Swilliam getc(fdesc)
269*41084Swilliam int fdesc;
270*41084Swilliam {
271*41084Swilliam register struct iob *io;
272*41084Swilliam register struct fs *fs;
273*41084Swilliam register char *p;
274*41084Swilliam int c, lbn, off, size, diff;
275*41084Swilliam
276*41084Swilliam
277*41084Swilliam errno = 0 ;
278*41084Swilliam if (fdesc >= 0 && fdesc <= 2)
279*41084Swilliam return (getchar());
280*41084Swilliam fdesc -= 3;
281*41084Swilliam if (fdesc < 0 || fdesc >= NFILES ||
282*41084Swilliam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
283*41084Swilliam errno = EBADF;
284*41084Swilliam return (-1);
285*41084Swilliam }
286*41084Swilliam p = io->i_ma;
287*41084Swilliam if (io->i_cc <= 0) {
288*41084Swilliam if ((io->i_flgs & F_FILE) != 0) {
289*41084Swilliam diff = io->i_ino.i_size - io->i_offset;
290*41084Swilliam if (diff <= 0)
291*41084Swilliam return (-1);
292*41084Swilliam fs = &io->i_fs;
293*41084Swilliam lbn = lblkno(fs, io->i_offset);
294*41084Swilliam io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
295*41084Swilliam off = blkoff(fs, io->i_offset);
296*41084Swilliam size = blksize(fs, &io->i_ino, lbn);
297*41084Swilliam } else {
298*41084Swilliam io->i_bn = io->i_offset / DEV_IOSIZE *
299*41084Swilliam (DEV_IOSIZE/DEV_BSIZE);
300*41084Swilliam off = io->i_offset % DEV_IOSIZE;
301*41084Swilliam size = DEV_IOSIZE;
302*41084Swilliam }
303*41084Swilliam io->i_ma = io->i_buf;
304*41084Swilliam io->i_cc = size;
305*41084Swilliam if (devread(io) <= 0) {
306*41084Swilliam errno = io->i_error;
307*41084Swilliam return (-1);
308*41084Swilliam }
309*41084Swilliam if ((io->i_flgs & F_FILE) != 0) {
310*41084Swilliam if (io->i_offset - off + size >= io->i_ino.i_size)
311*41084Swilliam io->i_cc = diff + off;
312*41084Swilliam io->i_cc -= off;
313*41084Swilliam }
314*41084Swilliam p = &io->i_buf[off];
315*41084Swilliam }
316*41084Swilliam io->i_cc--;
317*41084Swilliam io->i_offset++;
318*41084Swilliam c = (unsigned)*p++;
319*41084Swilliam io->i_ma = p;
320*41084Swilliam return (c);
321*41084Swilliam }
322*41084Swilliam
323*41084Swilliam /* does this port?
324*41084Swilliam getw(fdesc)
325*41084Swilliam int fdesc;
326*41084Swilliam {
327*41084Swilliam register w,i;
328*41084Swilliam register char *cp;
329*41084Swilliam int val;
330*41084Swilliam
331*41084Swilliam for (i = 0, val = 0, cp = &val; i < sizeof(val); i++) {
332*41084Swilliam w = getc(fdesc);
333*41084Swilliam if (w < 0) {
334*41084Swilliam if (i == 0)
335*41084Swilliam return (-1);
336*41084Swilliam else
337*41084Swilliam return (val);
338*41084Swilliam }
339*41084Swilliam *cp++ = w;
340*41084Swilliam }
341*41084Swilliam return (val);
342*41084Swilliam }
343*41084Swilliam */
344*41084Swilliam int errno;
345*41084Swilliam
read(fdesc,buf,count)346*41084Swilliam read(fdesc, buf, count)
347*41084Swilliam int fdesc, count;
348*41084Swilliam char *buf;
349*41084Swilliam {
350*41084Swilliam register int i, size;
351*41084Swilliam register struct iob *io;
352*41084Swilliam register struct fs *fs;
353*41084Swilliam int lbn, off;
354*41084Swilliam
355*41084Swilliam errno = 0;
356*41084Swilliam if (fdesc >= 0 & fdesc <= 2) {
357*41084Swilliam i = count;
358*41084Swilliam do {
359*41084Swilliam *buf = getchar();
360*41084Swilliam } while (--i && *buf++ != '\n');
361*41084Swilliam return (count - i);
362*41084Swilliam }
363*41084Swilliam fdesc -= 3;
364*41084Swilliam if (fdesc < 0 || fdesc >= NFILES ||
365*41084Swilliam ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
366*41084Swilliam errno = EBADF;
367*41084Swilliam return (-1);
368*41084Swilliam }
369*41084Swilliam if ((io->i_flgs&F_READ) == 0) {
370*41084Swilliam errno = EBADF;
371*41084Swilliam return (-1);
372*41084Swilliam }
373*41084Swilliam /*#ifndef SMALL*/
374*41084Swilliam if ((io->i_flgs & F_FILE) == 0) {
375*41084Swilliam #ifndef SMALL
376*41084Swilliam if (io->i_offset % 512 || count % 512) {
377*41084Swilliam #endif
378*41084Swilliam i = count;
379*41084Swilliam do {
380*41084Swilliam *buf++ = getc(fdesc+3);
381*41084Swilliam } while (--i);
382*41084Swilliam return (count - i);
383*41084Swilliam #ifndef SMALL
384*41084Swilliam } else {
385*41084Swilliam io->i_cc = count;
386*41084Swilliam io->i_ma = buf;
387*41084Swilliam io->i_bn = io->i_boff + (io->i_offset / DEV_BSIZE);
388*41084Swilliam i = devread(io);
389*41084Swilliam io->i_offset += count;
390*41084Swilliam if (i < 0)
391*41084Swilliam errno = io->i_error;
392*41084Swilliam return (i);
393*41084Swilliam }
394*41084Swilliam #endif
395*41084Swilliam }
396*41084Swilliam if (io->i_offset+count > io->i_ino.i_size)
397*41084Swilliam count = io->i_ino.i_size - io->i_offset;
398*41084Swilliam if ((i = count) <= 0)
399*41084Swilliam return (0);
400*41084Swilliam /*
401*41084Swilliam * While reading full blocks, do I/O into user buffer.
402*41084Swilliam * Anything else uses getc().
403*41084Swilliam */
404*41084Swilliam fs = &io->i_fs;
405*41084Swilliam while (i) {
406*41084Swilliam off = blkoff(fs, io->i_offset);
407*41084Swilliam lbn = lblkno(fs, io->i_offset);
408*41084Swilliam size = blksize(fs, &io->i_ino, lbn);
409*41084Swilliam if (off == 0 && size <= i) {
410*41084Swilliam io->i_bn = fsbtodb(fs, sbmap(io, lbn)) + io->i_boff;
411*41084Swilliam io->i_cc = size;
412*41084Swilliam io->i_ma = buf;
413*41084Swilliam if (devread(io) < 0) {
414*41084Swilliam errno = io->i_error;
415*41084Swilliam return (-1);
416*41084Swilliam }
417*41084Swilliam io->i_offset += size;
418*41084Swilliam io->i_cc = 0;
419*41084Swilliam buf += size;
420*41084Swilliam i -= size;
421*41084Swilliam } else {
422*41084Swilliam size -= off;
423*41084Swilliam if (size > i)
424*41084Swilliam size = i;
425*41084Swilliam i -= size;
426*41084Swilliam do {
427*41084Swilliam *buf++ = getc(fdesc+3);
428*41084Swilliam } while (--size);
429*41084Swilliam }
430*41084Swilliam }
431*41084Swilliam return (count);
432*41084Swilliam }
433*41084Swilliam
434*41084Swilliam #ifndef SMALL
write(fdesc,buf,count)435*41084Swilliam write(fdesc, buf, count)
436*41084Swilliam int fdesc, count;
437*41084Swilliam char *buf;
438*41084Swilliam {
439*41084Swilliam register int i;
440*41084Swilliam register struct iob *file;
441*41084Swilliam
442*41084Swilliam errno = 0;
443*41084Swilliam if (fdesc >= 0 && fdesc <= 2) {
444*41084Swilliam i = count;
445*41084Swilliam while (i--)
446*41084Swilliam putchar(*buf++);
447*41084Swilliam return (count);
448*41084Swilliam }
449*41084Swilliam fdesc -= 3;
450*41084Swilliam if (fdesc < 0 || fdesc >= NFILES ||
451*41084Swilliam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
452*41084Swilliam errno = EBADF;
453*41084Swilliam return (-1);
454*41084Swilliam }
455*41084Swilliam if ((file->i_flgs&F_WRITE) == 0) {
456*41084Swilliam errno = EBADF;
457*41084Swilliam return (-1);
458*41084Swilliam }
459*41084Swilliam file->i_cc = count;
460*41084Swilliam file->i_ma = buf;
461*41084Swilliam file->i_bn = file->i_boff + (file->i_offset / DEV_BSIZE);
462*41084Swilliam i = devwrite(file);
463*41084Swilliam file->i_offset += count;
464*41084Swilliam if (i < 0)
465*41084Swilliam errno = file->i_error;
466*41084Swilliam return (i);
467*41084Swilliam }
468*41084Swilliam #endif
469*41084Swilliam
470*41084Swilliam int openfirst = 1;
471*41084Swilliam int opendev; /* last device opened; for boot to set bootdev */
472*41084Swilliam
open(str,how)473*41084Swilliam open(str, how)
474*41084Swilliam char *str;
475*41084Swilliam int how;
476*41084Swilliam {
477*41084Swilliam register char *cp;
478*41084Swilliam int i;
479*41084Swilliam register struct iob *file;
480*41084Swilliam register struct devsw *dp;
481*41084Swilliam int fdesc;
482*41084Swilliam long atol();
483*41084Swilliam extern int bootdev;
484*41084Swilliam
485*41084Swilliam if (openfirst) {
486*41084Swilliam for (i = 0; i < NFILES; i++)
487*41084Swilliam iob[i].i_flgs = 0;
488*41084Swilliam openfirst = 0;
489*41084Swilliam }
490*41084Swilliam
491*41084Swilliam for (fdesc = 0; fdesc < NFILES; fdesc++)
492*41084Swilliam if (iob[fdesc].i_flgs == 0)
493*41084Swilliam goto gotfile;
494*41084Swilliam _stop("no more file slots");
495*41084Swilliam gotfile:
496*41084Swilliam (file = &iob[fdesc])->i_flgs |= F_ALLOC;
497*41084Swilliam
498*41084Swilliam for (cp = str; *cp && *cp != '/' && *cp != ':'; cp++)
499*41084Swilliam ;
500*41084Swilliam if (*cp != ':') {
501*41084Swilliam /* default bootstrap unit and device */
502*41084Swilliam file->i_ino.i_dev = bootdev;
503*41084Swilliam cp = str;
504*41084Swilliam } else {
505*41084Swilliam # define isdigit(n) ((n>='0') && (n<='9'))
506*41084Swilliam /*
507*41084Swilliam * syntax for possible device name:
508*41084Swilliam * <alpha-string><digit-string><letter>:
509*41084Swilliam */
510*41084Swilliam for (cp = str; *cp != ':' && !isdigit(*cp); cp++)
511*41084Swilliam ;
512*41084Swilliam for (dp = devsw; dp->dv_name; dp++) {
513*41084Swilliam if (!strncmp(str, dp->dv_name,cp-str))
514*41084Swilliam goto gotdev;
515*41084Swilliam }
516*41084Swilliam printf("unknown device\n");
517*41084Swilliam file->i_flgs = 0;
518*41084Swilliam errno = ENXIO;
519*41084Swilliam return (-1);
520*41084Swilliam gotdev:
521*41084Swilliam i = 0;
522*41084Swilliam while (*cp >= '0' && *cp <= '9')
523*41084Swilliam i = i * 10 + *cp++ - '0';
524*41084Swilliam if (i < 0 || i > 255) {
525*41084Swilliam printf("minor device number out of range (0-255)\n");
526*41084Swilliam file->i_flgs = 0;
527*41084Swilliam errno = EUNIT;
528*41084Swilliam return (-1);
529*41084Swilliam }
530*41084Swilliam if (*cp >= 'a' && *cp <= 'h') {
531*41084Swilliam if (i > 31) {
532*41084Swilliam printf("unit number out of range (0-31)\n");
533*41084Swilliam file->i_flgs = 0;
534*41084Swilliam errno = EUNIT;
535*41084Swilliam return (-1);
536*41084Swilliam }
537*41084Swilliam i = make_minor(i, *cp++ - 'a');
538*41084Swilliam }
539*41084Swilliam
540*41084Swilliam if (*cp++ != ':') {
541*41084Swilliam printf("incorrect device specification\n");
542*41084Swilliam file->i_flgs = 0;
543*41084Swilliam errno = EOFFSET;
544*41084Swilliam return (-1);
545*41084Swilliam }
546*41084Swilliam file->i_ino.i_dev = makedev(dp-devsw, i);
547*41084Swilliam }
548*41084Swilliam file->i_boff = 0;
549*41084Swilliam devopen(file);
550*41084Swilliam opendev = file->i_ino.i_dev;
551*41084Swilliam if (cp != str && *cp == '\0') {
552*41084Swilliam file->i_flgs |= how+1;
553*41084Swilliam file->i_cc = 0;
554*41084Swilliam file->i_offset = 0;
555*41084Swilliam return (fdesc+3);
556*41084Swilliam }
557*41084Swilliam file->i_ma = file->i_buf;
558*41084Swilliam file->i_cc = SBSIZE;
559*41084Swilliam file->i_bn = SBLOCK + file->i_boff;
560*41084Swilliam file->i_offset = 0;
561*41084Swilliam if (devread(file) < 0) {
562*41084Swilliam errno = file->i_error;
563*41084Swilliam printf("super block read error\n");
564*41084Swilliam return (-1);
565*41084Swilliam }
566*41084Swilliam file->i_fs = *(struct fs *)(file->i_buf);
567*41084Swilliam if ((i = find(cp, file)) == 0) {
568*41084Swilliam file->i_flgs = 0;
569*41084Swilliam errno = ESRCH;
570*41084Swilliam return (-1);
571*41084Swilliam }
572*41084Swilliam if (how != 0) {
573*41084Swilliam printf("can't write files yet.. sorry\n");
574*41084Swilliam file->i_flgs = 0;
575*41084Swilliam errno = EIO;
576*41084Swilliam return (-1);
577*41084Swilliam }
578*41084Swilliam if (openi(i, file) < 0) {
579*41084Swilliam errno = file->i_error;
580*41084Swilliam return (-1);
581*41084Swilliam }
582*41084Swilliam file->i_offset = 0;
583*41084Swilliam file->i_cc = 0;
584*41084Swilliam file->i_flgs |= F_FILE | (how+1);
585*41084Swilliam return (fdesc+3);
586*41084Swilliam }
587*41084Swilliam
close(fdesc)588*41084Swilliam close(fdesc)
589*41084Swilliam int fdesc;
590*41084Swilliam {
591*41084Swilliam struct iob *file;
592*41084Swilliam
593*41084Swilliam fdesc -= 3;
594*41084Swilliam if (fdesc < 0 || fdesc >= NFILES ||
595*41084Swilliam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
596*41084Swilliam errno = EBADF;
597*41084Swilliam return (-1);
598*41084Swilliam }
599*41084Swilliam if ((file->i_flgs&F_FILE) == 0)
600*41084Swilliam devclose(file);
601*41084Swilliam file->i_flgs = 0;
602*41084Swilliam return (0);
603*41084Swilliam }
604*41084Swilliam
605*41084Swilliam #ifndef SMALL
ioctl(fdesc,cmd,arg)606*41084Swilliam ioctl(fdesc, cmd, arg)
607*41084Swilliam int fdesc, cmd;
608*41084Swilliam char *arg;
609*41084Swilliam {
610*41084Swilliam register struct iob *file;
611*41084Swilliam int error = 0;
612*41084Swilliam
613*41084Swilliam fdesc -= 3;
614*41084Swilliam if (fdesc < 0 || fdesc >= NFILES ||
615*41084Swilliam ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0) {
616*41084Swilliam errno = EBADF;
617*41084Swilliam return (-1);
618*41084Swilliam }
619*41084Swilliam switch (cmd) {
620*41084Swilliam
621*41084Swilliam case SAIOHDR:
622*41084Swilliam file->i_flgs |= F_HDR;
623*41084Swilliam break;
624*41084Swilliam
625*41084Swilliam case SAIOCHECK:
626*41084Swilliam file->i_flgs |= F_CHECK;
627*41084Swilliam break;
628*41084Swilliam
629*41084Swilliam case SAIOHCHECK:
630*41084Swilliam file->i_flgs |= F_HCHECK;
631*41084Swilliam break;
632*41084Swilliam
633*41084Swilliam case SAIONOBAD:
634*41084Swilliam file->i_flgs |= F_NBSF;
635*41084Swilliam break;
636*41084Swilliam
637*41084Swilliam case SAIODOBAD:
638*41084Swilliam file->i_flgs &= ~F_NBSF;
639*41084Swilliam break;
640*41084Swilliam
641*41084Swilliam case SAIOECCLIM:
642*41084Swilliam file->i_flgs |= F_ECCLM;
643*41084Swilliam break;
644*41084Swilliam
645*41084Swilliam case SAIOECCUNL:
646*41084Swilliam file->i_flgs &= ~F_ECCLM;
647*41084Swilliam break;
648*41084Swilliam
649*41084Swilliam case SAIOSEVRE:
650*41084Swilliam file->i_flgs |= F_SEVRE;
651*41084Swilliam break;
652*41084Swilliam
653*41084Swilliam case SAIONSEVRE:
654*41084Swilliam file->i_flgs &= ~F_SEVRE;
655*41084Swilliam break;
656*41084Swilliam
657*41084Swilliam default:
658*41084Swilliam error = devioctl(file, cmd, arg);
659*41084Swilliam break;
660*41084Swilliam }
661*41084Swilliam if (error < 0)
662*41084Swilliam errno = file->i_error;
663*41084Swilliam return (error);
664*41084Swilliam }
665*41084Swilliam #endif
666*41084Swilliam
_stop(s)667*41084Swilliam _stop(s)
668*41084Swilliam char *s;
669*41084Swilliam {
670*41084Swilliam int i;
671*41084Swilliam
672*41084Swilliam for (i = 0; i < NFILES; i++)
673*41084Swilliam if (iob[i].i_flgs != 0)
674*41084Swilliam close(i);
675*41084Swilliam printf("%s\n", s);
676*41084Swilliam _rtt();
677*41084Swilliam }
678*41084Swilliam
trap(ps)679*41084Swilliam trap(ps)
680*41084Swilliam int ps;
681*41084Swilliam {
682*41084Swilliam printf("trap %o\n", ps);
683*41084Swilliam for (;;)
684*41084Swilliam ;
685*41084Swilliam }
686