fixes in setproctitle to avoid problems with titles longer than
[unix-history] / usr / src / usr.sbin / mkproto / mkproto.c
CommitLineData
4ba29bcc
DF
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 */
6
7#ifndef lint
8char copyright[] =
9"@(#) Copyright (c) 1980 Regents of the University of California.\n\
10 All rights reserved.\n";
11#endif not lint
12
524aa063 13#ifndef lint
4ba29bcc
DF
14static char sccsid[] = "@(#)mkproto.c 5.1 (Berkeley) %G%";
15#endif not lint
86c6257f
KM
16
17/*
18 * Make a file system prototype.
19 * usage: mkproto filsys proto
20 */
21#include <stdio.h>
22#include <sys/param.h>
23#include <sys/inode.h>
24#include <sys/fs.h>
25#include <sys/dir.h>
26
27union {
28 struct fs fs;
29 char fsx[SBSIZE];
30} ufs;
31#define sblock ufs.fs
32union {
33 struct cg cg;
34 char cgx[MAXBSIZE];
35} ucg;
36#define acg ucg.cg
37struct fs *fs;
38struct csum *fscs;
39int fso, fsi;
40FILE *proto;
41char token[BUFSIZ];
42int errs;
43int ino = 10;
44long getnum();
45char *strcpy();
46
47main(argc, argv)
48 int argc;
49 char *argv[];
50{
51 int i;
52
53 if (argc != 3) {
54 fprintf(stderr, "usage: mkproto filsys proto\n");
55 exit(1);
56 }
57 fso = open(argv[1], 1);
58 fsi = open(argv[1], 0);
59 if (fso < 0 || fsi < 0) {
60 perror(argv[1]);
61 exit(1);
62 }
63 fs = &sblock;
64 rdfs(SBLOCK, SBSIZE, (char *)fs);
65 fscs = (struct csum *)calloc(1, fs->fs_cssize);
66 for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
67 rdfs(fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
68 (int)(fs->fs_cssize - i < fs->fs_bsize ?
69 fs->fs_cssize - i : fs->fs_bsize),
70 ((char *)fscs) + i);
71 proto = fopen(argv[2], "r");
72 descend((struct inode *)0);
73 wtfs(SBLOCK, SBSIZE, (char *)fs);
74 for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
75 wtfs(fsbtodb(&sblock, fs->fs_csaddr + numfrags(&sblock, i)),
76 (int)(fs->fs_cssize - i < fs->fs_bsize ?
77 fs->fs_cssize - i : fs->fs_bsize),
78 ((char *)fscs) + i);
79 exit(errs);
80}
81
82descend(par)
83 struct inode *par;
84{
85 struct inode in;
86 int ibc = 0;
87 int i, f, c;
88 struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)];
89 daddr_t ib[MAXBSIZE / sizeof (daddr_t)];
90 char buf[MAXBSIZE];
91
92 getstr();
93 in.i_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
94 in.i_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0);
95 in.i_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0);
96 for (i = 3; i < 6; i++) {
97 c = token[i];
98 if (c < '0' || c > '7') {
99 printf("%c/%s: bad octal mode digit\n", c, token);
100 errs++;
101 c = 0;
102 }
103 in.i_mode |= (c-'0')<<(15-3*i);
104 }
105 in.i_uid = getnum(); in.i_gid = getnum();
106 for (i = 0; i < fs->fs_bsize; i++)
107 buf[i] = 0;
108 for (i = 0; i < NINDIR(fs); i++)
109 ib[i] = (daddr_t)0;
110 in.i_nlink = 1;
111 in.i_size = 0;
112 for (i = 0; i < NDADDR; i++)
113 in.i_db[i] = (daddr_t)0;
114 for (i = 0; i < NIADDR; i++)
115 in.i_ib[i] = (daddr_t)0;
116 if (par != (struct inode *)0) {
117 ialloc(&in);
118 } else {
119 par = &in;
120 i = itod(fs, ROOTINO);
121 rdfs(fsbtodb(fs, i), fs->fs_bsize, (char *)inos);
122 dip = &inos[ROOTINO % INOPB(fs)];
123 in.i_number = ROOTINO;
124 in.i_nlink = dip->di_nlink;
125 in.i_size = dip->di_size;
126 in.i_db[0] = dip->di_db[0];
127 rdfs(fsbtodb(fs, in.i_db[0]), fs->fs_bsize, buf);
128 }
129
130 switch (in.i_mode&IFMT) {
131
132 case IFREG:
133 getstr();
134 f = open(token, 0);
135 if (f < 0) {
136 printf("%s: cannot open\n", token);
137 errs++;
138 break;
139 }
140 while ((i = read(f, buf, (int)fs->fs_bsize)) > 0) {
141 in.i_size += i;
142 newblk(buf, &ibc, ib, (int)blksize(fs, &in, ibc));
143 }
144 close(f);
145 break;
146
147 case IFBLK:
148 case IFCHR:
149 /*
150 * special file
151 * content is maj/min types
152 */
153
154 i = getnum() & 0377;
155 f = getnum() & 0377;
11f47f73 156 in.i_rdev = (i << 8) | f;
86c6257f
KM
157 break;
158
159 case IFDIR:
160 /*
161 * directory
162 * put in extra links
163 * call recursively until
164 * name of "$" found
165 */
166
167 if (in.i_number != ROOTINO) {
168 par->i_nlink++;
169 in.i_nlink++;
170 entry(&in, in.i_number, ".", buf);
171 entry(&in, par->i_number, "..", buf);
172 }
173 for (;;) {
174 getstr();
175 if (token[0]=='$' && token[1]=='\0')
176 break;
177 entry(&in, (ino_t)(ino+1), token, buf);
178 descend(&in);
179 }
180 if (in.i_number != ROOTINO)
181 newblk(buf, &ibc, ib, (int)blksize(fs, &in, 0));
182 else
183 wtfs(fsbtodb(fs, in.i_db[0]), (int)fs->fs_bsize, buf);
184 break;
185 }
186 iput(&in, &ibc, ib);
187}
188
189/*ARGSUSED*/
190gmode(c, s, m0, m1, m2, m3)
191 char c, *s;
192{
193 int i;
194
195 for (i = 0; s[i]; i++)
196 if (c == s[i])
197 return((&m0)[i]);
198 printf("%c/%s: bad mode\n", c, token);
199 errs++;
200 return(0);
201}
202
203long
204getnum()
205{
206 int i, c;
207 long n;
208
209 getstr();
210 n = 0;
211 i = 0;
212 for (i = 0; c=token[i]; i++) {
213 if (c<'0' || c>'9') {
214 printf("%s: bad number\n", token);
215 errs++;
216 return((long)0);
217 }
218 n = n*10 + (c-'0');
219 }
220 return(n);
221}
222
223getstr()
224{
225 int i, c;
226
227loop:
228 switch (c = getc(proto)) {
229
230 case ' ':
231 case '\t':
232 case '\n':
233 goto loop;
234
235 case EOF:
236 printf("Unexpected EOF\n");
237 exit(1);
238
239 case ':':
240 while (getc(proto) != '\n')
241 ;
242 goto loop;
243
244 }
245 i = 0;
246 do {
247 token[i++] = c;
248 c = getc(proto);
249 } while (c != ' ' && c != '\t' && c != '\n' && c != '\0');
250 token[i] = 0;
251}
252
253entry(ip, inum, str, buf)
254 struct inode *ip;
255 ino_t inum;
256 char *str;
257 char *buf;
258{
259 register struct direct *dp, *odp;
e84afc49 260 int oldsize, newsize, spacefree;
86c6257f
KM
261
262 odp = dp = (struct direct *)buf;
263 while ((int)dp - (int)buf < ip->i_size) {
264 odp = dp;
265 dp = (struct direct *)((int)dp + dp->d_reclen);
266 }
267 if (odp != dp)
268 oldsize = DIRSIZ(odp);
269 else
270 oldsize = 0;
e84afc49 271 spacefree = odp->d_reclen - oldsize;
86c6257f
KM
272 dp = (struct direct *)((int)odp + oldsize);
273 dp->d_ino = inum;
274 dp->d_namlen = strlen(str);
275 newsize = DIRSIZ(dp);
e84afc49 276 if (spacefree >= newsize) {
86c6257f 277 odp->d_reclen = oldsize;
e84afc49 278 dp->d_reclen = spacefree;
86c6257f
KM
279 } else {
280 dp = (struct direct *)((int)odp + odp->d_reclen);
281 if ((int)dp - (int)buf >= fs->fs_bsize) {
282 printf("directory too large\n");
283 exit(1);
284 }
285 dp->d_ino = inum;
286 dp->d_namlen = strlen(str);
287 dp->d_reclen = DIRBLKSIZ;
288 }
289 strcpy(dp->d_name, str);
290 ip->i_size = (int)dp - (int)buf + newsize;
291}
292
293newblk(buf, aibc, ib, size)
294 int *aibc;
295 char *buf;
296 daddr_t *ib;
297 int size;
298{
299 int i;
300 daddr_t bno;
301
302 bno = alloc(size);
303 wtfs(fsbtodb(fs, bno), (int)fs->fs_bsize, buf);
304 for (i = 0; i < fs->fs_bsize; i++)
305 buf[i] = 0;
306 ib[(*aibc)++] = bno;
307 if (*aibc >= NINDIR(fs)) {
308 printf("indirect block full\n");
309 errs++;
310 *aibc = 0;
311 }
312}
313
314iput(ip, aibc, ib)
315 struct inode *ip;
316 int *aibc;
317 daddr_t *ib;
318{
319 daddr_t d;
320 int i;
321 struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
322
323 ip->i_atime = ip->i_mtime = ip->i_ctime = time((long *)0);
324 switch (ip->i_mode&IFMT) {
325
326 case IFDIR:
327 case IFREG:
328 for (i = 0; i < *aibc; i++) {
329 if (i >= NDADDR)
330 break;
331 ip->i_db[i] = ib[i];
332 }
333 if (*aibc > NDADDR) {
334 ip->i_ib[0] = alloc((int)fs->fs_bsize);
335 for (i = 0; i < NINDIR(fs) - NDADDR; i++) {
336 ib[i] = ib[i+NDADDR];
337 ib[i+NDADDR] = (daddr_t)0;
338 }
339 wtfs(fsbtodb(fs, ip->i_ib[0]),
340 (int)fs->fs_bsize, (char *)ib);
341 }
342 break;
343
344 case IFBLK:
345 case IFCHR:
346 break;
347
348 default:
349 printf("bad mode %o\n", ip->i_mode);
350 exit(1);
351 }
352 d = fsbtodb(fs, itod(fs, ip->i_number));
353 rdfs(d, (int)fs->fs_bsize, (char *)buf);
354 buf[itoo(fs, ip->i_number)].di_ic = ip->i_ic;
355 wtfs(d, (int)fs->fs_bsize, (char *)buf);
356}
357
358daddr_t
359alloc(size)
360 int size;
361{
362 int i, frag;
363 daddr_t d;
364 static int cg = 0;
365
366again:
367 rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
368 (char *)&acg);
369 if (acg.cg_magic != CG_MAGIC) {
370 printf("cg %d: bad magic number\n", cg);
371 return (0);
372 }
373 if (acg.cg_cs.cs_nbfree == 0) {
374 cg++;
375 if (cg >= fs->fs_ncg) {
376 printf("ran out of space\n");
377 return (0);
378 }
379 goto again;
380 }
381 for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag)
382 if (isblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag))
383 goto goth;
384 printf("internal error: can't find block in cyl %d\n", cg);
385 return (0);
386goth:
387 clrblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag);
388 acg.cg_cs.cs_nbfree--;
389 sblock.fs_cstotal.cs_nbfree--;
390 fscs[cg].cs_nbfree--;
391 acg.cg_btot[cbtocylno(&sblock, d)]--;
392 acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--;
393 if (size != sblock.fs_bsize) {
394 frag = howmany(size, sblock.fs_fsize);
395 fscs[cg].cs_nffree += sblock.fs_frag - frag;
396 sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag;
397 acg.cg_cs.cs_nffree += sblock.fs_frag - frag;
398 acg.cg_frsum[sblock.fs_frag - frag]++;
399 for (i = frag; i < sblock.fs_frag; i++)
400 setbit(acg.cg_free, d + i);
401 }
402 wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
403 (char *)&acg);
404 return (acg.cg_cgx * fs->fs_fpg + d);
405}
406
407/*
408 * Allocate an inode on the disk
409 */
410ialloc(ip)
411 register struct inode *ip;
412{
413 struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
414 daddr_t d;
415 int c;
416
417 ip->i_number = ++ino;
418 c = itog(&sblock, ip->i_number);
419 rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
420 (char *)&acg);
421 if (acg.cg_magic != CG_MAGIC) {
422 printf("cg %d: bad magic number\n", c);
423 exit(1);
424 }
425 if (ip->i_mode & IFDIR) {
426 acg.cg_cs.cs_ndir++;
427 sblock.fs_cstotal.cs_ndir++;
428 fscs[c].cs_ndir++;
429 }
430 acg.cg_cs.cs_nifree--;
431 setbit(acg.cg_iused, ip->i_number);
432 wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
433 (char *)&acg);
434 sblock.fs_cstotal.cs_nifree--;
435 fscs[c].cs_nifree--;
436 if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) {
437 printf("fsinit: inode value out of range (%d).\n",
438 ip->i_number);
439 exit(1);
440 }
441 return (ip->i_number);
442}
443
444/*
445 * read a block from the file system
446 */
447rdfs(bno, size, bf)
448 int bno, size;
449 char *bf;
450{
451 int n;
452
453 if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) {
454 printf("seek error: %ld\n", bno);
455 perror("rdfs");
456 exit(1);
457 }
458 n = read(fsi, bf, size);
459 if(n != size) {
460 printf("read error: %ld\n", bno);
461 perror("rdfs");
462 exit(1);
463 }
464}
465
466/*
467 * write a block to the file system
468 */
469wtfs(bno, size, bf)
470 int bno, size;
471 char *bf;
472{
473 int n;
474
475 lseek(fso, bno * DEV_BSIZE, 0);
476 if (lseek(fso, bno * DEV_BSIZE, 0) < 0) {
477 printf("seek error: %ld\n", bno);
478 perror("wtfs");
479 exit(1);
480 }
481 n = write(fso, bf, size);
482 if(n != size) {
483 printf("write error: %D\n", bno);
484 perror("wtfs");
485 exit(1);
486 }
487}
488/*
489 * check if a block is available
490 */
491isblock(fs, cp, h)
492 struct fs *fs;
493 unsigned char *cp;
494 int h;
495{
496 unsigned char mask;
497
498 switch (fs->fs_frag) {
499 case 8:
500 return (cp[h] == 0xff);
501 case 4:
502 mask = 0x0f << ((h & 0x1) << 2);
503 return ((cp[h >> 1] & mask) == mask);
504 case 2:
505 mask = 0x03 << ((h & 0x3) << 1);
506 return ((cp[h >> 2] & mask) == mask);
507 case 1:
508 mask = 0x01 << (h & 0x7);
509 return ((cp[h >> 3] & mask) == mask);
510 default:
511 fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
512 return (0);
513 }
514 /*NOTREACHED*/
515}
516
517/*
518 * take a block out of the map
519 */
520clrblock(fs, cp, h)
521 struct fs *fs;
522 unsigned char *cp;
523 int h;
524{
525 switch ((fs)->fs_frag) {
526 case 8:
527 cp[h] = 0;
528 return;
529 case 4:
530 cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
531 return;
532 case 2:
533 cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
534 return;
535 case 1:
536 cp[h >> 3] &= ~(0x01 << (h & 0x7));
537 return;
538 default:
539 fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
540 return;
541 }
542}
543