summaryrefslogtreecommitdiff
path: root/appl/cmd/uuencode.b
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 17:07:39 +0000
commit37da2899f40661e3e9631e497da8dc59b971cbd0 (patch)
treecbc6d4680e347d906f5fa7fca73214418741df72 /appl/cmd/uuencode.b
parent54bc8ff236ac10b3eaa928fd6bcfc0cdb2ba46ae (diff)
20060303a
Diffstat (limited to 'appl/cmd/uuencode.b')
-rw-r--r--appl/cmd/uuencode.b101
1 files changed, 101 insertions, 0 deletions
diff --git a/appl/cmd/uuencode.b b/appl/cmd/uuencode.b
new file mode 100644
index 00000000..54dedfdf
--- /dev/null
+++ b/appl/cmd/uuencode.b
@@ -0,0 +1,101 @@
+implement Uuencode;
+
+include "sys.m";
+ sys : Sys;
+include "draw.m";
+
+Uuencode : module
+{
+ init : fn(nil : ref Draw->Context, argv : list of string);
+};
+
+fatal(s : string)
+{
+ sys->fprint(sys->fildes(2), "%s\n", s);
+ exit;
+}
+
+usage()
+{
+ fatal("usage: uuencode [ sourcefile ] remotefile");
+}
+
+init(nil : ref Draw->Context, argv : list of string)
+{
+ fd : ref Sys->FD;
+ mode : int;
+
+ sys = load Sys Sys->PATH;
+ argv = tl argv;
+ if (argv == nil)
+ usage();
+ if (tl argv != nil) {
+ fd = sys->open(hd argv, Sys->OREAD);
+ if (fd == nil)
+ fatal(sys->sprint("cannot open %s", hd argv));
+ (ok, d) := sys->fstat(fd);
+ if (ok < 0)
+ fatal(sys->sprint("cannot stat %s: %r", hd argv));
+ if (d.mode & Sys->DMDIR)
+ fatal("cannot uuencode a directory");
+ mode = d.mode;
+ argv = tl argv;
+ }
+ else {
+ fd = sys->fildes(0);
+ mode = 8r666;
+ }
+ if (tl argv != nil)
+ usage();
+ sys->print("begin %o %s\n", mode, hd argv);
+ encode(fd);
+ sys->print("end\n");
+}
+
+LEN : con 45;
+
+code(c : int) : byte
+{
+ return byte ((c&16r3f) + ' ');
+}
+
+encode(ifd : ref Sys->FD)
+{
+ c, d, e : int;
+
+ ofd := sys->fildes(1);
+ ib := array[LEN] of byte;
+ ob := array[4*LEN/3 + 2] of byte;
+ for (;;) {
+ n := sys->read(ifd, ib, LEN);
+ if (n < 0)
+ fatal("cannot read input file: %r");
+ if (n == 0)
+ break;
+ i := 0;
+ ob[i++] = code(n);
+ for (j := 0; j < n; j += 3) {
+ c = int ib[j];
+ ob[i++] = code((0<<6)&16r00 | (c>>2)&16r3f);
+ if (j+1 < n)
+ d = int ib[j+1];
+ else
+ d = 0;
+ ob[i++] = code((c<<4)&16r30 | (d>>4)&16r0f);
+ if (j+2 < n)
+ e = int ib[j+2];
+ else
+ e = 0;
+ ob[i++] = code((d<<2)&16r3c | (e>>6)&16r03);
+ ob[i++] = code((e<<0)&16r3f | (0>>8)&16r00);
+ }
+ ob[i++] = byte '\n';
+ if (sys->write(ofd, ob, i) != i)
+ fatal("bad write to output: %r");
+ }
+ ob[0] = code(0);
+ ob[1] = byte '\n';
+ if (sys->write(ofd, ob, 2) != 2)
+ fatal("bad write to output: %r");
+}
+