xref: /inferno-os/appl/cmd/install/create.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Create;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "sys.m";
4*37da2899SCharles.Forsyth	sys: Sys;
5*37da2899SCharles.Forsyth	Dir, sprint, fprint: import sys;
6*37da2899SCharles.Forsythinclude "draw.m";
7*37da2899SCharles.Forsythinclude "bufio.m";
8*37da2899SCharles.Forsyth	bufio: Bufio;
9*37da2899SCharles.Forsyth	Iobuf: import bufio;
10*37da2899SCharles.Forsythinclude "string.m";
11*37da2899SCharles.Forsyth	str: String;
12*37da2899SCharles.Forsythinclude "arg.m";
13*37da2899SCharles.Forsyth	arg: Arg;
14*37da2899SCharles.Forsythinclude "daytime.m";
15*37da2899SCharles.Forsythinclude "keyring.m";
16*37da2899SCharles.Forsyth	keyring : Keyring;
17*37da2899SCharles.Forsythinclude "sh.m";
18*37da2899SCharles.Forsythinclude "wrap.m";
19*37da2899SCharles.Forsyth	wrap : Wrap;
20*37da2899SCharles.Forsythinclude "arch.m";
21*37da2899SCharles.Forsyth	arch : Arch;
22*37da2899SCharles.Forsythinclude "proto.m";
23*37da2899SCharles.Forsyth	proto : Proto;
24*37da2899SCharles.Forsythinclude "protocaller.m";
25*37da2899SCharles.Forsyth	protocaller : Protocaller;
26*37da2899SCharles.Forsyth
27*37da2899SCharles.ForsythWARN, ERROR, FATAL : import Protocaller;
28*37da2899SCharles.Forsyth
29*37da2899SCharles.ForsythCreate: module{
30*37da2899SCharles.Forsyth	init:	fn(nil: ref Draw->Context, nil: list of string);
31*37da2899SCharles.Forsyth	protofile: fn(new : string, old : string, d : ref Sys->Dir);
32*37da2899SCharles.Forsyth	protoerr: fn(lev : int, line : int, err : string);
33*37da2899SCharles.Forsyth};
34*37da2899SCharles.Forsyth
35*37da2899SCharles.Forsythbout: ref Iobuf;			# stdout when writing archive
36*37da2899SCharles.Forsythprotof: string;
37*37da2899SCharles.Forsythnotesf: string;
38*37da2899SCharles.Forsytholdroot: string;
39*37da2899SCharles.Forsythbuf: array of byte;
40*37da2899SCharles.Forsythbuflen := 1024-8;
41*37da2899SCharles.Forsythverb: int;
42*37da2899SCharles.Forsythxflag: int;
43*37da2899SCharles.Forsythstderr: ref Sys->FD;
44*37da2899SCharles.Forsythuid, gid : string;
45*37da2899SCharles.Forsythdesc : string;
46*37da2899SCharles.Forsythpass : int;
47*37da2899SCharles.Forsythupdate : int;
48*37da2899SCharles.Forsythmd5s : ref Keyring->DigestState;
49*37da2899SCharles.Forsythw : ref Wrap->Wrapped;
50*37da2899SCharles.Forsythroot := "/";
51*37da2899SCharles.Forsythprefix, notprefix: list of string;
52*37da2899SCharles.Forsythonlist: list of (string, string);	# NEW
53*37da2899SCharles.Forsythremfile: string;
54*37da2899SCharles.Forsyth
55*37da2899SCharles.Forsythn2o(n: string): string
56*37da2899SCharles.Forsyth{
57*37da2899SCharles.Forsyth	for(onl := onlist; onl != nil; onl = tl onl)
58*37da2899SCharles.Forsyth		if((hd onl).t1 == n)
59*37da2899SCharles.Forsyth			return (hd onl).t0;
60*37da2899SCharles.Forsyth	return n;
61*37da2899SCharles.Forsyth}
62*37da2899SCharles.Forsyth
63*37da2899SCharles.Forsythinit(nil: ref Draw->Context, args: list of string)
64*37da2899SCharles.Forsyth{
65*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
66*37da2899SCharles.Forsyth	bufio = load Bufio Bufio->PATH;
67*37da2899SCharles.Forsyth	str = load String String->PATH;
68*37da2899SCharles.Forsyth	arg = load Arg Arg->PATH;
69*37da2899SCharles.Forsyth	wrap = load Wrap Wrap->PATH;
70*37da2899SCharles.Forsyth	wrap->init(bufio);
71*37da2899SCharles.Forsyth	arch = load Arch Arch->PATH;
72*37da2899SCharles.Forsyth	arch->init(bufio);
73*37da2899SCharles.Forsyth	daytime := load Daytime Daytime->PATH;
74*37da2899SCharles.Forsyth	now := daytime->now();
75*37da2899SCharles.Forsyth	# {
76*37da2899SCharles.Forsyth	#	for(i := 0; i < 21; i++){
77*37da2899SCharles.Forsyth	#		n := now+(i-9)*100000000;
78*37da2899SCharles.Forsyth	#		sys->print("%d	->	%s\n", n, wrap->now2string(n));
79*37da2899SCharles.Forsyth	#		if(wrap->string2now(wrap->now2string(n)) != n)
80*37da2899SCharles.Forsyth	#			sys->print("%d wrong\n", n);
81*37da2899SCharles.Forsyth	#	}
82*37da2899SCharles.Forsyth	# }
83*37da2899SCharles.Forsyth	daytime = nil;
84*37da2899SCharles.Forsyth	proto = load Proto Proto->PATH;
85*37da2899SCharles.Forsyth	protocaller = load Protocaller "$self";
86*37da2899SCharles.Forsyth
87*37da2899SCharles.Forsyth	sys->pctl(Sys->NEWPGRP|Sys->FORKNS|Sys->FORKFD, nil);
88*37da2899SCharles.Forsyth	stderr = sys->fildes(2);
89*37da2899SCharles.Forsyth	if(arg == nil)
90*37da2899SCharles.Forsyth		error(sys->sprint("can't load %s: %r", Arg->PATH));
91*37da2899SCharles.Forsyth	name := "";
92*37da2899SCharles.Forsyth	desc = "inferno";
93*37da2899SCharles.Forsyth	tostdout := 0;
94*37da2899SCharles.Forsyth	not := 0;
95*37da2899SCharles.Forsyth	arg->init(args);
96*37da2899SCharles.Forsyth	while((c := arg->opt()) != 0)
97*37da2899SCharles.Forsyth		case c {
98*37da2899SCharles.Forsyth		'n' =>
99*37da2899SCharles.Forsyth			not = 1;
100*37da2899SCharles.Forsyth		'o' =>
101*37da2899SCharles.Forsyth			tostdout = 1;
102*37da2899SCharles.Forsyth		'p' =>
103*37da2899SCharles.Forsyth			protof = reqarg("proto file (-p)");
104*37da2899SCharles.Forsyth		'r' =>
105*37da2899SCharles.Forsyth			root = reqarg("root directory (-r)");
106*37da2899SCharles.Forsyth		's' =>
107*37da2899SCharles.Forsyth			oldroot = reqarg("source directory (-d)");
108*37da2899SCharles.Forsyth		'u' =>
109*37da2899SCharles.Forsyth			update = 1;
110*37da2899SCharles.Forsyth		'v' =>
111*37da2899SCharles.Forsyth			verb = 1;
112*37da2899SCharles.Forsyth		'x' =>
113*37da2899SCharles.Forsyth			xflag = 1;
114*37da2899SCharles.Forsyth		'N' =>
115*37da2899SCharles.Forsyth			uid = reqarg("user name (-U)");
116*37da2899SCharles.Forsyth		'G' =>
117*37da2899SCharles.Forsyth			gid = reqarg("group name (-G)");
118*37da2899SCharles.Forsyth		'd' or 'D' =>
119*37da2899SCharles.Forsyth			desc = reqarg("product description (-D)");
120*37da2899SCharles.Forsyth		't' =>
121*37da2899SCharles.Forsyth			rt := reqarg("package time (-t)");
122*37da2899SCharles.Forsyth			now = int rt;
123*37da2899SCharles.Forsyth		'i' =>
124*37da2899SCharles.Forsyth			notesf = reqarg("file (-i)");
125*37da2899SCharles.Forsyth		'R' =>
126*37da2899SCharles.Forsyth			remfile = reqarg("remove file (-R)");
127*37da2899SCharles.Forsyth		'P' =>
128*37da2899SCharles.Forsyth			arch->addperms(0);
129*37da2899SCharles.Forsyth		* =>
130*37da2899SCharles.Forsyth			usage();
131*37da2899SCharles.Forsyth		}
132*37da2899SCharles.Forsyth
133*37da2899SCharles.Forsyth	args = arg->argv();
134*37da2899SCharles.Forsyth	if(args == nil)
135*37da2899SCharles.Forsyth		usage();
136*37da2899SCharles.Forsyth	if (tostdout || xflag) {
137*37da2899SCharles.Forsyth		bout = bufio->fopen(sys->fildes(1), Sys->OWRITE);
138*37da2899SCharles.Forsyth		if(bout == nil)
139*37da2899SCharles.Forsyth			error(sys->sprint("can't open standard output for archive: %r"));
140*37da2899SCharles.Forsyth	}
141*37da2899SCharles.Forsyth	else {
142*37da2899SCharles.Forsyth		# ar := sys->sprint("%ud", now);
143*37da2899SCharles.Forsyth		ar := wrap->now2string(now, 0);
144*37da2899SCharles.Forsyth		bout = bufio->create(ar, Sys->OWRITE, 8r664);
145*37da2899SCharles.Forsyth		if(bout == nil)
146*37da2899SCharles.Forsyth			error(sys->sprint("can't create %s for archive: %r", ar));
147*37da2899SCharles.Forsyth		sys->print("archiving package %s to %s\n", hd args, ar);
148*37da2899SCharles.Forsyth	}
149*37da2899SCharles.Forsyth	buf = array [buflen] of byte;
150*37da2899SCharles.Forsyth	name = hd args;
151*37da2899SCharles.Forsyth	if(update){
152*37da2899SCharles.Forsyth		if(not)
153*37da2899SCharles.Forsyth			notprefix = tl args;
154*37da2899SCharles.Forsyth		else
155*37da2899SCharles.Forsyth			prefix = tl args;
156*37da2899SCharles.Forsyth	}
157*37da2899SCharles.Forsyth	else if (tl args != nil)
158*37da2899SCharles.Forsyth		fatal("only one name allowed");
159*37da2899SCharles.Forsyth	if (!xflag)
160*37da2899SCharles.Forsyth		digest := wrapinit(name, now);
161*37da2899SCharles.Forsyth	fprint(stderr, "processing %s\n", protof);
162*37da2899SCharles.Forsyth	proto->rdproto(protof, oldroot, protocaller);
163*37da2899SCharles.Forsyth	if (!xflag)
164*37da2899SCharles.Forsyth		wrapend(digest);
165*37da2899SCharles.Forsyth	if (!xflag)
166*37da2899SCharles.Forsyth		fprint(stderr, "file system made\n");
167*37da2899SCharles.Forsyth	arch->putend(bout);
168*37da2899SCharles.Forsyth	exits();
169*37da2899SCharles.Forsyth}
170*37da2899SCharles.Forsyth
171*37da2899SCharles.Forsythprotofile(new : string, old : string, d : ref Sys->Dir)
172*37da2899SCharles.Forsyth{
173*37da2899SCharles.Forsyth	if(xflag && bout != nil){
174*37da2899SCharles.Forsyth		bout.puts(sys->sprint("%s\t%d\t%bd\n", new, d.mtime, d.length));
175*37da2899SCharles.Forsyth		return;
176*37da2899SCharles.Forsyth	}
177*37da2899SCharles.Forsyth	d.uid = uid;
178*37da2899SCharles.Forsyth	d.gid = gid;
179*37da2899SCharles.Forsyth	if (!(d.mode & Sys->DMDIR)) {
180*37da2899SCharles.Forsyth		# if(verb)
181*37da2899SCharles.Forsyth		#	fprint(stderr, "%s\n", new);
182*37da2899SCharles.Forsyth		f := sys->open(old, Sys->OREAD);
183*37da2899SCharles.Forsyth		if(f == nil){
184*37da2899SCharles.Forsyth			warn(sys->sprint("can't open %s: %r", old));
185*37da2899SCharles.Forsyth			return;
186*37da2899SCharles.Forsyth		}
187*37da2899SCharles.Forsyth	}
188*37da2899SCharles.Forsyth	mkarch(new, old, d);
189*37da2899SCharles.Forsyth}
190*37da2899SCharles.Forsyth
191*37da2899SCharles.Forsythprotoerr(lev : int, line : int, err : string)
192*37da2899SCharles.Forsyth{
193*37da2899SCharles.Forsyth	s := "line " + string line + " : " + err;
194*37da2899SCharles.Forsyth	case lev {
195*37da2899SCharles.Forsyth		WARN => warn(s);
196*37da2899SCharles.Forsyth		ERROR => error(s);
197*37da2899SCharles.Forsyth		FATAL => fatal(s);
198*37da2899SCharles.Forsyth	}
199*37da2899SCharles.Forsyth}
200*37da2899SCharles.Forsyth
201*37da2899SCharles.Forsythquit()
202*37da2899SCharles.Forsyth{
203*37da2899SCharles.Forsyth	if(bout != nil)
204*37da2899SCharles.Forsyth		bout.flush();
205*37da2899SCharles.Forsyth	exits();
206*37da2899SCharles.Forsyth}
207*37da2899SCharles.Forsyth
208*37da2899SCharles.Forsythreqarg(what: string): string
209*37da2899SCharles.Forsyth{
210*37da2899SCharles.Forsyth	if((o := arg->arg()) == nil){
211*37da2899SCharles.Forsyth		sys->fprint(stderr, "missing %s\n", what);
212*37da2899SCharles.Forsyth		exits();
213*37da2899SCharles.Forsyth	}
214*37da2899SCharles.Forsyth	return o;
215*37da2899SCharles.Forsyth}
216*37da2899SCharles.Forsyth
217*37da2899SCharles.Forsythputhdr(f : string, d: ref Dir)
218*37da2899SCharles.Forsyth{
219*37da2899SCharles.Forsyth	if (d.mode & Sys->DMDIR)
220*37da2899SCharles.Forsyth		d.length = big 0;
221*37da2899SCharles.Forsyth	arch->puthdr(bout, f, d);
222*37da2899SCharles.Forsyth}
223*37da2899SCharles.Forsyth
224*37da2899SCharles.Forsytherror(s: string)
225*37da2899SCharles.Forsyth{
226*37da2899SCharles.Forsyth	fprint(stderr, "%s: %s\n", protof, s);
227*37da2899SCharles.Forsyth	quit();
228*37da2899SCharles.Forsyth}
229*37da2899SCharles.Forsyth
230*37da2899SCharles.Forsythfatal(s: string)
231*37da2899SCharles.Forsyth{
232*37da2899SCharles.Forsyth	fprint(stderr, "fatal: %s\n", s);
233*37da2899SCharles.Forsyth	exits();
234*37da2899SCharles.Forsyth}
235*37da2899SCharles.Forsyth
236*37da2899SCharles.Forsythwarn(s: string)
237*37da2899SCharles.Forsyth{
238*37da2899SCharles.Forsyth	fprint(stderr, "%s: %s\n", protof, s);
239*37da2899SCharles.Forsyth}
240*37da2899SCharles.Forsyth
241*37da2899SCharles.Forsythusage()
242*37da2899SCharles.Forsyth{
243*37da2899SCharles.Forsyth	fprint(stderr, "usage: install/create [-ovx] [-N uid] [-G gid] [-r root] [-d desc] [-s src-fs] [-p proto] name\n");
244*37da2899SCharles.Forsyth	fprint(stderr, "or install/create -u [-ovx] [-N uid] [-G gid] [-r root] [-d desc] [-s src-fs] [-p proto] old-package [prefix ...]\n");
245*37da2899SCharles.Forsyth	exits();
246*37da2899SCharles.Forsyth}
247*37da2899SCharles.Forsyth
248*37da2899SCharles.Forsythwrapinit(name : string, t : int) : array of byte
249*37da2899SCharles.Forsyth{
250*37da2899SCharles.Forsyth	rmfile : string;
251*37da2899SCharles.Forsyth	rmfd: ref Sys->FD;
252*37da2899SCharles.Forsyth
253*37da2899SCharles.Forsyth	if (uid == nil)
254*37da2899SCharles.Forsyth		uid = "inferno";
255*37da2899SCharles.Forsyth	if (gid == nil)
256*37da2899SCharles.Forsyth		gid = "inferno";
257*37da2899SCharles.Forsyth	if (update) {
258*37da2899SCharles.Forsyth		w = wrap->openwraphdr(name, root, nil, 0);
259*37da2899SCharles.Forsyth		if (w == nil)
260*37da2899SCharles.Forsyth			fatal("no such package found");
261*37da2899SCharles.Forsyth		# ignore any updates - NEW commented out
262*37da2899SCharles.Forsyth		# while (w.nu > 0 && w.u[w.nu-1].typ == wrap->UPD)
263*37da2899SCharles.Forsyth		#	w.nu--;
264*37da2899SCharles.Forsyth
265*37da2899SCharles.Forsyth		# w.nu = 1;	NEW commented out
266*37da2899SCharles.Forsyth		if (protof == nil)
267*37da2899SCharles.Forsyth			protof = w.u[0].dir + "/proto";
268*37da2899SCharles.Forsyth		name = w.name;
269*37da2899SCharles.Forsyth	}
270*37da2899SCharles.Forsyth	else {
271*37da2899SCharles.Forsyth		if (protof == nil)
272*37da2899SCharles.Forsyth			fatal("proto file missing");
273*37da2899SCharles.Forsyth	}
274*37da2899SCharles.Forsyth	(md5file, md5fd) := opentemp("wrap.md5", t);
275*37da2899SCharles.Forsyth	if (md5fd == nil)
276*37da2899SCharles.Forsyth		fatal(sys->sprint("cannot create %s", md5file));
277*37da2899SCharles.Forsyth	keyring = load Keyring Keyring->PATH;
278*37da2899SCharles.Forsyth	md5s = keyring->md5(nil, 0, nil, nil);
279*37da2899SCharles.Forsyth	md5b := bufio->fopen(md5fd, Bufio->OWRITE);
280*37da2899SCharles.Forsyth	if (md5b == nil)
281*37da2899SCharles.Forsyth		fatal(sys->sprint("cannot open %s", md5file));
282*37da2899SCharles.Forsyth	fprint(stderr, "wrap pass %s\n", protof);
283*37da2899SCharles.Forsyth	obout := bout;
284*37da2899SCharles.Forsyth	bout = md5b;
285*37da2899SCharles.Forsyth	pass = 0;
286*37da2899SCharles.Forsyth	proto->rdproto(protof, oldroot, protocaller);
287*37da2899SCharles.Forsyth	bout.flush();
288*37da2899SCharles.Forsyth	bout = md5b = nil;
289*37da2899SCharles.Forsyth	digest := array[keyring->MD5dlen] of { * => byte 0 };
290*37da2899SCharles.Forsyth	keyring->md5(nil, 0, digest, md5s);
291*37da2899SCharles.Forsyth	md5s = nil;
292*37da2899SCharles.Forsyth	(md5sort, md5sfd) := opentemp("wrap.md5s", t);
293*37da2899SCharles.Forsyth	if (md5sfd == nil)
294*37da2899SCharles.Forsyth		fatal(sys->sprint("cannot create %s", md5sort));
295*37da2899SCharles.Forsyth	endc := chan of int;
296*37da2899SCharles.Forsyth	md5fd = nil;	# close md5file
297*37da2899SCharles.Forsyth	spawn fsort(md5sfd, md5file, endc);
298*37da2899SCharles.Forsyth	md5sfd = nil;
299*37da2899SCharles.Forsyth	res := <- endc;
300*37da2899SCharles.Forsyth	if (res < 0)
301*37da2899SCharles.Forsyth		fatal("sort failed");
302*37da2899SCharles.Forsyth	if (update) {
303*37da2899SCharles.Forsyth		(rmfile, rmfd) = opentemp("wrap.rm", t);
304*37da2899SCharles.Forsyth		if (rmfd == nil)
305*37da2899SCharles.Forsyth			fatal(sys->sprint("cannot create %s", rmfile));
306*37da2899SCharles.Forsyth		rmed: list of string;
307*37da2899SCharles.Forsyth		for(i := w.nu-1; i >= 0; i--){	# NEW does loop
308*37da2899SCharles.Forsyth			w.u[i].bmd5.seek(big 0, Bufio->SEEKSTART);
309*37da2899SCharles.Forsyth			while ((p := w.u[i].bmd5.gets('\n')) != nil) {
310*37da2899SCharles.Forsyth				if(prefix != nil && !wrap->match(p, prefix))
311*37da2899SCharles.Forsyth					continue;
312*37da2899SCharles.Forsyth				if(notprefix != nil && !wrap->notmatch(p, notprefix))
313*37da2899SCharles.Forsyth					continue;
314*37da2899SCharles.Forsyth				(q, nil) := str->splitl(p, " ");
315*37da2899SCharles.Forsyth				q = pathcat(root, q);
316*37da2899SCharles.Forsyth				(ok, nil) := sys->stat(q);
317*37da2899SCharles.Forsyth				if(ok < 0)
318*37da2899SCharles.Forsyth					(ok, nil) = sys->stat(n2o(q));
319*37da2899SCharles.Forsyth				if (len q >= 7 && q[len q - 7:] == "emu.new")	# quick hack for now
320*37da2899SCharles.Forsyth					continue;
321*37da2899SCharles.Forsyth				if (ok < 0){
322*37da2899SCharles.Forsyth					for(r := rmed; r != nil; r = tl r)	# NEW to avoid duplication
323*37da2899SCharles.Forsyth						if(hd r == q)
324*37da2899SCharles.Forsyth							break;
325*37da2899SCharles.Forsyth					if(r == nil){
326*37da2899SCharles.Forsyth						# sys->fprint(rmfd, "%s\n", q);
327*37da2899SCharles.Forsyth						rmed = q :: rmed;
328*37da2899SCharles.Forsyth					}
329*37da2899SCharles.Forsyth				}
330*37da2899SCharles.Forsyth			}
331*37da2899SCharles.Forsyth		}
332*37da2899SCharles.Forsyth		for(r := rmed; r != nil; r = tl r)
333*37da2899SCharles.Forsyth			sys->fprint(rmfd, "%s\n", hd r);
334*37da2899SCharles.Forsyth		if(remfile != nil){
335*37da2899SCharles.Forsyth			rfd := sys->open(remfile, Sys->OREAD);
336*37da2899SCharles.Forsyth			rbuf := array[128] of byte;
337*37da2899SCharles.Forsyth			for(;;){
338*37da2899SCharles.Forsyth				n := sys->read(rfd, rbuf, 128);
339*37da2899SCharles.Forsyth				if(n <= 0)
340*37da2899SCharles.Forsyth					break;
341*37da2899SCharles.Forsyth				sys->write(rmfd, rbuf, n);
342*37da2899SCharles.Forsyth			}
343*37da2899SCharles.Forsyth		}
344*37da2899SCharles.Forsyth		rmfd = nil;
345*37da2899SCharles.Forsyth		rmed = nil;
346*37da2899SCharles.Forsyth	}
347*37da2899SCharles.Forsyth	bout = obout;
348*37da2899SCharles.Forsyth	if (update)
349*37da2899SCharles.Forsyth		wrap->putwrap(bout, name, t, desc, w.tfull, prefix == nil && notprefix == nil, uid, gid);
350*37da2899SCharles.Forsyth	else
351*37da2899SCharles.Forsyth		wrap->putwrap(bout, name, t, desc, 0, 1, uid, gid);
352*37da2899SCharles.Forsyth	wrap->putwrapfile(bout, name, t, "proto", protof, uid, gid);
353*37da2899SCharles.Forsyth	wrap->putwrapfile(bout, name, t, "md5sum", md5sort, uid, gid);
354*37da2899SCharles.Forsyth	if (update)
355*37da2899SCharles.Forsyth		wrap->putwrapfile(bout, name, t, "remove", rmfile, uid, gid);
356*37da2899SCharles.Forsyth	if(notesf != nil)
357*37da2899SCharles.Forsyth		wrap->putwrapfile(bout, name, t, "notes", notesf, uid, gid);
358*37da2899SCharles.Forsyth	md5s = keyring->md5(nil, 0, nil, nil);
359*37da2899SCharles.Forsyth	pass = 1;
360*37da2899SCharles.Forsyth	return digest;
361*37da2899SCharles.Forsyth}
362*37da2899SCharles.Forsyth
363*37da2899SCharles.Forsythwrapend(digest : array of byte)
364*37da2899SCharles.Forsyth{
365*37da2899SCharles.Forsyth	digest0 := array[keyring->MD5dlen] of { * => byte 0 };
366*37da2899SCharles.Forsyth	keyring->md5(nil, 0, digest0, md5s);
367*37da2899SCharles.Forsyth	md5s = nil;
368*37da2899SCharles.Forsyth	if (wrap->memcmp(digest, digest0, keyring->MD5dlen) != 0)
369*37da2899SCharles.Forsyth		warn(sys->sprint("files changed underfoot %s %s", wrap->md5conv(digest), wrap->md5conv(digest0)));
370*37da2899SCharles.Forsyth}
371*37da2899SCharles.Forsyth
372*37da2899SCharles.Forsythmkarch(new : string, old : string, d : ref Dir)
373*37da2899SCharles.Forsyth{
374*37da2899SCharles.Forsyth	if(pass == 0 && old != new)
375*37da2899SCharles.Forsyth		onlist = (old, new) :: onlist;
376*37da2899SCharles.Forsyth	if(prefix != nil && !wrap->match(new, prefix))
377*37da2899SCharles.Forsyth		return;
378*37da2899SCharles.Forsyth	if(notprefix != nil && !wrap->notmatch(new, notprefix))
379*37da2899SCharles.Forsyth		return;
380*37da2899SCharles.Forsyth	digest := array[keyring->MD5dlen] of { * => byte 0 };
381*37da2899SCharles.Forsyth	wrap->md5file(old, digest);
382*37da2899SCharles.Forsyth	(ok, nil) := wrap->getfileinfo(w, new, digest, nil, nil);
383*37da2899SCharles.Forsyth	if (ok >= 0)
384*37da2899SCharles.Forsyth		return;
385*37da2899SCharles.Forsyth	n := array of byte new;
386*37da2899SCharles.Forsyth	keyring->md5(n, len n, nil, md5s);
387*37da2899SCharles.Forsyth	if (pass == 0) {
388*37da2899SCharles.Forsyth		bout.puts(sys->sprint("%s %s\n", new, wrap->md5conv(digest)));
389*37da2899SCharles.Forsyth		return;
390*37da2899SCharles.Forsyth	}
391*37da2899SCharles.Forsyth	if(verb)
392*37da2899SCharles.Forsyth		fprint(stderr, "%s\n", new);
393*37da2899SCharles.Forsyth	puthdr(new, d);
394*37da2899SCharles.Forsyth	if(!(d.mode & Sys->DMDIR)) {
395*37da2899SCharles.Forsyth		err := arch->putfile(bout, old, int d.length);
396*37da2899SCharles.Forsyth		if (err != nil)
397*37da2899SCharles.Forsyth			warn(err);
398*37da2899SCharles.Forsyth	}
399*37da2899SCharles.Forsyth}
400*37da2899SCharles.Forsyth
401*37da2899SCharles.Forsythfsort(fd : ref Sys->FD, file : string, c : chan of int)
402*37da2899SCharles.Forsyth{
403*37da2899SCharles.Forsyth	sys->pctl(Sys->FORKFD, nil);
404*37da2899SCharles.Forsyth	sys->dup(fd.fd, 1);
405*37da2899SCharles.Forsyth	cmd := "/dis/sort.dis";
406*37da2899SCharles.Forsyth	m := load Command cmd;
407*37da2899SCharles.Forsyth	if(m == nil) {
408*37da2899SCharles.Forsyth		c <-= -1;
409*37da2899SCharles.Forsyth		return;
410*37da2899SCharles.Forsyth	}
411*37da2899SCharles.Forsyth	m->init(nil, cmd :: file :: nil);
412*37da2899SCharles.Forsyth	c <-= 0;
413*37da2899SCharles.Forsyth}
414*37da2899SCharles.Forsyth
415*37da2899SCharles.Forsythtmpfiles: list of string;
416*37da2899SCharles.Forsyth
417*37da2899SCharles.Forsythopentemp(prefix: string, t: int): (string, ref Sys->FD)
418*37da2899SCharles.Forsyth{
419*37da2899SCharles.Forsyth	name := sys->sprint("/tmp/%s.%ud.%d", prefix, t, sys->pctl(0, nil));
420*37da2899SCharles.Forsyth	fd := sys->create(name, Sys->ORDWR, 8r666);
421*37da2899SCharles.Forsyth	# fd := sys->create(name, Sys->ORDWR | Sys->ORCLOSE, 8r666); not on Nt
422*37da2899SCharles.Forsyth	tmpfiles = name :: tmpfiles;
423*37da2899SCharles.Forsyth	return (name, fd);
424*37da2899SCharles.Forsyth}
425*37da2899SCharles.Forsyth
426*37da2899SCharles.Forsythexits()
427*37da2899SCharles.Forsyth{
428*37da2899SCharles.Forsyth	wrap->end();
429*37da2899SCharles.Forsyth	for( ; tmpfiles != nil; tmpfiles = tl tmpfiles)
430*37da2899SCharles.Forsyth		sys->remove(hd tmpfiles);
431*37da2899SCharles.Forsyth	exit;
432*37da2899SCharles.Forsyth}
433*37da2899SCharles.Forsyth
434*37da2899SCharles.Forsythpathcat(s : string, t : string) : string
435*37da2899SCharles.Forsyth{
436*37da2899SCharles.Forsyth	if (s == nil) return t;
437*37da2899SCharles.Forsyth	if (t == nil) return s;
438*37da2899SCharles.Forsyth	slashs := s[len s - 1] == '/';
439*37da2899SCharles.Forsyth	slasht := t[0] == '/';
440*37da2899SCharles.Forsyth	if (slashs && slasht)
441*37da2899SCharles.Forsyth		return s + t[1:];
442*37da2899SCharles.Forsyth	if (!slashs && !slasht)
443*37da2899SCharles.Forsyth		return s + "/" + t;
444*37da2899SCharles.Forsyth	return s + t;
445*37da2899SCharles.Forsyth}
446