From 37da2899f40661e3e9631e497da8dc59b971cbd0 Mon Sep 17 00:00:00 2001 From: "Charles.Forsyth" Date: Fri, 22 Dec 2006 17:07:39 +0000 Subject: 20060303a --- appl/cmd/lstar.b | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 appl/cmd/lstar.b (limited to 'appl/cmd/lstar.b') diff --git a/appl/cmd/lstar.b b/appl/cmd/lstar.b new file mode 100644 index 00000000..fddd19d2 --- /dev/null +++ b/appl/cmd/lstar.b @@ -0,0 +1,120 @@ +implement lstar; + +include "sys.m"; + sys: Sys; + print, sprint, fprint: import sys; + stdin, stderr: ref sys->FD; +include "draw.m"; + +TBLOCK: con 512; # tar logical blocksize +Header: adt{ + name: string; + size: int; + mtime: int; + skip: int; +}; + +lstar: module{ + init: fn(nil: ref Draw->Context, nil: list of string); +}; + +Error(mess: string){ + fprint(stderr,"lstar: %s: %r\n",mess); + exit; +} + + +NBLOCK: con 20; # blocking factor for efficient read +tarbuf := array[NBLOCK*TBLOCK] of byte; # static buffer +nblock := NBLOCK; # how many blocks of data are in tarbuf +recno := NBLOCK; # how many blocks in tarbuf have been consumed +getblock():array of byte{ + if(recno>=nblock){ + i := sys->read(stdin,tarbuf,TBLOCK*NBLOCK); + if(i==0) + return tarbuf[0:0]; + if(i<0) + Error("read error"); + if(i%TBLOCK!=0) + Error("blocksize error"); + nblock = i/TBLOCK; + recno = 0; + } + recno++; + return tarbuf[(recno-1)*TBLOCK:recno*TBLOCK]; +} + +octal(b:array of byte):int{ + sum := 0; + for(i:=0; i + skip = 0; + size = octal(dblock[124:136]); + mtime = octal(dblock[136:148]); + '1' => + fprint(stderr,"skipping link %s -> %s\n",name,string(dblock[157:257])); + '2' or 's' => + fprint(stderr,"skipping symlink %s\n",name); + '3' or '4' or '6' => + fprint(stderr,"skipping special file %s\n",name); + * => + Error(sprint("unrecognized typeflag %d for %s",int dblock[156],name)); + } + return ref Header(name,size,mtime,skip); +} + + +init(nil: ref Draw->Context, nil: list of string){ + sys = load Sys Sys->PATH; + stdin = sys->fildes(0); + stderr = sys->fildes(2); + ofile: ref sys->FD; + + while((file := getdir())!=nil){ + bytes := file.size; + blocks := (bytes+TBLOCK-1)/TBLOCK; + for(; blocks>0; blocks--) + getblock(); + print("%s %d %d 0\n",file.name,file.mtime,file.size); + ofile = nil; + } +} -- cgit v1.2.3