xref: /inferno-os/appl/cmd/touch.b (revision 961f7d6c4c59cea370b706e4643853ab19193ffe)
1implement Touch;
2
3include "sys.m";
4	sys: Sys;
5
6include "draw.m";
7
8include "daytime.m";
9	daytime: Daytime;
10
11include "arg.m";
12
13stderr: ref Sys->FD;
14
15Touch: module
16{
17	init: fn(ctxt: ref Draw->Context, argl: list of string);
18};
19
20init(nil: ref Draw->Context, args: list of string)
21{
22	sys = load Sys Sys->PATH;
23	stderr = sys->fildes(2);
24	force := 1;
25	status := 0;
26	daytime = load Daytime Daytime->PATH;
27	if(daytime == nil)
28		cantload(Daytime->PATH);
29	arg := load Arg Arg->PATH;
30	if(arg == nil)
31		cantload(Arg->PATH);
32	arg->init(args);
33	arg->setusage("touch [-c] [-t time] file ...");
34	now := daytime->now();
35	while((c := arg->opt()) != 0)
36		case c {
37		't' =>		now = int arg->earg();
38		'c' =>	force = 0;
39		* =>	arg->usage();
40		}
41	args = arg->argv();
42	if(args == nil)
43		arg->usage();
44	arg = nil;
45	for(; args != nil; args = tl args)
46		status += touch(force, hd args, now);
47	if(status)
48		raise "fail:touch";
49}
50
51cantload(s: string)
52{
53	sys->fprint(stderr, "touch: can't load %s: %r\n", s);
54	raise "fail:load";
55}
56
57touch(force: int, name: string, now: int): int
58{
59	dir := sys->nulldir;
60	dir.mtime = now;
61	(rc, nil) := sys->stat(name);
62	if(rc >= 0){
63		if(sys->wstat(name, dir) >= 0)
64			return 0;
65		force = 0;	# we don't want to create it: it's there, we just can't wstat it
66	}
67	if(force == 0) {
68		sys->fprint(stderr, "touch: %s: cannot change time: %r\n", name);
69		return 1;
70	}
71	if((fd := sys->create(name, Sys->OREAD|Sys->OEXCL, 8r666)) == nil) {
72		sys->fprint(stderr, "touch: %s: cannot create: %r\n", name);
73		return 1;
74	}
75	sys->fwstat(fd, dir);
76	return 0;
77}
78