implement dd; include "sys.m"; sys: Sys; stderr: ref Sys->FD; include "draw.m"; dd: module{ init: fn(nil: ref Draw->Context, argv: list of string);}; BIG: con 2147483647;LCASE,UCASE,SWAB,NERR ,SYNC : con (1<<iota); NULL,CNULL,EBCDIC,IBM,ASCII,BLOCK,UNBLOCK: con iota; cflag: int;ctype: int; fflag: int;arg: string;ifile: string;ofile: string;ibuf: array of byte;obuf: array of byte;op: int;skip: int;oseekn: int;iseekn: int;count: int;files:= 1;ibs:= 512;obs:= 512;bs: int;cbs: int;ibc: int;obc: int;cbc: int;nifr: int;nipr: int;nofr: int;nopr: int;ntrunc: int;ibf: ref Sys->FD;obf: ref Sys->FD;nspace: int; iskey(key:string, s: string): int{ return key[0] == '-' && key[1:] == s;} exits(msg: string){ if(msg == nil) exit; raise "fail:"+msg;} perror(msg: string){ sys->fprint(stderr, "%s: %r\n", msg);} init(nil: ref Draw->Context, argv: list of string){ sys = load Sys Sys->PATH; if(sys == nil) return; stderr = sys->fildes(2); ctype = NULL; argv = tl argv; while(argv != nil) { key := hd argv; argv = tl argv; if(argv == nil){ sys->fprint(stderr, "dd: arg %s needs a value\n", key); exits("arg"); } arg = hd argv; argv = tl argv; if(iskey(key, "ibs")) { ibs = number(BIG); continue; } if(iskey(key, "obs")) { obs = number(BIG); continue; } if(iskey(key, "cbs")) { cbs = number(BIG); continue; } if(iskey(key, "bs")) { bs = number(BIG); continue; } if(iskey(key, "if")) { ifile = arg[0:]; continue; } if(iskey(key, "of")) { ofile = arg[0:]; continue; } if(iskey(key, "skip")) { skip = number(BIG); continue; } if(iskey(key, "seek") || iskey(key, "oseek")) { oseekn = number(BIG); continue; } if(iskey(key, "iseek")) { iseekn = number(BIG); continue; } if(iskey(key, "count")) { count = number(BIG); continue; } if(iskey(key, "files")) { files = number(BIG); continue; } if(iskey(key, "conv")) { do { if(arg == nil) break; if(match(",")) continue; if(match("ebcdic")) { ctype = EBCDIC; continue; } if(match("ibm")) { ctype = IBM; continue; } if(match("ascii")) { ctype = ASCII; continue; } if(match("block")) { ctype = BLOCK; continue; } if(match("unblock")) { ctype = UNBLOCK; continue; } if(match("lcase")) { cflag |= LCASE; continue; } if(match("ucase")) { cflag |= UCASE; continue; } if(match("swab")) { cflag |= SWAB; continue; } if(match("noerror")) { cflag |= NERR; continue; } if(match("sync")) { cflag |= SYNC; continue; } } while(1); continue; } sys->fprint(stderr, "dd: bad arg: %s\n", key); exits("arg"); } if(ctype == NULL && cflag&(LCASE|UCASE)) ctype = CNULL; if(ifile != nil) ibf = sys->open(ifile, Sys->OREAD); else ibf = sys->fildes(sys->dup(0, -1)); if(ibf == nil) { sys->fprint(stderr, "dd: open %s: %r\n", ifile); exits("open"); } if(ofile != nil){ obf = sys->create(ofile, Sys->OWRITE, 8r664); if(obf == nil) { sys->fprint(stderr, "dd: create %s: %r\n", ofile); exits("create"); } }else{ obf = sys->fildes(sys->dup(1, -1)); if(obf == nil) { sys->fprint(stderr, "dd: can't dup file descriptor: %r\n"); exits("dup"); } } if(bs) ibs = obs = bs; if(ibs == obs && ctype == NULL) fflag++; if(ibs == 0 || obs == 0) { sys->fprint(stderr, "dd: counts: cannot be zero\n"); exits("counts"); } ibuf = array[ibs] of byte; obuf = array[obs] of byte; if(fflag) obuf = ibuf; sys->seek(obf, big obs*big oseekn, Sys->SEEKRELA); sys->seek(ibf, big ibs*big iseekn, Sys->SEEKRELA); while(skip) { sys->read(ibf, ibuf, ibs); skip--; } ibc = 0; obc = 0; cbc = 0; op = 0; ip := 0; do { if(ibc-- == 0) { ibc = 0; if(count==0 || nifr+nipr!=count) { if(cflag&(NERR|SYNC)) for(ip=0; ip < len ibuf; ip++) ibuf[ip] = byte 0; ibc = sys->read(ibf, ibuf, ibs); } if(ibc == -1) { perror("read"); if((cflag&NERR) == 0) { flsh(); term(); } ibc = 0; for(c:=0; c<ibs; c++) if(ibuf[c] != byte 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { flsh(); term(); } if(ibc != ibs) { nipr++; if(cflag&SYNC) ibc = ibs; } else nifr++; ip = 0; c := (ibc>>1) & ~1; if(cflag&SWAB && c) do { a := ibuf[ip++]; ibuf[ip-1] = ibuf[ip]; ibuf[ip++] = a; } while(--c); if(fflag) { obc = ibc; flsh(); ibc = 0; } continue; } c := 0; c |= int ibuf[ip++]; c &= 8r377; conv(c); } while(1);} conv(c: int){ case ctype { NULL => null(c); CNULL => cnull(c); EBCDIC => ebcdic(c); IBM => ibm(c); ASCII => ascii(c); BLOCK => block(c); UNBLOCK => unblock(c); }} flsh(){ if(obc) { if(obc == obs) nofr++; else nopr++; c := sys->write(obf, obuf, obc); if(c != obc) { perror("write"); term(); } obc = 0; }} match(s: string): int{ if(len s > len arg) return 0; if(arg[:len s] == s) { arg = arg[len s:]; return 1; } return 0;} number(bignum: int): int{ n := 0; i := 0; while(i < len arg && arg[i] >= '0' && arg[i] <= '9') n = n*10 + arg[i++] - '0'; for(;i<len arg; i++) case(arg[i]) { 'k' => n *= 1024; 'b' => n *= 512; 'x' => arg = arg[i:]; n *= number(BIG); } if(n>=bignum || n<0) { sys->fprint(stderr, "dd: argument out of range\n"); exits("range"); } return n;} cnull(cc: int){ c := cc; if((cflag&UCASE) && c>='a' && c<='z') c += 'A'-'a'; if((cflag&LCASE) && c>='A' && c<='Z') c += 'a'-'A'; null(c);} null(c: int){ obuf[op++] = byte c; if(++obc >= obs) { flsh(); op = 0; }} ascii(cc: int){ c := etoa[cc]; if(cbs == 0) { cnull(int c); return; } if(c == byte ' ') nspace++; else { while(nspace > 0) { null(' '); nspace--; } cnull(int c); } if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; }} unblock(cc: int){ c := cc & 8r377; if(cbs == 0) { cnull(c); return; } if(c == ' ') nspace++; else { while(nspace > 0) { null(' '); nspace--; } cnull(c); } if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; }} ebcdic(cc: int){ c := cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = int atoe[c]; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(int atoe[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c);} ibm(cc: int){ c := cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = int atoibm[c] & 8r377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(int atoibm[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c);} block(cc: int){ c := cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c &= 8r377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(' '); cbc++; } cbc = 0; return; } if(cbc == cbs)Lines 1–500 of 625. Load more
implement dd; include "sys.m"; sys: Sys; stderr: ref Sys->FD; include "draw.m"; dd: module { init: fn(nil: ref Draw->Context, argv: list of string); }; BIG: con 2147483647; LCASE, UCASE, SWAB, NERR , SYNC : con (1<<iota); NULL, CNULL, EBCDIC, IBM, ASCII, BLOCK, UNBLOCK: con iota; cflag: int; ctype: int; fflag: int; arg: string; ifile: string; ofile: string; ibuf: array of byte; obuf: array of byte; op: int; skip: int; oseekn: int; iseekn: int; count: int; files:= 1; ibs:= 512; obs:= 512; bs: int; cbs: int; ibc: int; obc: int; cbc: int; nifr: int; nipr: int; nofr: int; nopr: int; ntrunc: int; ibf: ref Sys->FD; obf: ref Sys->FD; nspace: int; iskey(key:string, s: string): int { return key[0] == '-' && key[1:] == s; } exits(msg: string) { if(msg == nil) exit; raise "fail:"+msg; } perror(msg: string) { sys->fprint(stderr, "%s: %r\n", msg); } init(nil: ref Draw->Context, argv: list of string) { sys = load Sys Sys->PATH; if(sys == nil) return; stderr = sys->fildes(2); ctype = NULL; argv = tl argv; while(argv != nil) { key := hd argv; argv = tl argv; if(argv == nil){ sys->fprint(stderr, "dd: arg %s needs a value\n", key); exits("arg"); } arg = hd argv; argv = tl argv; if(iskey(key, "ibs")) { ibs = number(BIG); continue; } if(iskey(key, "obs")) { obs = number(BIG); continue; } if(iskey(key, "cbs")) { cbs = number(BIG); continue; } if(iskey(key, "bs")) { bs = number(BIG); continue; } if(iskey(key, "if")) { ifile = arg[0:]; continue; } if(iskey(key, "of")) { ofile = arg[0:]; continue; } if(iskey(key, "skip")) { skip = number(BIG); continue; } if(iskey(key, "seek") || iskey(key, "oseek")) { oseekn = number(BIG); continue; } if(iskey(key, "iseek")) { iseekn = number(BIG); continue; } if(iskey(key, "count")) { count = number(BIG); continue; } if(iskey(key, "files")) { files = number(BIG); continue; } if(iskey(key, "conv")) { do { if(arg == nil) break; if(match(",")) continue; if(match("ebcdic")) { ctype = EBCDIC; continue; } if(match("ibm")) { ctype = IBM; continue; } if(match("ascii")) { ctype = ASCII; continue; } if(match("block")) { ctype = BLOCK; continue; } if(match("unblock")) { ctype = UNBLOCK; continue; } if(match("lcase")) { cflag |= LCASE; continue; } if(match("ucase")) { cflag |= UCASE; continue; } if(match("swab")) { cflag |= SWAB; continue; } if(match("noerror")) { cflag |= NERR; continue; } if(match("sync")) { cflag |= SYNC; continue; } } while(1); continue; } sys->fprint(stderr, "dd: bad arg: %s\n", key); exits("arg"); } if(ctype == NULL && cflag&(LCASE|UCASE)) ctype = CNULL; if(ifile != nil) ibf = sys->open(ifile, Sys->OREAD); else ibf = sys->fildes(sys->dup(0, -1)); if(ibf == nil) { sys->fprint(stderr, "dd: open %s: %r\n", ifile); exits("open"); } if(ofile != nil){ obf = sys->create(ofile, Sys->OWRITE, 8r664); if(obf == nil) { sys->fprint(stderr, "dd: create %s: %r\n", ofile); exits("create"); } }else{ obf = sys->fildes(sys->dup(1, -1)); if(obf == nil) { sys->fprint(stderr, "dd: can't dup file descriptor: %r\n"); exits("dup"); } } if(bs) ibs = obs = bs; if(ibs == obs && ctype == NULL) fflag++; if(ibs == 0 || obs == 0) { sys->fprint(stderr, "dd: counts: cannot be zero\n"); exits("counts"); } ibuf = array[ibs] of byte; obuf = array[obs] of byte; if(fflag) obuf = ibuf; sys->seek(obf, big obs*big oseekn, Sys->SEEKRELA); sys->seek(ibf, big ibs*big iseekn, Sys->SEEKRELA); while(skip) { sys->read(ibf, ibuf, ibs); skip--; } ibc = 0; obc = 0; cbc = 0; op = 0; ip := 0; do { if(ibc-- == 0) { ibc = 0; if(count==0 || nifr+nipr!=count) { if(cflag&(NERR|SYNC)) for(ip=0; ip < len ibuf; ip++) ibuf[ip] = byte 0; ibc = sys->read(ibf, ibuf, ibs); } if(ibc == -1) { perror("read"); if((cflag&NERR) == 0) { flsh(); term(); } ibc = 0; for(c:=0; c<ibs; c++) if(ibuf[c] != byte 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { flsh(); term(); } if(ibc != ibs) { nipr++; if(cflag&SYNC) ibc = ibs; } else nifr++; ip = 0; c := (ibc>>1) & ~1; if(cflag&SWAB && c) do { a := ibuf[ip++]; ibuf[ip-1] = ibuf[ip]; ibuf[ip++] = a; } while(--c); if(fflag) { obc = ibc; flsh(); ibc = 0; } continue; } c := 0; c |= int ibuf[ip++]; c &= 8r377; conv(c); } while(1); } conv(c: int) { case ctype { NULL => null(c); CNULL => cnull(c); EBCDIC => ebcdic(c); IBM => ibm(c); ASCII => ascii(c); BLOCK => block(c); UNBLOCK => unblock(c); } } flsh() { if(obc) { if(obc == obs) nofr++; else nopr++; c := sys->write(obf, obuf, obc); if(c != obc) { perror("write"); term(); } obc = 0; } } match(s: string): int { if(len s > len arg) return 0; if(arg[:len s] == s) { arg = arg[len s:]; return 1; } return 0; } number(bignum: int): int { n := 0; i := 0; while(i < len arg && arg[i] >= '0' && arg[i] <= '9') n = n*10 + arg[i++] - '0'; for(;i<len arg; i++) case(arg[i]) { 'k' => n *= 1024; 'b' => n *= 512; 'x' => arg = arg[i:]; n *= number(BIG); } if(n>=bignum || n<0) { sys->fprint(stderr, "dd: argument out of range\n"); exits("range"); } return n; } cnull(cc: int) { c := cc; if((cflag&UCASE) && c>='a' && c<='z') c += 'A'-'a'; if((cflag&LCASE) && c>='A' && c<='Z') c += 'a'-'A'; null(c); } null(c: int) { obuf[op++] = byte c; if(++obc >= obs) { flsh(); op = 0; } } ascii(cc: int) { c := etoa[cc]; if(cbs == 0) { cnull(int c); return; } if(c == byte ' ') nspace++; else { while(nspace > 0) { null(' '); nspace--; } cnull(int c); } if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; } } unblock(cc: int) { c := cc & 8r377; if(cbs == 0) { cnull(c); return; } if(c == ' ') nspace++; else { while(nspace > 0) { null(' '); nspace--; } cnull(c); } if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; } } ebcdic(cc: int) { c := cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = int atoe[c]; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(int atoe[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c); } ibm(cc: int) { c := cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = int atoibm[c] & 8r377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(int atoibm[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c); } block(cc: int) { c := cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c &= 8r377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(' '); cbc++; } cbc = 0; return; } if(cbc == cbs)