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