|
|
1.1 root 1: /* read fstab and drive chuck */
2: /* this has to make up raw device names, or used the cooked devices */
3: #include <fstab.h>
4: #include <sys/param.h> /* param for BITFS */
5: #include <sys/stat.h>
6: #include <libc.h>
7:
8: enum {E64 = 64};
9: struct fstab fs[E64]; /* surely enough for all time */
10: int procs[E64], pstat[E64];
11: int min = 0x7fffffff, max = -1, exitcode, cnt;
12: char *options = "cwp:";
13: char *cmd = "/etc/chuck";
14: int wflag, cflag;
15: extern int errno;
16: extern char *sys_errlist[];
17: struct stat rst;
18:
19: main(argc, argv)
20: char **argv;
21: { int i, n;
22: int did;
23: extern int optind;
24: extern char *optarg;
25: struct fstab *p;
26: while((i = getopt(argc, argv, options)) != -1)
27: switch(i) {
28: default:
29: pmesg("weird opt %c, should be %s\n", i, options);
30: exit(1);
31: case 'w':
32: wflag = 1;
33: continue;
34: case 'p':
35: cmd = optarg;
36: continue;
37: case 'c':
38: cflag = 1;
39: continue;
40: }
41: stat("/", &rst);
42: for(n = 0; n < E64; n++)
43: if(p = getfsent())
44: fs[n] = *p;
45: else
46: break;
47: if(n >= E64)
48: pmesg("only doing %d entries from fstab\n", n);
49: cnt = n;
50: for(i = 0; i < n; i++) {
51: if(fs[i].fs_ftype != 0)
52: continue;
53: if(fs[i].fs_passno < min)
54: min = fs[i].fs_passno;
55: if(fs[i].fs_passno > max)
56: max = fs[i].fs_passno;
57: }
58: for(i = min; i <= max; i++)
59: pass(i);
60: for (did = 0, i = 0; i < n; i++) {
61: if (pstat[i] == 0)
62: continue;
63: if (did == 0) {
64: did++;
65: pmesg("Failed for:\n");
66: }
67: pmesg("%s\n", fs[i].fs_spec);
68: }
69: exit(exitcode);
70: }
71:
72: pass(n)
73: { int i, pid, stat;
74: for(i = 0; i < cnt; i++)
75: if(fs[i].fs_ftype == 0 && fs[i].fs_passno == n)
76: execit(i, fs+i);
77: while((pid = wait(&stat)) != -1) {
78: for(i = 0; i < cnt; i++)
79: if (procs[i] == pid)
80: break;
81: if (i >= cnt) {
82: pmesg("upchuck: unexpected wait pid %d stat %d\n", pid, stat);
83: continue;
84: }
85: pstat[i] = stat;
86: if (stat == 0)
87: continue;
88: exitcode = 1;
89: if (stat & 0377)
90: pmesg("%s: exit signal %d\n", stat);
91: pmesg("%s: do manually\n", fs[i].fs_spec);
92: }
93: }
94:
95: char *
96: guessraw(s)
97: char *s;
98: { char *p, *q, *strrchr();
99: if(cflag)
100: return(s);
101: p = strrchr(s, '/');
102: if(!p)
103: return(s);
104: q = (char *)malloc(strlen(s)+2);
105: *p = 0;
106: sprintf(q, "%s/r%s", s, p+1);
107: *p = '/';
108: if(access(q, 4) == 0)
109: return(q);
110: return(s);
111: }
112:
113: /* cooked device for root, otherwise raw if appropriate access */
114: execit(n, p)
115: struct fstab *p;
116: { int i, fl = 0;
117: struct stat stb;
118: char *s;
119: if(stat(p->fs_spec, &stb) < 0) {
120: exitcode = 1;
121: pmesg("couldn't stat (%s,%s)\n", p->fs_spec, sys_errlist[errno]);
122: return;
123: }
124: /* is it a wretched 4k or a wretched 1k file system? */
125: if(!BITFS(stb.st_rdev))
126: fl = 2;
127: if(stb.st_rdev == rst.st_dev) {
128: s = p->fs_spec;
129: goto known;
130: }
131: s = guessraw(p->fs_spec);
132: known:
133: switch(i = fork()) {
134: case -1:
135: exitcode = 1;
136: pmesg("upchuck couldn't fork (%s)\n", sys_errlist[errno]);
137: return;
138: case 0:
139: switch(fl+wflag) {
140: case 0:
141: execlp(cmd, cmd, s, 0);
142: break;
143: case 1:
144: execlp(cmd, cmd, "-w", s, 0);
145: break;
146: case 2:
147: execlp(cmd, cmd, "-b", "1024", s, 0);
148: break;
149: case 3:
150: execlp(cmd, cmd, "-w", "-b", "1024", s, 0);
151: break;
152: }
153: pmesg("upchuck couldn't exec %s (%s)\n", cmd, sys_errlist[errno]);
154: exit(1);
155: default:
156: procs[n] = i;
157: return;
158: }
159: }
160:
161: char ebuf[128];
162: pmesg(s, a, b, c, d, e, f)
163: char *s;
164: {
165: sprintf(ebuf, s, a, b, c, d, e, f);
166: write(2, ebuf, strlen(ebuf));
167: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.