add fifo_pathconf
[unix-history] / usr / src / sys / stand.att / open.c
CommitLineData
8a8c3c41
KB
1/*-
2 * Copyright (c) 1982, 1988 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.proprietary.c%
6 *
61ef809e 7 * @(#)open.c 7.6 (Berkeley) %G%
8a8c3c41
KB
8 */
9
10#include <sys/param.h>
11#include <sys/reboot.h>
38a01dbe 12
d8c95a01 13#include <ufs/ufs/dir.h>
61ef809e 14#include <stand.att/saio.h>
8a8c3c41
KB
15
16int firstopen;
17u_int opendev; /* last device opened */
18extern u_int bootdev;
19
20struct dirstuff {
21 int loc;
22 struct iob *io;
70192ca8 23 char *name;
8a8c3c41
KB
24};
25
26#ifndef SMALL
27static ino_t dlook __P((char *, struct iob *, char *));
28static int find __P((char *, struct iob *));
29static int getdev __P((char *, int));
30static int getunit __P((char *));
31static struct direct *readdir __P((struct dirstuff *));
32static int openi __P((int, struct iob *));
33#endif
34
35open(str, how)
36 char *str;
37 int how;
38{
39 static int firstopen = 1;
40 register struct iob *file;
41 register char *t;
42 register int cnt;
43 int fdesc, args[8], *argp;
44
45 if (firstopen) {
46 for (cnt = 0; cnt < SOPEN_MAX; cnt++)
47 iob[cnt].i_flgs = 0;
48 firstopen = 0;
49 }
50
51 for (fdesc = 0;; fdesc++) {
52 if (fdesc == SOPEN_MAX)
53 _stop("No more file slots");
54 if (iob[fdesc].i_flgs == 0) {
55 file = &iob[fdesc];
56 file->i_flgs |= F_ALLOC;
57 file->i_adapt = file->i_ctlr = file->i_unit =
58 file->i_part = 0;
59 break;
60 }
61 }
62
63 for (cnt = 0; cnt < sizeof(args)/sizeof(args[0]); args[cnt++] = 0);
64#ifndef SMALL
65 for (t = str; *t && *t != '/' && *t != ':' && *t != '('; ++t)
66 if (isupper(*t))
67 *t = tolower(*t);
68 switch(*t) {
69 case '(': /* type(adapt, ctlr, drive, partition)file */
70 if ((file->i_dev = getdev(str, t - str)) == -1)
71 goto bad;
72 for (argp = args + 4, cnt = 0; *t != ')'; ++cnt) {
73 for (++t; isspace(*t); ++t);
74 if (*t == ')')
75 break;
76 if (!isdigit(*t))
77 goto badspec;
78 *argp++ = atoi(t);
79 for (++t; isdigit(*t); ++t);
80 if (*t != ',' && *t != ')' || cnt == 4)
81 goto badspec;
82 }
83 for (++t; isspace(*t); ++t);
84 argp -= 4;
85 file->i_adapt = *argp++;
86 file->i_ctlr = *argp++;
87 file->i_unit = *argp++;
88 file->i_part = *argp;
89 break;
90 case ':': /* [A-Za-z]*[0-9]*[A-Za-z]:file */
91 for (t = str; *t != ':' && !isdigit(*t); ++t);
92 if ((file->i_dev = getdev(str, t - str)) == -1)
93 goto bad;
94 if ((file->i_unit = getunit(t)) == -1)
95 goto bad;
96 for (; isdigit(*t); ++t);
97 if (*t >= 'a' && *t <= 'h')
98 file->i_part = *t++ - 'a';
99 if (*t != ':') {
100 errno = EOFFSET;
101 goto badspec;
102 }
103 for (++t; isspace(*t); ++t);
104 break;
105 case '/':
106 default: /* default bootstrap unit and device */
107#else
108 {
109#endif /* SMALL */
110 file->i_dev = B_TYPE(bootdev);
111 file->i_adapt = B_ADAPTOR(bootdev);
112 file->i_ctlr = B_CONTROLLER(bootdev);
113 file->i_unit = B_UNIT(bootdev);
114 file->i_part = B_PARTITION(bootdev);
115 t = str;
116 }
117
118 opendev = MAKEBOOTDEV(file->i_dev, file->i_adapt, file->i_ctlr,
119 file->i_unit, file->i_part);
120
121 if (errno = devopen(file))
122 goto bad;
123
124 if (*t == '\0') {
125 file->i_flgs |= how + 1;
126 file->i_cc = 0;
127 file->i_offset = 0;
128 return (fdesc+3);
129 }
130#ifndef SMALL
131 else if (how != 0) {
132 printf("Can't write files yet.. Sorry\n");
133 errno = EIO;
134 goto bad;
135 }
136#endif
137 file->i_ma = (char *)(&file->i_fs);
138 file->i_cc = SBSIZE;
139 file->i_bn = SBOFF / DEV_BSIZE + file->i_boff;
140 file->i_offset = 0;
141 if (devread(file) < 0) {
142 errno = file->i_error;
143 printf("super block read error\n");
144 goto bad;
145 }
146 if ((cnt = find(t, file)) == 0) {
147 errno = ESRCH;
148 goto bad;
149 }
150 if (openi(cnt, file) < 0) {
151 errno = file->i_error;
152 goto bad;
153 }
154 file->i_offset = 0;
155 file->i_cc = 0;
156 file->i_flgs |= F_FILE | (how+1);
157 return (fdesc+3);
158
159#ifndef SMALL
160badspec:
161 printf("malformed device specification\nusage: device(adaptor, controller, drive, partition)file -or- <device><unit><partitionletter>:<file>\n");
162#endif
163bad:
164 file->i_flgs = 0;
165 return (-1);
166}
167
168#ifndef SMALL
169static
170getdev(str, len)
171 register char *str;
172 int len;
173{
174 register struct devsw *dp;
175 register int i;
176 char savedch = str[len];
177
178 str[len] = '\0';
179 for (dp = devsw, i = 0; i < ndevs; dp++, i++)
180 if (dp->dv_name && strcmp(str, dp->dv_name) == 0) {
181 str[len] = savedch;
182 return (i);
183 }
184 printf("Unknown device\nKnown devices are:\n");
185 for (dp = devsw, i = 0; i < ndevs; dp++, i++)
186 if (dp->dv_name)
187 printf(" %s", dp->dv_name);
188 printf("\n");
189 errno = ENXIO;
190 return (-1);
191}
192
193static
194getunit(cp)
195 register char *cp;
196{
197 int unit;
198
199 unit = atoi(cp);
200 if ((u_int)unit > 255) {
201 printf("minor device number out of range (0-255)\n");
202 errno = EUNIT;
203 return (-1);
204 }
205 return (unit);
206}
207#endif /* SMALL */
208
209static
210find(path, file)
211 register char *path;
212 struct iob *file;
213{
214 register char *q;
215 char *dir, c;
216 int n;
217
218 if (path == NULL || *path == '\0') {
219 printf("null path\n");
220 return (0);
221 }
222
223 if (openi((ino_t) ROOTINO, file) < 0) {
224 printf("can't read root inode\n");
225 return (0);
226 }
227 dir = path;
228 while (*path) {
229 while (*path == '/')
230 path++;
231 q = path;
232 while(*q != '/' && *q != '\0')
233 q++;
234 c = *q;
235 *q = '\0';
236 if (q == path) path = "." ; /* "/" means "/." */
237
238 if ((n = dlook(path, file, dir)) != 0) {
239 if (c == '\0')
240 break;
241 if (openi(n, file) < 0)
242 return (0);
243 *q = c;
244 path = q;
245 continue;
246 } else {
247 printf("%s: not found\n", path);
248 return (0);
249 }
250 }
251 return (n);
252}
253
254static ino_t
255dlook(s, io, dir)
256 char *s;
257 register struct iob *io;
258 char *dir;
259{
260 register struct direct *dp;
261 register struct dinode *ip;
262 struct dirstuff dirp;
263 int len;
264
265 if (s == NULL || *s == '\0')
266 return (0);
267 ip = &io->i_ino;
268 if ((ip->di_mode&IFMT) != IFDIR) {
269 printf("%s: not a directory\n", dir);
270 return (0);
271 }
272 if (ip->di_size == 0) {
273 printf("%s: zero length directory\n", dir);
274 return (0);
275 }
276 len = strlen(s);
277 dirp.loc = 0;
278 dirp.io = io;
70192ca8 279 dirp.name = dir;
8a8c3c41
KB
280 for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
281 if(dp->d_ino == 0)
282 continue;
283 if (dp->d_namlen == len && !strcmp(s, dp->d_name))
284 return (dp->d_ino);
285 }
286 return (0);
287}
288
289static struct direct *
290readdir(dirp)
291 register struct dirstuff *dirp;
292{
293 register struct direct *dp;
294 register struct iob *io;
295 daddr_t lbn, d;
296 int off;
297
298 io = dirp->io;
299 for(;;) {
300 if (dirp->loc >= io->i_ino.di_size)
301 return (NULL);
302 off = blkoff(&io->i_fs, dirp->loc);
303 if (off == 0) {
304 lbn = lblkno(&io->i_fs, dirp->loc);
305 d = bmap(io, lbn);
306 if(d == 0)
307 return (NULL);
308 io->i_bn = fsbtodb(&io->i_fs, d) + io->i_boff;
309 io->i_ma = io->i_buf;
310 io->i_cc = dblksize(&io->i_fs, &io->i_ino, lbn);
311 if (devread(io) < 0) {
312 errno = io->i_error;
70192ca8
MH
313 printf("%s: directory read error, bn %ld\n",
314 dirp->name, io->i_bn);
8a8c3c41
KB
315 return (NULL);
316 }
317 }
318 dp = (struct direct *)(io->i_buf + off);
319 dirp->loc += dp->d_reclen;
70192ca8
MH
320 if (dp->d_ino == 0) {
321 if (dp->d_reclen == 0) {
322 printf("%s: bad directory entry, offset %ld\n",
323 dirp->name, dirp->loc);
324 return (NULL);
325 }
8a8c3c41 326 continue;
70192ca8 327 }
8a8c3c41
KB
328 return (dp);
329 }
330}
331
332static
333openi(n, io)
334 int n;
335 register struct iob *io;
336{
337 register struct dinode *dp;
338 int cc;
339
340 io->i_offset = 0;
341 io->i_bn = fsbtodb(&io->i_fs, itod(&io->i_fs, n)) + io->i_boff;
342 io->i_cc = io->i_fs.fs_bsize;
343 io->i_ma = io->i_buf;
344 cc = devread(io);
345 dp = (struct dinode *)io->i_buf;
346 io->i_ino = dp[itoo(&io->i_fs, n)];
347 return (cc);
348}