Charles.Forsyth20060303a828770d19 years agoHistory
132 lines · 2.7 KB · Brainfuck
RawDownload
implement Uudecode; include "sys.m";	sys : Sys;include "draw.m";include "string.m";	str : String;include "bufio.m";	bufio : Bufio;	Iobuf : import bufio; Uudecode : 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: uudecode [ -p ] [ encodedfile... ]");} init(nil : ref Draw->Context, argv : list of string){	fd : ref Sys->FD; 	tostdout := 0;	sys = load Sys Sys->PATH;	str = load String String->PATH;	bufio = load Bufio Bufio->PATH;	argv = tl argv;	if (argv != nil && hd argv == "-p") {		tostdout = 1;		argv = tl argv;	}	if (argv != nil) {		for (; argv != nil; argv = tl argv) {			fd = sys->open(hd argv, Sys->OREAD);			if (fd == nil)				fatal(sys->sprint("cannot open %s", hd argv));			decode(fd, tostdout);		}	}	else		decode(sys->fildes(0), tostdout);} code(c : byte) : int{	return (int c - ' ')&16r3f;} LEN : con 45;			decode(ifd : ref Sys->FD, tostdout : int){	mode : int;	ofile : string; 	bio := bufio->fopen(ifd, Bufio->OREAD);	if (bio == nil)		fatal("cannot open input for buffered io: %r");	while ((s := bio.gets('\n')) != nil) {		if (len s >= 6 && s[0:6] == "begin ") {			(n, l) := sys->tokenize(s, " \n");			if (n < 3)				fatal("bad begin line");			(mode, nil) = str->toint(hd tl l, 8);			ofile = hd tl tl l;			break;		}	}	if (ofile == nil)		fatal("no begin line");	if (tostdout)		ofd := sys->fildes(1);	else {		if (ofile[0] == '~')	# ~user/file			ofile = "/usr/" + ofile[1:];		ofd = sys->create(ofile, Sys->OWRITE, 8r666);		if (ofd == nil)			fatal(sys->sprint("cannot create %s: %r", ofile));	}	ob := array[LEN] of byte;	while ((s = bio.gets('\n')) != nil) {		b := array of byte s;		n := code(b[0]);		if (n == 0 && (len b != 2 || b[1] != byte '\n'))			fatal("bad 0 count line");		if (n <= 0)			break;		if (n > LEN)			fatal("too many bytes on line");		e := 0; f := 0;		if (n%3 == 1) {			e = 2; f = 4;		}		else if (n%3 == 2) {			e = 3; f = 4;		}		if (len b < 4*(n/3)+e+2 || len b > 4*(n/3)+f+2)			fatal("bad uuencode count");		b = b[1:];		i := 0;		nl := n;		for (j := 0; nl > 0; j += 4) {			if (nl >= 1)				ob[i++] = byte (code(b[j+0])<<2 | code(b[j+1])>>4);			if (nl >= 2)				ob[i++] = byte (code(b[j+1])<<4 | code(b[j+2])>>2);			if (nl >= 3)				ob[i++] = byte (code(b[j+2])<<6 | code(b[j+3])>>0);			nl -= 3;		}		if (sys->write(ofd, ob, i) != i)			fatal("bad write to output: %r");		}	s = bio.gets('\n');	if (s == nil || len s < 4 || s[0:4] != "end\n")		fatal("missing end line");	if (!tostdout) {		d := sys->nulldir;		d.mode = mode;		if (sys->fwstat(ofd, d) < 0)			fatal(sys->sprint("cannot wstat %s: %r", ofile));	}}