xref: /inferno-os/appl/cmd/uuencode.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1*37da2899SCharles.Forsythimplement Uuencode;
2*37da2899SCharles.Forsyth
3*37da2899SCharles.Forsythinclude "sys.m";
4*37da2899SCharles.Forsyth	sys : Sys;
5*37da2899SCharles.Forsythinclude "draw.m";
6*37da2899SCharles.Forsyth
7*37da2899SCharles.ForsythUuencode : module
8*37da2899SCharles.Forsyth{
9*37da2899SCharles.Forsyth	init : fn(nil : ref Draw->Context, argv : list of string);
10*37da2899SCharles.Forsyth};
11*37da2899SCharles.Forsyth
12*37da2899SCharles.Forsythfatal(s : string)
13*37da2899SCharles.Forsyth{
14*37da2899SCharles.Forsyth	sys->fprint(sys->fildes(2), "%s\n", s);
15*37da2899SCharles.Forsyth	exit;
16*37da2899SCharles.Forsyth}
17*37da2899SCharles.Forsyth
18*37da2899SCharles.Forsythusage()
19*37da2899SCharles.Forsyth{
20*37da2899SCharles.Forsyth	fatal("usage: uuencode [ sourcefile ] remotefile");
21*37da2899SCharles.Forsyth}
22*37da2899SCharles.Forsyth
23*37da2899SCharles.Forsythinit(nil : ref Draw->Context, argv : list of string)
24*37da2899SCharles.Forsyth{
25*37da2899SCharles.Forsyth	fd : ref Sys->FD;
26*37da2899SCharles.Forsyth	mode : int;
27*37da2899SCharles.Forsyth
28*37da2899SCharles.Forsyth	sys = load Sys Sys->PATH;
29*37da2899SCharles.Forsyth	argv = tl argv;
30*37da2899SCharles.Forsyth	if (argv == nil)
31*37da2899SCharles.Forsyth		usage();
32*37da2899SCharles.Forsyth	if (tl argv != nil) {
33*37da2899SCharles.Forsyth		fd = sys->open(hd argv, Sys->OREAD);
34*37da2899SCharles.Forsyth		if (fd == nil)
35*37da2899SCharles.Forsyth			fatal(sys->sprint("cannot open %s", hd argv));
36*37da2899SCharles.Forsyth		(ok, d) := sys->fstat(fd);
37*37da2899SCharles.Forsyth		if (ok < 0)
38*37da2899SCharles.Forsyth			fatal(sys->sprint("cannot stat %s: %r", hd argv));
39*37da2899SCharles.Forsyth		if (d.mode & Sys->DMDIR)
40*37da2899SCharles.Forsyth			fatal("cannot uuencode a directory");
41*37da2899SCharles.Forsyth		mode = d.mode;
42*37da2899SCharles.Forsyth		argv = tl argv;
43*37da2899SCharles.Forsyth	}
44*37da2899SCharles.Forsyth	else {
45*37da2899SCharles.Forsyth		fd = sys->fildes(0);
46*37da2899SCharles.Forsyth		mode = 8r666;
47*37da2899SCharles.Forsyth	}
48*37da2899SCharles.Forsyth	if (tl argv != nil)
49*37da2899SCharles.Forsyth		usage();
50*37da2899SCharles.Forsyth	sys->print("begin %o %s\n", mode, hd argv);
51*37da2899SCharles.Forsyth	encode(fd);
52*37da2899SCharles.Forsyth	sys->print("end\n");
53*37da2899SCharles.Forsyth}
54*37da2899SCharles.Forsyth
55*37da2899SCharles.ForsythLEN : con 45;
56*37da2899SCharles.Forsyth
57*37da2899SCharles.Forsythcode(c : int) : byte
58*37da2899SCharles.Forsyth{
59*37da2899SCharles.Forsyth	return byte ((c&16r3f) + ' ');
60*37da2899SCharles.Forsyth}
61*37da2899SCharles.Forsyth
62*37da2899SCharles.Forsythencode(ifd : ref Sys->FD)
63*37da2899SCharles.Forsyth{
64*37da2899SCharles.Forsyth	c, d, e : int;
65*37da2899SCharles.Forsyth
66*37da2899SCharles.Forsyth	ofd := sys->fildes(1);
67*37da2899SCharles.Forsyth	ib := array[LEN] of byte;
68*37da2899SCharles.Forsyth	ob := array[4*LEN/3 + 2] of byte;
69*37da2899SCharles.Forsyth	for (;;) {
70*37da2899SCharles.Forsyth		n := sys->read(ifd, ib, LEN);
71*37da2899SCharles.Forsyth		if (n < 0)
72*37da2899SCharles.Forsyth			fatal("cannot read input file: %r");
73*37da2899SCharles.Forsyth		if (n == 0)
74*37da2899SCharles.Forsyth			break;
75*37da2899SCharles.Forsyth		i := 0;
76*37da2899SCharles.Forsyth		ob[i++] = code(n);
77*37da2899SCharles.Forsyth		for (j := 0; j < n; j += 3) {
78*37da2899SCharles.Forsyth			c = int ib[j];
79*37da2899SCharles.Forsyth			ob[i++] = code((0<<6)&16r00 | (c>>2)&16r3f);
80*37da2899SCharles.Forsyth			if (j+1 < n)
81*37da2899SCharles.Forsyth				d = int ib[j+1];
82*37da2899SCharles.Forsyth			else
83*37da2899SCharles.Forsyth				d = 0;
84*37da2899SCharles.Forsyth			ob[i++] = code((c<<4)&16r30 | (d>>4)&16r0f);
85*37da2899SCharles.Forsyth			if (j+2 < n)
86*37da2899SCharles.Forsyth				e = int ib[j+2];
87*37da2899SCharles.Forsyth			else
88*37da2899SCharles.Forsyth				e = 0;
89*37da2899SCharles.Forsyth			ob[i++] = code((d<<2)&16r3c | (e>>6)&16r03);
90*37da2899SCharles.Forsyth			ob[i++] = code((e<<0)&16r3f | (0>>8)&16r00);
91*37da2899SCharles.Forsyth		}
92*37da2899SCharles.Forsyth		ob[i++] = byte '\n';
93*37da2899SCharles.Forsyth		if (sys->write(ofd, ob, i) != i)
94*37da2899SCharles.Forsyth			fatal("bad write to output: %r");
95*37da2899SCharles.Forsyth	}
96*37da2899SCharles.Forsyth	ob[0] = code(0);
97*37da2899SCharles.Forsyth	ob[1] = byte '\n';
98*37da2899SCharles.Forsyth	if (sys->write(ofd, ob, 2) != 2)
99*37da2899SCharles.Forsyth		fatal("bad write to output: %r");
100*37da2899SCharles.Forsyth}
101*37da2899SCharles.Forsyth
102