Blame


1 d2173bb5 2012-07-17 rsc #include <u.h>
2 d2173bb5 2012-07-17 rsc #include <libc.h>
3 d2173bb5 2012-07-17 rsc #include <auth.h>
4 d2173bb5 2012-07-17 rsc #include <bio.h>
5 d2173bb5 2012-07-17 rsc
6 fee1a463 2012-08-05 rsc #define mkdir plan9mkdir
7 d2173bb5 2012-07-17 rsc #define getmode plan9_getmode
8 d2173bb5 2012-07-17 rsc #define setuid plan9_setuid
9 d2173bb5 2012-07-17 rsc
10 d2173bb5 2012-07-17 rsc enum{
11 d2173bb5 2012-07-17 rsc LEN = 8*1024,
12 d2173bb5 2012-07-17 rsc HUNKS = 128,
13 d2173bb5 2012-07-17 rsc
14 d2173bb5 2012-07-17 rsc /*
15 d2173bb5 2012-07-17 rsc * types of destination file sytems
16 d2173bb5 2012-07-17 rsc */
17 d2173bb5 2012-07-17 rsc Kfs = 0,
18 d2173bb5 2012-07-17 rsc Fs,
19 d2173bb5 2012-07-17 rsc Archive,
20 d2173bb5 2012-07-17 rsc };
21 d2173bb5 2012-07-17 rsc
22 d2173bb5 2012-07-17 rsc typedef struct File File;
23 d2173bb5 2012-07-17 rsc
24 d2173bb5 2012-07-17 rsc struct File{
25 d2173bb5 2012-07-17 rsc char *new;
26 d2173bb5 2012-07-17 rsc char *elem;
27 d2173bb5 2012-07-17 rsc char *old;
28 d2173bb5 2012-07-17 rsc char *uid;
29 d2173bb5 2012-07-17 rsc char *gid;
30 d2173bb5 2012-07-17 rsc ulong mode;
31 d2173bb5 2012-07-17 rsc };
32 d2173bb5 2012-07-17 rsc
33 d2173bb5 2012-07-17 rsc void arch(Dir*);
34 d2173bb5 2012-07-17 rsc void copy(Dir*);
35 d2173bb5 2012-07-17 rsc int copyfile(File*, Dir*, int);
36 d2173bb5 2012-07-17 rsc void* emalloc(ulong);
37 d2173bb5 2012-07-17 rsc void error(char *, ...);
38 d2173bb5 2012-07-17 rsc void freefile(File*);
39 d2173bb5 2012-07-17 rsc File* getfile(File*);
40 d2173bb5 2012-07-17 rsc char* getmode(char*, ulong*);
41 d2173bb5 2012-07-17 rsc char* getname(char*, char**);
42 d2173bb5 2012-07-17 rsc char* getpath(char*);
43 d2173bb5 2012-07-17 rsc void kfscmd(char *);
44 d2173bb5 2012-07-17 rsc void mkdir(Dir*);
45 d2173bb5 2012-07-17 rsc int mkfile(File*);
46 d2173bb5 2012-07-17 rsc void mkfs(File*, int);
47 d2173bb5 2012-07-17 rsc char* mkpath(char*, char*);
48 d2173bb5 2012-07-17 rsc void mktree(File*, int);
49 d2173bb5 2012-07-17 rsc void mountkfs(char*);
50 d2173bb5 2012-07-17 rsc void printfile(File*);
51 d2173bb5 2012-07-17 rsc void setnames(File*);
52 d2173bb5 2012-07-17 rsc void setusers(void);
53 d2173bb5 2012-07-17 rsc void skipdir(void);
54 d2173bb5 2012-07-17 rsc char* strdup(char*);
55 d2173bb5 2012-07-17 rsc int uptodate(Dir*, char*);
56 d2173bb5 2012-07-17 rsc void usage(void);
57 d2173bb5 2012-07-17 rsc void warn(char *, ...);
58 d2173bb5 2012-07-17 rsc
59 d2173bb5 2012-07-17 rsc Biobuf *b;
60 d2173bb5 2012-07-17 rsc Biobuf bout; /* stdout when writing archive */
61 d2173bb5 2012-07-17 rsc uchar boutbuf[2*LEN];
62 d2173bb5 2012-07-17 rsc char newfile[LEN];
63 d2173bb5 2012-07-17 rsc char oldfile[LEN];
64 d2173bb5 2012-07-17 rsc char *proto;
65 d2173bb5 2012-07-17 rsc char *cputype;
66 d2173bb5 2012-07-17 rsc char *users;
67 d2173bb5 2012-07-17 rsc char *oldroot;
68 d2173bb5 2012-07-17 rsc char *newroot;
69 d2173bb5 2012-07-17 rsc char *prog = "mkfs";
70 d2173bb5 2012-07-17 rsc int lineno;
71 d2173bb5 2012-07-17 rsc char *buf;
72 d2173bb5 2012-07-17 rsc char *zbuf;
73 d2173bb5 2012-07-17 rsc int buflen = 1024-8;
74 d2173bb5 2012-07-17 rsc int indent;
75 d2173bb5 2012-07-17 rsc int verb;
76 d2173bb5 2012-07-17 rsc int modes;
77 d2173bb5 2012-07-17 rsc int ream;
78 d2173bb5 2012-07-17 rsc int debug;
79 d2173bb5 2012-07-17 rsc int xflag;
80 d2173bb5 2012-07-17 rsc int sfd;
81 d2173bb5 2012-07-17 rsc int fskind; /* Kfs, Fs, Archive */
82 d2173bb5 2012-07-17 rsc int setuid; /* on Fs: set uid and gid? */
83 d2173bb5 2012-07-17 rsc char *user;
84 d2173bb5 2012-07-17 rsc
85 d2173bb5 2012-07-17 rsc void
86 d2173bb5 2012-07-17 rsc main(int argc, char **argv)
87 d2173bb5 2012-07-17 rsc {
88 d2173bb5 2012-07-17 rsc File file;
89 d2173bb5 2012-07-17 rsc char *name;
90 d2173bb5 2012-07-17 rsc int i, errs;
91 d2173bb5 2012-07-17 rsc
92 d2173bb5 2012-07-17 rsc quotefmtinstall();
93 d2173bb5 2012-07-17 rsc user = getuser();
94 d2173bb5 2012-07-17 rsc name = "";
95 d2173bb5 2012-07-17 rsc memset(&file, 0, sizeof file);
96 d2173bb5 2012-07-17 rsc file.new = "";
97 d2173bb5 2012-07-17 rsc file.old = 0;
98 d2173bb5 2012-07-17 rsc oldroot = "";
99 d2173bb5 2012-07-17 rsc newroot = "/n/kfs";
100 d2173bb5 2012-07-17 rsc users = 0;
101 d2173bb5 2012-07-17 rsc fskind = Kfs;
102 d2173bb5 2012-07-17 rsc ARGBEGIN{
103 d2173bb5 2012-07-17 rsc case 'a':
104 d2173bb5 2012-07-17 rsc if(fskind != Kfs) {
105 d2173bb5 2012-07-17 rsc fprint(2, "cannot use -a with -d\n");
106 d2173bb5 2012-07-17 rsc usage();
107 d2173bb5 2012-07-17 rsc }
108 d2173bb5 2012-07-17 rsc fskind = Archive;
109 d2173bb5 2012-07-17 rsc newroot = "";
110 d2173bb5 2012-07-17 rsc Binits(&bout, 1, OWRITE, boutbuf, sizeof boutbuf);
111 d2173bb5 2012-07-17 rsc break;
112 d2173bb5 2012-07-17 rsc case 'd':
113 d2173bb5 2012-07-17 rsc if(fskind != Kfs) {
114 d2173bb5 2012-07-17 rsc fprint(2, "cannot use -d with -a\n");
115 d2173bb5 2012-07-17 rsc usage();
116 d2173bb5 2012-07-17 rsc }
117 d2173bb5 2012-07-17 rsc fskind = Fs;
118 d2173bb5 2012-07-17 rsc newroot = ARGF();
119 d2173bb5 2012-07-17 rsc break;
120 d2173bb5 2012-07-17 rsc case 'D':
121 d2173bb5 2012-07-17 rsc debug = 1;
122 d2173bb5 2012-07-17 rsc break;
123 d2173bb5 2012-07-17 rsc case 'n':
124 d2173bb5 2012-07-17 rsc name = EARGF(usage());
125 d2173bb5 2012-07-17 rsc break;
126 d2173bb5 2012-07-17 rsc case 'p':
127 d2173bb5 2012-07-17 rsc modes = 1;
128 d2173bb5 2012-07-17 rsc break;
129 d2173bb5 2012-07-17 rsc case 'r':
130 d2173bb5 2012-07-17 rsc ream = 1;
131 d2173bb5 2012-07-17 rsc break;
132 d2173bb5 2012-07-17 rsc case 's':
133 d2173bb5 2012-07-17 rsc oldroot = ARGF();
134 d2173bb5 2012-07-17 rsc break;
135 d2173bb5 2012-07-17 rsc case 'u':
136 d2173bb5 2012-07-17 rsc users = ARGF();
137 d2173bb5 2012-07-17 rsc break;
138 d2173bb5 2012-07-17 rsc case 'U':
139 d2173bb5 2012-07-17 rsc setuid = 1;
140 d2173bb5 2012-07-17 rsc break;
141 d2173bb5 2012-07-17 rsc case 'v':
142 d2173bb5 2012-07-17 rsc verb = 1;
143 d2173bb5 2012-07-17 rsc break;
144 d2173bb5 2012-07-17 rsc case 'x':
145 d2173bb5 2012-07-17 rsc xflag = 1;
146 d2173bb5 2012-07-17 rsc break;
147 d2173bb5 2012-07-17 rsc case 'z':
148 d2173bb5 2012-07-17 rsc buflen = atoi(ARGF())-8;
149 d2173bb5 2012-07-17 rsc break;
150 d2173bb5 2012-07-17 rsc default:
151 d2173bb5 2012-07-17 rsc usage();
152 d2173bb5 2012-07-17 rsc }ARGEND
153 d2173bb5 2012-07-17 rsc
154 fa325e9b 2020-01-10 cross if(!argc)
155 d2173bb5 2012-07-17 rsc usage();
156 d2173bb5 2012-07-17 rsc
157 d2173bb5 2012-07-17 rsc buf = emalloc(buflen);
158 d2173bb5 2012-07-17 rsc zbuf = emalloc(buflen);
159 d2173bb5 2012-07-17 rsc memset(zbuf, 0, buflen);
160 d2173bb5 2012-07-17 rsc
161 d2173bb5 2012-07-17 rsc mountkfs(name);
162 d2173bb5 2012-07-17 rsc kfscmd("allow");
163 d2173bb5 2012-07-17 rsc proto = "users";
164 d2173bb5 2012-07-17 rsc setusers();
165 d2173bb5 2012-07-17 rsc cputype = getenv("cputype");
166 d2173bb5 2012-07-17 rsc if(cputype == 0)
167 d2173bb5 2012-07-17 rsc cputype = "68020";
168 d2173bb5 2012-07-17 rsc
169 d2173bb5 2012-07-17 rsc errs = 0;
170 d2173bb5 2012-07-17 rsc for(i = 0; i < argc; i++){
171 d2173bb5 2012-07-17 rsc proto = argv[i];
172 d2173bb5 2012-07-17 rsc fprint(2, "processing %q\n", proto);
173 d2173bb5 2012-07-17 rsc
174 d2173bb5 2012-07-17 rsc b = Bopen(proto, OREAD);
175 d2173bb5 2012-07-17 rsc if(!b){
176 d2173bb5 2012-07-17 rsc fprint(2, "%q: can't open %q: skipping\n", prog, proto);
177 d2173bb5 2012-07-17 rsc errs++;
178 d2173bb5 2012-07-17 rsc continue;
179 d2173bb5 2012-07-17 rsc }
180 d2173bb5 2012-07-17 rsc
181 d2173bb5 2012-07-17 rsc lineno = 0;
182 d2173bb5 2012-07-17 rsc indent = 0;
183 d2173bb5 2012-07-17 rsc mkfs(&file, -1);
184 d2173bb5 2012-07-17 rsc Bterm(b);
185 d2173bb5 2012-07-17 rsc }
186 d2173bb5 2012-07-17 rsc fprint(2, "file system made\n");
187 d2173bb5 2012-07-17 rsc kfscmd("disallow");
188 d2173bb5 2012-07-17 rsc kfscmd("sync");
189 d2173bb5 2012-07-17 rsc if(errs)
190 d2173bb5 2012-07-17 rsc exits("skipped protos");
191 d2173bb5 2012-07-17 rsc if(fskind == Archive){
192 d2173bb5 2012-07-17 rsc Bprint(&bout, "end of archive\n");
193 d2173bb5 2012-07-17 rsc Bterm(&bout);
194 d2173bb5 2012-07-17 rsc }
195 d2173bb5 2012-07-17 rsc exits(0);
196 d2173bb5 2012-07-17 rsc }
197 d2173bb5 2012-07-17 rsc
198 d2173bb5 2012-07-17 rsc void
199 d2173bb5 2012-07-17 rsc mkfs(File *me, int level)
200 d2173bb5 2012-07-17 rsc {
201 d2173bb5 2012-07-17 rsc File *child;
202 d2173bb5 2012-07-17 rsc int rec;
203 d2173bb5 2012-07-17 rsc
204 d2173bb5 2012-07-17 rsc child = getfile(me);
205 d2173bb5 2012-07-17 rsc if(!child)
206 d2173bb5 2012-07-17 rsc return;
207 d2173bb5 2012-07-17 rsc if((child->elem[0] == '+' || child->elem[0] == '*') && child->elem[1] == '\0'){
208 d2173bb5 2012-07-17 rsc rec = child->elem[0] == '+';
209 d2173bb5 2012-07-17 rsc free(child->new);
210 d2173bb5 2012-07-17 rsc child->new = strdup(me->new);
211 d2173bb5 2012-07-17 rsc setnames(child);
212 d2173bb5 2012-07-17 rsc mktree(child, rec);
213 d2173bb5 2012-07-17 rsc freefile(child);
214 d2173bb5 2012-07-17 rsc child = getfile(me);
215 d2173bb5 2012-07-17 rsc }
216 d2173bb5 2012-07-17 rsc while(child && indent > level){
217 d2173bb5 2012-07-17 rsc if(mkfile(child))
218 d2173bb5 2012-07-17 rsc mkfs(child, indent);
219 d2173bb5 2012-07-17 rsc freefile(child);
220 d2173bb5 2012-07-17 rsc child = getfile(me);
221 d2173bb5 2012-07-17 rsc }
222 d2173bb5 2012-07-17 rsc if(child){
223 d2173bb5 2012-07-17 rsc freefile(child);
224 d2173bb5 2012-07-17 rsc Bseek(b, -Blinelen(b), 1);
225 d2173bb5 2012-07-17 rsc lineno--;
226 d2173bb5 2012-07-17 rsc }
227 d2173bb5 2012-07-17 rsc }
228 d2173bb5 2012-07-17 rsc
229 d2173bb5 2012-07-17 rsc void
230 d2173bb5 2012-07-17 rsc mktree(File *me, int rec)
231 d2173bb5 2012-07-17 rsc {
232 d2173bb5 2012-07-17 rsc File child;
233 d2173bb5 2012-07-17 rsc Dir *d;
234 d2173bb5 2012-07-17 rsc int i, n, fd;
235 d2173bb5 2012-07-17 rsc
236 d2173bb5 2012-07-17 rsc fd = open(oldfile, OREAD);
237 d2173bb5 2012-07-17 rsc if(fd < 0){
238 d2173bb5 2012-07-17 rsc warn("can't open %q: %r", oldfile);
239 d2173bb5 2012-07-17 rsc return;
240 d2173bb5 2012-07-17 rsc }
241 d2173bb5 2012-07-17 rsc
242 d2173bb5 2012-07-17 rsc child = *me;
243 d2173bb5 2012-07-17 rsc while((n = dirread(fd, &d)) > 0){
244 d2173bb5 2012-07-17 rsc for(i = 0; i < n; i++){
245 d2173bb5 2012-07-17 rsc child.new = mkpath(me->new, d[i].name);
246 d2173bb5 2012-07-17 rsc if(me->old)
247 d2173bb5 2012-07-17 rsc child.old = mkpath(me->old, d[i].name);
248 d2173bb5 2012-07-17 rsc child.elem = d[i].name;
249 d2173bb5 2012-07-17 rsc setnames(&child);
250 d2173bb5 2012-07-17 rsc if(copyfile(&child, &d[i], 1) && rec)
251 d2173bb5 2012-07-17 rsc mktree(&child, rec);
252 d2173bb5 2012-07-17 rsc free(child.new);
253 d2173bb5 2012-07-17 rsc if(child.old)
254 d2173bb5 2012-07-17 rsc free(child.old);
255 d2173bb5 2012-07-17 rsc }
256 d2173bb5 2012-07-17 rsc }
257 d2173bb5 2012-07-17 rsc close(fd);
258 d2173bb5 2012-07-17 rsc }
259 d2173bb5 2012-07-17 rsc
260 d2173bb5 2012-07-17 rsc int
261 d2173bb5 2012-07-17 rsc mkfile(File *f)
262 d2173bb5 2012-07-17 rsc {
263 d2173bb5 2012-07-17 rsc Dir *dir;
264 d2173bb5 2012-07-17 rsc
265 d2173bb5 2012-07-17 rsc if((dir = dirstat(oldfile)) == nil){
266 d2173bb5 2012-07-17 rsc warn("can't stat file %q: %r", oldfile);
267 d2173bb5 2012-07-17 rsc skipdir();
268 d2173bb5 2012-07-17 rsc return 0;
269 d2173bb5 2012-07-17 rsc }
270 d2173bb5 2012-07-17 rsc return copyfile(f, dir, 0);
271 d2173bb5 2012-07-17 rsc }
272 d2173bb5 2012-07-17 rsc
273 d2173bb5 2012-07-17 rsc int
274 d2173bb5 2012-07-17 rsc copyfile(File *f, Dir *d, int permonly)
275 d2173bb5 2012-07-17 rsc {
276 d2173bb5 2012-07-17 rsc ulong mode;
277 d2173bb5 2012-07-17 rsc Dir nd;
278 d2173bb5 2012-07-17 rsc
279 d2173bb5 2012-07-17 rsc if(xflag){
280 d2173bb5 2012-07-17 rsc Bprint(&bout, "%q\t%ld\t%lld\n", f->new, d->mtime, d->length);
281 d2173bb5 2012-07-17 rsc return (d->mode & DMDIR) != 0;
282 d2173bb5 2012-07-17 rsc }
283 d2173bb5 2012-07-17 rsc if(verb && (fskind == Archive || ream))
284 d2173bb5 2012-07-17 rsc fprint(2, "%q\n", f->new);
285 d2173bb5 2012-07-17 rsc d->name = f->elem;
286 d2173bb5 2012-07-17 rsc if(d->type != 'M' && d->type != 'Z'){
287 d2173bb5 2012-07-17 rsc d->uid = "sys";
288 d2173bb5 2012-07-17 rsc d->gid = "sys";
289 d2173bb5 2012-07-17 rsc mode = (d->mode >> 6) & 7;
290 d2173bb5 2012-07-17 rsc d->mode |= mode | (mode << 3);
291 d2173bb5 2012-07-17 rsc }
292 d2173bb5 2012-07-17 rsc if(strcmp(f->uid, "-") != 0)
293 d2173bb5 2012-07-17 rsc d->uid = f->uid;
294 d2173bb5 2012-07-17 rsc if(strcmp(f->gid, "-") != 0)
295 d2173bb5 2012-07-17 rsc d->gid = f->gid;
296 d2173bb5 2012-07-17 rsc if(fskind == Fs && !setuid){
297 d2173bb5 2012-07-17 rsc d->uid = "";
298 d2173bb5 2012-07-17 rsc d->gid = "";
299 d2173bb5 2012-07-17 rsc }
300 d2173bb5 2012-07-17 rsc if(f->mode != ~0){
301 d2173bb5 2012-07-17 rsc if(permonly)
302 d2173bb5 2012-07-17 rsc d->mode = (d->mode & ~0666) | (f->mode & 0666);
303 d2173bb5 2012-07-17 rsc else if((d->mode&DMDIR) != (f->mode&DMDIR))
304 d2173bb5 2012-07-17 rsc warn("inconsistent mode for %q", f->new);
305 d2173bb5 2012-07-17 rsc else
306 d2173bb5 2012-07-17 rsc d->mode = f->mode;
307 d2173bb5 2012-07-17 rsc }
308 d2173bb5 2012-07-17 rsc if(!uptodate(d, newfile)){
309 d2173bb5 2012-07-17 rsc if(verb && (fskind != Archive && ream == 0))
310 d2173bb5 2012-07-17 rsc fprint(2, "%q\n", f->new);
311 d2173bb5 2012-07-17 rsc if(d->mode & DMDIR)
312 d2173bb5 2012-07-17 rsc mkdir(d);
313 d2173bb5 2012-07-17 rsc else
314 d2173bb5 2012-07-17 rsc copy(d);
315 d2173bb5 2012-07-17 rsc }else if(modes){
316 d2173bb5 2012-07-17 rsc nulldir(&nd);
317 d2173bb5 2012-07-17 rsc nd.mode = d->mode;
318 d2173bb5 2012-07-17 rsc nd.gid = d->gid;
319 d2173bb5 2012-07-17 rsc nd.mtime = d->mtime;
320 d2173bb5 2012-07-17 rsc if(verb && (fskind != Archive && ream == 0))
321 d2173bb5 2012-07-17 rsc fprint(2, "%q\n", f->new);
322 d2173bb5 2012-07-17 rsc if(dirwstat(newfile, &nd) < 0)
323 d2173bb5 2012-07-17 rsc warn("can't set modes for %q: %r", f->new);
324 d2173bb5 2012-07-17 rsc nulldir(&nd);
325 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
326 d2173bb5 2012-07-17 rsc dirwstat(newfile, &nd);
327 d2173bb5 2012-07-17 rsc }
328 d2173bb5 2012-07-17 rsc return (d->mode & DMDIR) != 0;
329 d2173bb5 2012-07-17 rsc }
330 d2173bb5 2012-07-17 rsc
331 d2173bb5 2012-07-17 rsc /*
332 d2173bb5 2012-07-17 rsc * check if file to is up to date with
333 d2173bb5 2012-07-17 rsc * respect to the file represented by df
334 d2173bb5 2012-07-17 rsc */
335 d2173bb5 2012-07-17 rsc int
336 d2173bb5 2012-07-17 rsc uptodate(Dir *df, char *to)
337 d2173bb5 2012-07-17 rsc {
338 d2173bb5 2012-07-17 rsc int ret;
339 d2173bb5 2012-07-17 rsc Dir *dt;
340 d2173bb5 2012-07-17 rsc
341 d2173bb5 2012-07-17 rsc if(fskind == Archive || ream || (dt = dirstat(to)) == nil)
342 d2173bb5 2012-07-17 rsc return 0;
343 d2173bb5 2012-07-17 rsc ret = dt->mtime >= df->mtime;
344 d2173bb5 2012-07-17 rsc free(dt);
345 d2173bb5 2012-07-17 rsc return ret;
346 d2173bb5 2012-07-17 rsc }
347 d2173bb5 2012-07-17 rsc
348 d2173bb5 2012-07-17 rsc void
349 d2173bb5 2012-07-17 rsc copy(Dir *d)
350 d2173bb5 2012-07-17 rsc {
351 d2173bb5 2012-07-17 rsc char cptmp[LEN], *p;
352 d2173bb5 2012-07-17 rsc int f, t, n, needwrite, nowarnyet = 1;
353 d2173bb5 2012-07-17 rsc vlong tot, len;
354 d2173bb5 2012-07-17 rsc Dir nd;
355 d2173bb5 2012-07-17 rsc
356 d2173bb5 2012-07-17 rsc f = open(oldfile, OREAD);
357 d2173bb5 2012-07-17 rsc if(f < 0){
358 d2173bb5 2012-07-17 rsc warn("can't open %q: %r", oldfile);
359 d2173bb5 2012-07-17 rsc return;
360 d2173bb5 2012-07-17 rsc }
361 d2173bb5 2012-07-17 rsc t = -1;
362 d2173bb5 2012-07-17 rsc if(fskind == Archive)
363 d2173bb5 2012-07-17 rsc arch(d);
364 d2173bb5 2012-07-17 rsc else{
365 d2173bb5 2012-07-17 rsc strcpy(cptmp, newfile);
366 d2173bb5 2012-07-17 rsc p = utfrrune(cptmp, L'/');
367 d2173bb5 2012-07-17 rsc if(!p)
368 d2173bb5 2012-07-17 rsc error("internal temporary file error");
369 d2173bb5 2012-07-17 rsc strcpy(p+1, "__mkfstmp");
370 d2173bb5 2012-07-17 rsc t = create(cptmp, OWRITE, 0666);
371 d2173bb5 2012-07-17 rsc if(t < 0){
372 d2173bb5 2012-07-17 rsc warn("can't create %q: %r", newfile);
373 d2173bb5 2012-07-17 rsc close(f);
374 d2173bb5 2012-07-17 rsc return;
375 d2173bb5 2012-07-17 rsc }
376 d2173bb5 2012-07-17 rsc }
377 d2173bb5 2012-07-17 rsc
378 d2173bb5 2012-07-17 rsc needwrite = 0;
379 d2173bb5 2012-07-17 rsc for(tot = 0; tot < d->length; tot += n){
380 d2173bb5 2012-07-17 rsc len = d->length - tot;
381 d2173bb5 2012-07-17 rsc /* don't read beyond d->length */
382 d2173bb5 2012-07-17 rsc if (len > buflen)
383 d2173bb5 2012-07-17 rsc len = buflen;
384 d2173bb5 2012-07-17 rsc n = read(f, buf, len);
385 d2173bb5 2012-07-17 rsc if(n <= 0) {
386 d2173bb5 2012-07-17 rsc if(n < 0 && nowarnyet) {
387 d2173bb5 2012-07-17 rsc warn("can't read %q: %r", oldfile);
388 d2173bb5 2012-07-17 rsc nowarnyet = 0;
389 d2173bb5 2012-07-17 rsc }
390 d2173bb5 2012-07-17 rsc /*
391 d2173bb5 2012-07-17 rsc * don't quit: pad to d->length (in pieces) to agree
392 d2173bb5 2012-07-17 rsc * with the length in the header, already emitted.
393 d2173bb5 2012-07-17 rsc */
394 d2173bb5 2012-07-17 rsc memset(buf, 0, len);
395 d2173bb5 2012-07-17 rsc n = len;
396 d2173bb5 2012-07-17 rsc }
397 d2173bb5 2012-07-17 rsc if(fskind == Archive){
398 d2173bb5 2012-07-17 rsc if(Bwrite(&bout, buf, n) != n)
399 d2173bb5 2012-07-17 rsc error("write error: %r");
400 d2173bb5 2012-07-17 rsc }else if(memcmp(buf, zbuf, n) == 0){
401 d2173bb5 2012-07-17 rsc if(seek(t, n, 1) < 0)
402 d2173bb5 2012-07-17 rsc error("can't write zeros to %q: %r", newfile);
403 d2173bb5 2012-07-17 rsc needwrite = 1;
404 d2173bb5 2012-07-17 rsc }else{
405 d2173bb5 2012-07-17 rsc if(write(t, buf, n) < n)
406 d2173bb5 2012-07-17 rsc error("can't write %q: %r", newfile);
407 d2173bb5 2012-07-17 rsc needwrite = 0;
408 d2173bb5 2012-07-17 rsc }
409 d2173bb5 2012-07-17 rsc }
410 d2173bb5 2012-07-17 rsc close(f);
411 d2173bb5 2012-07-17 rsc if(needwrite){
412 d2173bb5 2012-07-17 rsc if(seek(t, -1, 1) < 0 || write(t, zbuf, 1) != 1)
413 d2173bb5 2012-07-17 rsc error("can't write zero at end of %q: %r", newfile);
414 d2173bb5 2012-07-17 rsc }
415 d2173bb5 2012-07-17 rsc if(tot != d->length){
416 d2173bb5 2012-07-17 rsc /* this should no longer happen */
417 d2173bb5 2012-07-17 rsc warn("wrong number of bytes written to %q (was %lld should be %lld)\n",
418 d2173bb5 2012-07-17 rsc newfile, tot, d->length);
419 d2173bb5 2012-07-17 rsc if(fskind == Archive){
420 d2173bb5 2012-07-17 rsc warn("seeking to proper position\n");
421 d2173bb5 2012-07-17 rsc /* does no good if stdout is a pipe */
422 d2173bb5 2012-07-17 rsc Bseek(&bout, d->length - tot, 1);
423 d2173bb5 2012-07-17 rsc }
424 d2173bb5 2012-07-17 rsc }
425 d2173bb5 2012-07-17 rsc if(fskind == Archive)
426 d2173bb5 2012-07-17 rsc return;
427 d2173bb5 2012-07-17 rsc remove(newfile);
428 d2173bb5 2012-07-17 rsc nulldir(&nd);
429 d2173bb5 2012-07-17 rsc nd.mode = d->mode;
430 d2173bb5 2012-07-17 rsc nd.gid = d->gid;
431 d2173bb5 2012-07-17 rsc nd.mtime = d->mtime;
432 d2173bb5 2012-07-17 rsc nd.name = d->name;
433 d2173bb5 2012-07-17 rsc if(dirfwstat(t, &nd) < 0)
434 d2173bb5 2012-07-17 rsc error("can't move tmp file to %q: %r", newfile);
435 d2173bb5 2012-07-17 rsc nulldir(&nd);
436 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
437 d2173bb5 2012-07-17 rsc dirfwstat(t, &nd);
438 d2173bb5 2012-07-17 rsc close(t);
439 d2173bb5 2012-07-17 rsc }
440 d2173bb5 2012-07-17 rsc
441 d2173bb5 2012-07-17 rsc void
442 d2173bb5 2012-07-17 rsc mkdir(Dir *d)
443 d2173bb5 2012-07-17 rsc {
444 d2173bb5 2012-07-17 rsc Dir *d1;
445 d2173bb5 2012-07-17 rsc Dir nd;
446 d2173bb5 2012-07-17 rsc int fd;
447 d2173bb5 2012-07-17 rsc
448 d2173bb5 2012-07-17 rsc if(fskind == Archive){
449 d2173bb5 2012-07-17 rsc arch(d);
450 d2173bb5 2012-07-17 rsc return;
451 d2173bb5 2012-07-17 rsc }
452 d2173bb5 2012-07-17 rsc fd = create(newfile, OREAD, d->mode);
453 d2173bb5 2012-07-17 rsc nulldir(&nd);
454 d2173bb5 2012-07-17 rsc nd.mode = d->mode;
455 d2173bb5 2012-07-17 rsc nd.gid = d->gid;
456 d2173bb5 2012-07-17 rsc nd.mtime = d->mtime;
457 d2173bb5 2012-07-17 rsc if(fd < 0){
458 d2173bb5 2012-07-17 rsc if((d1 = dirstat(newfile)) == nil || !(d1->mode & DMDIR)){
459 d2173bb5 2012-07-17 rsc free(d1);
460 d2173bb5 2012-07-17 rsc error("can't create %q", newfile);
461 d2173bb5 2012-07-17 rsc }
462 d2173bb5 2012-07-17 rsc free(d1);
463 d2173bb5 2012-07-17 rsc if(dirwstat(newfile, &nd) < 0)
464 d2173bb5 2012-07-17 rsc warn("can't set modes for %q: %r", newfile);
465 d2173bb5 2012-07-17 rsc nulldir(&nd);
466 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
467 d2173bb5 2012-07-17 rsc dirwstat(newfile, &nd);
468 d2173bb5 2012-07-17 rsc return;
469 d2173bb5 2012-07-17 rsc }
470 d2173bb5 2012-07-17 rsc if(dirfwstat(fd, &nd) < 0)
471 d2173bb5 2012-07-17 rsc warn("can't set modes for %q: %r", newfile);
472 d2173bb5 2012-07-17 rsc nulldir(&nd);
473 d2173bb5 2012-07-17 rsc nd.uid = d->uid;
474 d2173bb5 2012-07-17 rsc dirfwstat(fd, &nd);
475 d2173bb5 2012-07-17 rsc close(fd);
476 d2173bb5 2012-07-17 rsc }
477 d2173bb5 2012-07-17 rsc
478 d2173bb5 2012-07-17 rsc void
479 d2173bb5 2012-07-17 rsc arch(Dir *d)
480 d2173bb5 2012-07-17 rsc {
481 d2173bb5 2012-07-17 rsc Bprint(&bout, "%q %luo %q %q %lud %lld\n",
482 d2173bb5 2012-07-17 rsc newfile, d->mode, d->uid, d->gid, d->mtime, d->length);
483 d2173bb5 2012-07-17 rsc }
484 d2173bb5 2012-07-17 rsc
485 d2173bb5 2012-07-17 rsc char *
486 d2173bb5 2012-07-17 rsc mkpath(char *prefix, char *elem)
487 d2173bb5 2012-07-17 rsc {
488 d2173bb5 2012-07-17 rsc char *p;
489 d2173bb5 2012-07-17 rsc int n;
490 d2173bb5 2012-07-17 rsc
491 d2173bb5 2012-07-17 rsc n = strlen(prefix) + strlen(elem) + 2;
492 d2173bb5 2012-07-17 rsc p = emalloc(n);
493 d2173bb5 2012-07-17 rsc sprint(p, "%s/%s", prefix, elem);
494 d2173bb5 2012-07-17 rsc return p;
495 d2173bb5 2012-07-17 rsc }
496 d2173bb5 2012-07-17 rsc
497 d2173bb5 2012-07-17 rsc char *
498 d2173bb5 2012-07-17 rsc strdup(char *s)
499 d2173bb5 2012-07-17 rsc {
500 d2173bb5 2012-07-17 rsc char *t;
501 d2173bb5 2012-07-17 rsc
502 d2173bb5 2012-07-17 rsc t = emalloc(strlen(s) + 1);
503 d2173bb5 2012-07-17 rsc return strcpy(t, s);
504 d2173bb5 2012-07-17 rsc }
505 d2173bb5 2012-07-17 rsc
506 d2173bb5 2012-07-17 rsc void
507 d2173bb5 2012-07-17 rsc setnames(File *f)
508 d2173bb5 2012-07-17 rsc {
509 d2173bb5 2012-07-17 rsc sprint(newfile, "%s%s", newroot, f->new);
510 d2173bb5 2012-07-17 rsc if(f->old){
511 d2173bb5 2012-07-17 rsc if(f->old[0] == '/')
512 d2173bb5 2012-07-17 rsc sprint(oldfile, "%s%s", oldroot, f->old);
513 d2173bb5 2012-07-17 rsc else
514 d2173bb5 2012-07-17 rsc strcpy(oldfile, f->old);
515 d2173bb5 2012-07-17 rsc }else
516 d2173bb5 2012-07-17 rsc sprint(oldfile, "%s%s", oldroot, f->new);
517 fa325e9b 2020-01-10 cross if(strlen(newfile) >= sizeof newfile
518 d2173bb5 2012-07-17 rsc || strlen(oldfile) >= sizeof oldfile)
519 d2173bb5 2012-07-17 rsc error("name overfile");
520 d2173bb5 2012-07-17 rsc }
521 d2173bb5 2012-07-17 rsc
522 d2173bb5 2012-07-17 rsc void
523 d2173bb5 2012-07-17 rsc freefile(File *f)
524 d2173bb5 2012-07-17 rsc {
525 d2173bb5 2012-07-17 rsc if(f->old)
526 d2173bb5 2012-07-17 rsc free(f->old);
527 d2173bb5 2012-07-17 rsc if(f->new)
528 d2173bb5 2012-07-17 rsc free(f->new);
529 d2173bb5 2012-07-17 rsc free(f);
530 d2173bb5 2012-07-17 rsc }
531 d2173bb5 2012-07-17 rsc
532 d2173bb5 2012-07-17 rsc /*
533 d2173bb5 2012-07-17 rsc * skip all files in the proto that
534 d2173bb5 2012-07-17 rsc * could be in the current dir
535 d2173bb5 2012-07-17 rsc */
536 d2173bb5 2012-07-17 rsc void
537 d2173bb5 2012-07-17 rsc skipdir(void)
538 d2173bb5 2012-07-17 rsc {
539 d2173bb5 2012-07-17 rsc char *p, c;
540 d2173bb5 2012-07-17 rsc int level;
541 d2173bb5 2012-07-17 rsc
542 d2173bb5 2012-07-17 rsc if(indent < 0 || b == nil) /* b is nil when copying adm/users */
543 d2173bb5 2012-07-17 rsc return;
544 d2173bb5 2012-07-17 rsc level = indent;
545 d2173bb5 2012-07-17 rsc for(;;){
546 d2173bb5 2012-07-17 rsc indent = 0;
547 d2173bb5 2012-07-17 rsc p = Brdline(b, '\n');
548 d2173bb5 2012-07-17 rsc lineno++;
549 d2173bb5 2012-07-17 rsc if(!p){
550 d2173bb5 2012-07-17 rsc indent = -1;
551 d2173bb5 2012-07-17 rsc return;
552 d2173bb5 2012-07-17 rsc }
553 d2173bb5 2012-07-17 rsc while((c = *p++) != '\n')
554 d2173bb5 2012-07-17 rsc if(c == ' ')
555 d2173bb5 2012-07-17 rsc indent++;
556 d2173bb5 2012-07-17 rsc else if(c == '\t')
557 d2173bb5 2012-07-17 rsc indent += 8;
558 d2173bb5 2012-07-17 rsc else
559 d2173bb5 2012-07-17 rsc break;
560 d2173bb5 2012-07-17 rsc if(indent <= level){
561 d2173bb5 2012-07-17 rsc Bseek(b, -Blinelen(b), 1);
562 d2173bb5 2012-07-17 rsc lineno--;
563 d2173bb5 2012-07-17 rsc return;
564 d2173bb5 2012-07-17 rsc }
565 d2173bb5 2012-07-17 rsc }
566 d2173bb5 2012-07-17 rsc }
567 d2173bb5 2012-07-17 rsc
568 d2173bb5 2012-07-17 rsc File*
569 d2173bb5 2012-07-17 rsc getfile(File *old)
570 d2173bb5 2012-07-17 rsc {
571 d2173bb5 2012-07-17 rsc File *f;
572 d2173bb5 2012-07-17 rsc char *elem;
573 d2173bb5 2012-07-17 rsc char *p;
574 d2173bb5 2012-07-17 rsc int c;
575 d2173bb5 2012-07-17 rsc
576 d2173bb5 2012-07-17 rsc if(indent < 0)
577 d2173bb5 2012-07-17 rsc return 0;
578 d2173bb5 2012-07-17 rsc loop:
579 d2173bb5 2012-07-17 rsc indent = 0;
580 d2173bb5 2012-07-17 rsc p = Brdline(b, '\n');
581 d2173bb5 2012-07-17 rsc lineno++;
582 d2173bb5 2012-07-17 rsc if(!p){
583 d2173bb5 2012-07-17 rsc indent = -1;
584 d2173bb5 2012-07-17 rsc return 0;
585 d2173bb5 2012-07-17 rsc }
586 d2173bb5 2012-07-17 rsc while((c = *p++) != '\n')
587 d2173bb5 2012-07-17 rsc if(c == ' ')
588 d2173bb5 2012-07-17 rsc indent++;
589 d2173bb5 2012-07-17 rsc else if(c == '\t')
590 d2173bb5 2012-07-17 rsc indent += 8;
591 d2173bb5 2012-07-17 rsc else
592 d2173bb5 2012-07-17 rsc break;
593 d2173bb5 2012-07-17 rsc if(c == '\n' || c == '#')
594 d2173bb5 2012-07-17 rsc goto loop;
595 d2173bb5 2012-07-17 rsc p--;
596 d2173bb5 2012-07-17 rsc f = emalloc(sizeof *f);
597 d2173bb5 2012-07-17 rsc p = getname(p, &elem);
598 d2173bb5 2012-07-17 rsc if(debug)
599 d2173bb5 2012-07-17 rsc fprint(2, "getfile: %q root %q\n", elem, old->new);
600 d2173bb5 2012-07-17 rsc f->new = mkpath(old->new, elem);
601 d2173bb5 2012-07-17 rsc f->elem = utfrrune(f->new, L'/') + 1;
602 d2173bb5 2012-07-17 rsc p = getmode(p, &f->mode);
603 d2173bb5 2012-07-17 rsc p = getname(p, &f->uid);
604 d2173bb5 2012-07-17 rsc if(!*f->uid)
605 d2173bb5 2012-07-17 rsc f->uid = "-";
606 d2173bb5 2012-07-17 rsc p = getname(p, &f->gid);
607 d2173bb5 2012-07-17 rsc if(!*f->gid)
608 d2173bb5 2012-07-17 rsc f->gid = "-";
609 d2173bb5 2012-07-17 rsc f->old = getpath(p);
610 d2173bb5 2012-07-17 rsc if(f->old && strcmp(f->old, "-") == 0){
611 d2173bb5 2012-07-17 rsc free(f->old);
612 d2173bb5 2012-07-17 rsc f->old = 0;
613 d2173bb5 2012-07-17 rsc }
614 d2173bb5 2012-07-17 rsc setnames(f);
615 d2173bb5 2012-07-17 rsc
616 d2173bb5 2012-07-17 rsc if(debug)
617 d2173bb5 2012-07-17 rsc printfile(f);
618 d2173bb5 2012-07-17 rsc
619 d2173bb5 2012-07-17 rsc return f;
620 d2173bb5 2012-07-17 rsc }
621 d2173bb5 2012-07-17 rsc
622 d2173bb5 2012-07-17 rsc char*
623 d2173bb5 2012-07-17 rsc getpath(char *p)
624 d2173bb5 2012-07-17 rsc {
625 d2173bb5 2012-07-17 rsc char *q, *new;
626 d2173bb5 2012-07-17 rsc int c, n;
627 d2173bb5 2012-07-17 rsc
628 d2173bb5 2012-07-17 rsc while((c = *p) == ' ' || c == '\t')
629 d2173bb5 2012-07-17 rsc p++;
630 d2173bb5 2012-07-17 rsc q = p;
631 d2173bb5 2012-07-17 rsc while((c = *q) != '\n' && c != ' ' && c != '\t')
632 d2173bb5 2012-07-17 rsc q++;
633 d2173bb5 2012-07-17 rsc if(q == p)
634 d2173bb5 2012-07-17 rsc return 0;
635 d2173bb5 2012-07-17 rsc n = q - p;
636 d2173bb5 2012-07-17 rsc new = emalloc(n + 1);
637 d2173bb5 2012-07-17 rsc memcpy(new, p, n);
638 d2173bb5 2012-07-17 rsc new[n] = 0;
639 d2173bb5 2012-07-17 rsc return new;
640 d2173bb5 2012-07-17 rsc }
641 d2173bb5 2012-07-17 rsc
642 d2173bb5 2012-07-17 rsc char*
643 d2173bb5 2012-07-17 rsc getname(char *p, char **buf)
644 d2173bb5 2012-07-17 rsc {
645 d2173bb5 2012-07-17 rsc char *s, *start;
646 d2173bb5 2012-07-17 rsc int c;
647 d2173bb5 2012-07-17 rsc
648 d2173bb5 2012-07-17 rsc while((c = *p) == ' ' || c == '\t')
649 d2173bb5 2012-07-17 rsc p++;
650 d2173bb5 2012-07-17 rsc
651 d2173bb5 2012-07-17 rsc start = p;
652 d2173bb5 2012-07-17 rsc while((c = *p) != '\n' && c != ' ' && c != '\t' && c != '\0')
653 d2173bb5 2012-07-17 rsc p++;
654 d2173bb5 2012-07-17 rsc
655 d2173bb5 2012-07-17 rsc *buf = malloc(p+1-start);
656 d2173bb5 2012-07-17 rsc if(*buf == nil)
657 d2173bb5 2012-07-17 rsc return nil;
658 d2173bb5 2012-07-17 rsc memmove(*buf, start, p-start);
659 d2173bb5 2012-07-17 rsc (*buf)[p-start] = '\0';
660 d2173bb5 2012-07-17 rsc
661 d2173bb5 2012-07-17 rsc if(**buf == '$'){
662 d2173bb5 2012-07-17 rsc s = getenv(*buf+1);
663 d2173bb5 2012-07-17 rsc if(s == 0){
664 d2173bb5 2012-07-17 rsc warn("can't read environment variable %q", *buf+1);
665 d2173bb5 2012-07-17 rsc skipdir();
666 d2173bb5 2012-07-17 rsc free(*buf);
667 d2173bb5 2012-07-17 rsc return nil;
668 d2173bb5 2012-07-17 rsc }
669 d2173bb5 2012-07-17 rsc free(*buf);
670 d2173bb5 2012-07-17 rsc *buf = s;
671 d2173bb5 2012-07-17 rsc }
672 d2173bb5 2012-07-17 rsc return p;
673 d2173bb5 2012-07-17 rsc }
674 d2173bb5 2012-07-17 rsc
675 d2173bb5 2012-07-17 rsc char*
676 d2173bb5 2012-07-17 rsc getmode(char *p, ulong *xmode)
677 d2173bb5 2012-07-17 rsc {
678 d2173bb5 2012-07-17 rsc char *buf, *s;
679 d2173bb5 2012-07-17 rsc ulong m;
680 d2173bb5 2012-07-17 rsc
681 d2173bb5 2012-07-17 rsc *xmode = ~0;
682 d2173bb5 2012-07-17 rsc p = getname(p, &buf);
683 d2173bb5 2012-07-17 rsc if(p == nil)
684 d2173bb5 2012-07-17 rsc return nil;
685 d2173bb5 2012-07-17 rsc
686 d2173bb5 2012-07-17 rsc s = buf;
687 d2173bb5 2012-07-17 rsc if(!*s || strcmp(s, "-") == 0)
688 d2173bb5 2012-07-17 rsc return p;
689 d2173bb5 2012-07-17 rsc m = 0;
690 d2173bb5 2012-07-17 rsc if(*s == 'd'){
691 d2173bb5 2012-07-17 rsc m |= DMDIR;
692 d2173bb5 2012-07-17 rsc s++;
693 d2173bb5 2012-07-17 rsc }
694 d2173bb5 2012-07-17 rsc if(*s == 'a'){
695 d2173bb5 2012-07-17 rsc m |= DMAPPEND;
696 d2173bb5 2012-07-17 rsc s++;
697 d2173bb5 2012-07-17 rsc }
698 d2173bb5 2012-07-17 rsc if(*s == 'l'){
699 d2173bb5 2012-07-17 rsc m |= DMEXCL;
700 d2173bb5 2012-07-17 rsc s++;
701 d2173bb5 2012-07-17 rsc }
702 d2173bb5 2012-07-17 rsc if(s[0] < '0' || s[0] > '7'
703 d2173bb5 2012-07-17 rsc || s[1] < '0' || s[1] > '7'
704 d2173bb5 2012-07-17 rsc || s[2] < '0' || s[2] > '7'
705 d2173bb5 2012-07-17 rsc || s[3]){
706 d2173bb5 2012-07-17 rsc warn("bad mode specification %q", buf);
707 d2173bb5 2012-07-17 rsc free(buf);
708 d2173bb5 2012-07-17 rsc return p;
709 d2173bb5 2012-07-17 rsc }
710 d2173bb5 2012-07-17 rsc *xmode = m | strtoul(s, 0, 8);
711 d2173bb5 2012-07-17 rsc free(buf);
712 d2173bb5 2012-07-17 rsc return p;
713 d2173bb5 2012-07-17 rsc }
714 d2173bb5 2012-07-17 rsc
715 d2173bb5 2012-07-17 rsc void
716 d2173bb5 2012-07-17 rsc setusers(void)
717 d2173bb5 2012-07-17 rsc {
718 d2173bb5 2012-07-17 rsc File file;
719 d2173bb5 2012-07-17 rsc int m;
720 d2173bb5 2012-07-17 rsc
721 d2173bb5 2012-07-17 rsc if(fskind != Kfs)
722 d2173bb5 2012-07-17 rsc return;
723 d2173bb5 2012-07-17 rsc m = modes;
724 d2173bb5 2012-07-17 rsc modes = 1;
725 d2173bb5 2012-07-17 rsc file.uid = "adm";
726 d2173bb5 2012-07-17 rsc file.gid = "adm";
727 d2173bb5 2012-07-17 rsc file.mode = DMDIR|0775;
728 d2173bb5 2012-07-17 rsc file.new = "/adm";
729 d2173bb5 2012-07-17 rsc file.elem = "adm";
730 d2173bb5 2012-07-17 rsc file.old = 0;
731 d2173bb5 2012-07-17 rsc setnames(&file);
732 d2173bb5 2012-07-17 rsc strcpy(oldfile, file.new); /* Don't use root for /adm */
733 d2173bb5 2012-07-17 rsc mkfile(&file);
734 d2173bb5 2012-07-17 rsc file.new = "/adm/users";
735 d2173bb5 2012-07-17 rsc file.old = users;
736 d2173bb5 2012-07-17 rsc file.elem = "users";
737 d2173bb5 2012-07-17 rsc file.mode = 0664;
738 d2173bb5 2012-07-17 rsc setnames(&file);
739 d2173bb5 2012-07-17 rsc if (file.old)
740 d2173bb5 2012-07-17 rsc strcpy(oldfile, file.old); /* Don't use root for /adm/users */
741 d2173bb5 2012-07-17 rsc mkfile(&file);
742 d2173bb5 2012-07-17 rsc kfscmd("user");
743 d2173bb5 2012-07-17 rsc mkfile(&file);
744 d2173bb5 2012-07-17 rsc file.mode = DMDIR|0775;
745 d2173bb5 2012-07-17 rsc file.new = "/adm";
746 d2173bb5 2012-07-17 rsc file.old = "/adm";
747 d2173bb5 2012-07-17 rsc file.elem = "adm";
748 d2173bb5 2012-07-17 rsc setnames(&file);
749 d2173bb5 2012-07-17 rsc strcpy(oldfile, file.old); /* Don't use root for /adm */
750 d2173bb5 2012-07-17 rsc mkfile(&file);
751 d2173bb5 2012-07-17 rsc modes = m;
752 d2173bb5 2012-07-17 rsc }
753 d2173bb5 2012-07-17 rsc
754 d2173bb5 2012-07-17 rsc void
755 d2173bb5 2012-07-17 rsc mountkfs(char *name)
756 d2173bb5 2012-07-17 rsc {
757 d2173bb5 2012-07-17 rsc if(fskind != Kfs)
758 d2173bb5 2012-07-17 rsc return;
759 d2173bb5 2012-07-17 rsc sysfatal("no kfs: use -a or -d");
760 d2173bb5 2012-07-17 rsc }
761 d2173bb5 2012-07-17 rsc
762 d2173bb5 2012-07-17 rsc void
763 d2173bb5 2012-07-17 rsc kfscmd(char *cmd)
764 d2173bb5 2012-07-17 rsc {
765 d2173bb5 2012-07-17 rsc char buf[4*1024];
766 d2173bb5 2012-07-17 rsc int n;
767 d2173bb5 2012-07-17 rsc
768 d2173bb5 2012-07-17 rsc if(fskind != Kfs)
769 d2173bb5 2012-07-17 rsc return;
770 d2173bb5 2012-07-17 rsc if(write(sfd, cmd, strlen(cmd)) != strlen(cmd)){
771 d2173bb5 2012-07-17 rsc fprint(2, "%q: error writing %q: %r", prog, cmd);
772 d2173bb5 2012-07-17 rsc return;
773 d2173bb5 2012-07-17 rsc }
774 d2173bb5 2012-07-17 rsc for(;;){
775 d2173bb5 2012-07-17 rsc n = read(sfd, buf, sizeof buf - 1);
776 d2173bb5 2012-07-17 rsc if(n <= 0)
777 d2173bb5 2012-07-17 rsc return;
778 d2173bb5 2012-07-17 rsc buf[n] = '\0';
779 d2173bb5 2012-07-17 rsc if(strcmp(buf, "done") == 0 || strcmp(buf, "success") == 0)
780 d2173bb5 2012-07-17 rsc return;
781 d2173bb5 2012-07-17 rsc if(strcmp(buf, "unknown command") == 0){
782 d2173bb5 2012-07-17 rsc fprint(2, "%q: command %q not recognized\n", prog, cmd);
783 d2173bb5 2012-07-17 rsc return;
784 d2173bb5 2012-07-17 rsc }
785 d2173bb5 2012-07-17 rsc }
786 d2173bb5 2012-07-17 rsc }
787 d2173bb5 2012-07-17 rsc
788 d2173bb5 2012-07-17 rsc void *
789 d2173bb5 2012-07-17 rsc emalloc(ulong n)
790 d2173bb5 2012-07-17 rsc {
791 d2173bb5 2012-07-17 rsc void *p;
792 d2173bb5 2012-07-17 rsc
793 d2173bb5 2012-07-17 rsc if((p = malloc(n)) == 0)
794 d2173bb5 2012-07-17 rsc error("out of memory");
795 d2173bb5 2012-07-17 rsc return p;
796 d2173bb5 2012-07-17 rsc }
797 d2173bb5 2012-07-17 rsc
798 d2173bb5 2012-07-17 rsc void
799 d2173bb5 2012-07-17 rsc error(char *fmt, ...)
800 d2173bb5 2012-07-17 rsc {
801 d2173bb5 2012-07-17 rsc char buf[1024];
802 d2173bb5 2012-07-17 rsc va_list arg;
803 d2173bb5 2012-07-17 rsc
804 d2173bb5 2012-07-17 rsc sprint(buf, "%q: %q:%d: ", prog, proto, lineno);
805 d2173bb5 2012-07-17 rsc va_start(arg, fmt);
806 d2173bb5 2012-07-17 rsc vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
807 d2173bb5 2012-07-17 rsc va_end(arg);
808 d2173bb5 2012-07-17 rsc fprint(2, "%s\n", buf);
809 d2173bb5 2012-07-17 rsc kfscmd("disallow");
810 d2173bb5 2012-07-17 rsc kfscmd("sync");
811 d2173bb5 2012-07-17 rsc exits(0);
812 d2173bb5 2012-07-17 rsc }
813 d2173bb5 2012-07-17 rsc
814 d2173bb5 2012-07-17 rsc void
815 d2173bb5 2012-07-17 rsc warn(char *fmt, ...)
816 d2173bb5 2012-07-17 rsc {
817 d2173bb5 2012-07-17 rsc char buf[1024];
818 d2173bb5 2012-07-17 rsc va_list arg;
819 d2173bb5 2012-07-17 rsc
820 d2173bb5 2012-07-17 rsc sprint(buf, "%q: %q:%d: ", prog, proto, lineno);
821 d2173bb5 2012-07-17 rsc va_start(arg, fmt);
822 d2173bb5 2012-07-17 rsc vseprint(buf+strlen(buf), buf+sizeof(buf), fmt, arg);
823 d2173bb5 2012-07-17 rsc va_end(arg);
824 d2173bb5 2012-07-17 rsc fprint(2, "%s\n", buf);
825 d2173bb5 2012-07-17 rsc }
826 d2173bb5 2012-07-17 rsc
827 d2173bb5 2012-07-17 rsc void
828 d2173bb5 2012-07-17 rsc printfile(File *f)
829 d2173bb5 2012-07-17 rsc {
830 d2173bb5 2012-07-17 rsc if(f->old)
831 d2173bb5 2012-07-17 rsc fprint(2, "%q from %q %q %q %lo\n", f->new, f->old, f->uid, f->gid, f->mode);
832 d2173bb5 2012-07-17 rsc else
833 d2173bb5 2012-07-17 rsc fprint(2, "%q %q %q %lo\n", f->new, f->uid, f->gid, f->mode);
834 d2173bb5 2012-07-17 rsc }
835 d2173bb5 2012-07-17 rsc
836 d2173bb5 2012-07-17 rsc void
837 d2173bb5 2012-07-17 rsc usage(void)
838 d2173bb5 2012-07-17 rsc {
839 d2173bb5 2012-07-17 rsc fprint(2, "usage: %q [-aprvx] [-d root] [-n name] [-s source] [-u users] [-z n] proto ...\n", prog);
840 d2173bb5 2012-07-17 rsc exits("usage");
841 d2173bb5 2012-07-17 rsc }