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