#include <u.h>#include <libc.h> #define BIG ((1UL<<31)-1)#define VBIG ((1ULL<<63)-1)#define LCASE (1<<0)#define UCASE (1<<1)#define SWAB (1<<2)#define NERR (1<<3)#define SYNC (1<<4) int cflag;int fflag; char *string;char *ifile;char *ofile;char *ibuf;char *obuf; vlong skip;vlong oseekn;vlong iseekn;vlong count; long files = 1;long ibs = 512;long obs = 512;long bs;long cbs;long ibc;long obc;long cbc;long nifr;long nipr;long nofr;long nopr;long ntrunc; int dotrunc = 1;int ibf;int obf; char *op;int nspace; uchar etoa[256];uchar atoe[256];uchar atoibm[256]; int quiet; void flsh(void);int match(char *s);vlong number(vlong big);void cnull(int cc);void null(int c);void ascii(int cc);void unblock(int cc);void ebcdic(int cc);void ibm(int cc);void block(int cc);void term(char*);void stats(void); #define iskey(s) ((key[0] == '-') && (strcmp(key+1, s) == 0)) intmain(int argc, char *argv[]){ void (*conv)(int); char *ip; char *key; int a, c; conv = null; for(c=1; c<argc; c++) { key = argv[c++]; if(c >= argc){ fprint(2, "dd: arg %s needs a value\n", key); exits("arg"); } string = argv[c]; if(iskey("ibs")) { ibs = number(BIG); continue; } if(iskey("obs")) { obs = number(BIG); continue; } if(iskey("cbs")) { cbs = number(BIG); continue; } if(iskey("bs")) { bs = number(BIG); continue; } if(iskey("if")) { ifile = string; continue; } if(iskey("of")) { ofile = string; continue; } if(iskey("trunc")) { dotrunc = number(BIG); continue; } if(iskey("quiet")) { quiet = number(BIG); continue; } if(iskey("skip")) { skip = number(VBIG); continue; } if(iskey("seek") || iskey("oseek")) { oseekn = number(VBIG); continue; } if(iskey("iseek")) { iseekn = number(VBIG); continue; } if(iskey("count")) { count = number(VBIG); continue; } if(iskey("files")) { files = number(BIG); continue; } if(iskey("conv")) { cloop: if(match(",")) goto cloop; if(*string == '\0') continue; if(match("ebcdic")) { conv = ebcdic; goto cloop; } if(match("ibm")) { conv = ibm; goto cloop; } if(match("ascii")) { conv = ascii; goto cloop; } if(match("block")) { conv = block; goto cloop; } if(match("unblock")) { conv = unblock; goto cloop; } if(match("lcase")) { cflag |= LCASE; goto cloop; } if(match("ucase")) { cflag |= UCASE; goto cloop; } if(match("swab")) { cflag |= SWAB; goto cloop; } if(match("noerror")) { cflag |= NERR; goto cloop; } if(match("sync")) { cflag |= SYNC; goto cloop; } fprint(2, "dd: bad conv %s\n", argv[c]); exits("arg"); } fprint(2, "dd: bad arg: %s\n", key); exits("arg"); } if(conv == null && cflag&(LCASE|UCASE)) conv = cnull; if(ifile) ibf = open(ifile, 0); else ibf = dup(0, -1); if(ibf < 0) { fprint(2, "dd: open %s: %r\n", ifile); exits("open"); } if(ofile){ if(dotrunc) obf = create(ofile, 1, 0664); else obf = open(ofile, 1); if(obf < 0) { fprint(2, "dd: create %s: %r\n", ofile); exits("create"); } }else{ obf = dup(1, -1); if(obf < 0) { fprint(2, "dd: can't dup file descriptor: %s: %r\n", ofile); exits("dup"); } } if(bs) ibs = obs = bs; if(ibs == obs && conv == null) fflag++; if(ibs == 0 || obs == 0) { fprint(2, "dd: counts: cannot be zero\n"); exits("counts"); } ibuf = sbrk(ibs); if(fflag) obuf = ibuf; else obuf = sbrk(obs); sbrk(64); /* For good measure */ if(ibuf == (char *)-1 || obuf == (char *)-1) { fprint(2, "dd: not enough memory: %r\n"); exits("memory"); } ibc = 0; obc = 0; cbc = 0; op = obuf; /* if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, term);*/ seek(obf, obs*oseekn, 1); seek(ibf, ibs*iseekn, 1); while(skip) { read(ibf, ibuf, ibs); skip--; } ip = 0;loop: if(ibc-- == 0) { ibc = 0; if(count==0 || nifr+nipr!=count) { if(cflag&(NERR|SYNC)) for(ip=ibuf+ibs; ip>ibuf;) *--ip = 0; ibc = read(ibf, ibuf, ibs); } if(ibc == -1) { perror("read"); if((cflag&NERR) == 0) { flsh(); term("errors"); } ibc = 0; for(c=0; c<ibs; c++) if(ibuf[c] != 0) ibc = c+1; seek(ibf, ibs, 1); stats(); }else if(ibc == 0 && --files<=0) { flsh(); term(nil); } if(ibc != ibs) { nipr++; if(cflag&SYNC) ibc = ibs; } else nifr++; ip = ibuf; c = (ibc>>1) & ~1; if(cflag&SWAB && c) do { a = *ip++; ip[-1] = *ip; *ip++ = a; } while(--c); ip = ibuf; if(fflag) { obc = ibc; flsh(); ibc = 0; } goto loop; } c = 0; c |= *ip++; c &= 0377; (*conv)(c); goto loop;} voidflsh(void){ int c; if(obc) { /* don't perror dregs of previous errors on a short write */ werrstr(""); c = write(obf, obuf, obc); if(c != obc) { if(c > 0) ++nopr; perror("write"); term("errors"); } if(obc == obs) nofr++; else nopr++; obc = 0; }} intmatch(char *s){ char *cs; cs = string; while(*cs++ == *s) if(*s++ == '\0') goto true; if(*s != '\0') return 0; true: cs--; string = cs; return 1;} static char power[] = "kmgtpezy"; vlongnumber(vlong big){ char *cs, *q, ch; int c; uvlong n; n = strtoull(string, &cs, 0); if(cs == string){bad: fprint(2, "dd: bad number %s\n", string); exits("badnum"); } for(;;){ switch(ch = *cs++){ default: q = strchr(power, ch); if(q == nil) goto bad; for(c = q - power + 1; c--; ) n *= 1024; break; case 'b': n *= 512; break; case 'x':/* case '*':*/ string = cs; n *= number(VBIG); case '\0': if(n > big) { fprint(2, "dd: argument %llud out of range\n", n); exits("range"); } return n; } }} voidcnull(int cc){ int c; c = cc; if((cflag&UCASE) && c>='a' && c<='z') c += 'A'-'a'; if((cflag&LCASE) && c>='A' && c<='Z') c += 'a'-'A'; null(c);} voidnull(int c){ *op = c; op++; if(++obc >= obs) { flsh(); op = obuf; }} voidascii(int cc){ int c; c = etoa[cc]; if(cbs == 0) { cnull(c); return; } if(c == ' ') { nspace++; goto out; } while(nspace > 0) { null(' '); nspace--; } cnull(c); out: if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; }} voidunblock(int cc){ int c; c = cc & 0377; if(cbs == 0) { cnull(c); return; } if(c == ' ') { nspace++; goto out; } while(nspace > 0) { null(' '); nspace--; } cnull(c); out: if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; }} voidebcdic(int cc){ int c; c = cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = atoe[c]; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(atoe[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c);} voidibm(int cc){ int c; Lines 1–500 of 678. Load more
#include <u.h> #include <libc.h> #define BIG ((1UL<<31)-1) #define VBIG ((1ULL<<63)-1) #define LCASE (1<<0) #define UCASE (1<<1) #define SWAB (1<<2) #define NERR (1<<3) #define SYNC (1<<4) int cflag; int fflag; char *string; char *ifile; char *ofile; char *ibuf; char *obuf; vlong skip; vlong oseekn; vlong iseekn; vlong count; long files = 1; long ibs = 512; long obs = 512; long bs; long cbs; long ibc; long obc; long cbc; long nifr; long nipr; long nofr; long nopr; long ntrunc; int dotrunc = 1; int ibf; int obf; char *op; int nspace; uchar etoa[256]; uchar atoe[256]; uchar atoibm[256]; int quiet; void flsh(void); int match(char *s); vlong number(vlong big); void cnull(int cc); void null(int c); void ascii(int cc); void unblock(int cc); void ebcdic(int cc); void ibm(int cc); void block(int cc); void term(char*); void stats(void); #define iskey(s) ((key[0] == '-') && (strcmp(key+1, s) == 0)) int main(int argc, char *argv[]) { void (*conv)(int); char *ip; char *key; int a, c; conv = null; for(c=1; c<argc; c++) { key = argv[c++]; if(c >= argc){ fprint(2, "dd: arg %s needs a value\n", key); exits("arg"); } string = argv[c]; if(iskey("ibs")) { ibs = number(BIG); continue; } if(iskey("obs")) { obs = number(BIG); continue; } if(iskey("cbs")) { cbs = number(BIG); continue; } if(iskey("bs")) { bs = number(BIG); continue; } if(iskey("if")) { ifile = string; continue; } if(iskey("of")) { ofile = string; continue; } if(iskey("trunc")) { dotrunc = number(BIG); continue; } if(iskey("quiet")) { quiet = number(BIG); continue; } if(iskey("skip")) { skip = number(VBIG); continue; } if(iskey("seek") || iskey("oseek")) { oseekn = number(VBIG); continue; } if(iskey("iseek")) { iseekn = number(VBIG); continue; } if(iskey("count")) { count = number(VBIG); continue; } if(iskey("files")) { files = number(BIG); continue; } if(iskey("conv")) { cloop: if(match(",")) goto cloop; if(*string == '\0') continue; if(match("ebcdic")) { conv = ebcdic; goto cloop; } if(match("ibm")) { conv = ibm; goto cloop; } if(match("ascii")) { conv = ascii; goto cloop; } if(match("block")) { conv = block; goto cloop; } if(match("unblock")) { conv = unblock; goto cloop; } if(match("lcase")) { cflag |= LCASE; goto cloop; } if(match("ucase")) { cflag |= UCASE; goto cloop; } if(match("swab")) { cflag |= SWAB; goto cloop; } if(match("noerror")) { cflag |= NERR; goto cloop; } if(match("sync")) { cflag |= SYNC; goto cloop; } fprint(2, "dd: bad conv %s\n", argv[c]); exits("arg"); } fprint(2, "dd: bad arg: %s\n", key); exits("arg"); } if(conv == null && cflag&(LCASE|UCASE)) conv = cnull; if(ifile) ibf = open(ifile, 0); else ibf = dup(0, -1); if(ibf < 0) { fprint(2, "dd: open %s: %r\n", ifile); exits("open"); } if(ofile){ if(dotrunc) obf = create(ofile, 1, 0664); else obf = open(ofile, 1); if(obf < 0) { fprint(2, "dd: create %s: %r\n", ofile); exits("create"); } }else{ obf = dup(1, -1); if(obf < 0) { fprint(2, "dd: can't dup file descriptor: %s: %r\n", ofile); exits("dup"); } } if(bs) ibs = obs = bs; if(ibs == obs && conv == null) fflag++; if(ibs == 0 || obs == 0) { fprint(2, "dd: counts: cannot be zero\n"); exits("counts"); } ibuf = sbrk(ibs); if(fflag) obuf = ibuf; else obuf = sbrk(obs); sbrk(64); /* For good measure */ if(ibuf == (char *)-1 || obuf == (char *)-1) { fprint(2, "dd: not enough memory: %r\n"); exits("memory"); } ibc = 0; obc = 0; cbc = 0; op = obuf; /* if(signal(SIGINT, SIG_IGN) != SIG_IGN) signal(SIGINT, term); */ seek(obf, obs*oseekn, 1); seek(ibf, ibs*iseekn, 1); while(skip) { read(ibf, ibuf, ibs); skip--; } ip = 0; loop: if(ibc-- == 0) { ibc = 0; if(count==0 || nifr+nipr!=count) { if(cflag&(NERR|SYNC)) for(ip=ibuf+ibs; ip>ibuf;) *--ip = 0; ibc = read(ibf, ibuf, ibs); } if(ibc == -1) { perror("read"); if((cflag&NERR) == 0) { flsh(); term("errors"); } ibc = 0; for(c=0; c<ibs; c++) if(ibuf[c] != 0) ibc = c+1; seek(ibf, ibs, 1); stats(); }else if(ibc == 0 && --files<=0) { flsh(); term(nil); } if(ibc != ibs) { nipr++; if(cflag&SYNC) ibc = ibs; } else nifr++; ip = ibuf; c = (ibc>>1) & ~1; if(cflag&SWAB && c) do { a = *ip++; ip[-1] = *ip; *ip++ = a; } while(--c); ip = ibuf; if(fflag) { obc = ibc; flsh(); ibc = 0; } goto loop; } c = 0; c |= *ip++; c &= 0377; (*conv)(c); goto loop; } void flsh(void) { int c; if(obc) { /* don't perror dregs of previous errors on a short write */ werrstr(""); c = write(obf, obuf, obc); if(c != obc) { if(c > 0) ++nopr; perror("write"); term("errors"); } if(obc == obs) nofr++; else nopr++; obc = 0; } } int match(char *s) { char *cs; cs = string; while(*cs++ == *s) if(*s++ == '\0') goto true; if(*s != '\0') return 0; true: cs--; string = cs; return 1; } static char power[] = "kmgtpezy"; vlong number(vlong big) { char *cs, *q, ch; int c; uvlong n; n = strtoull(string, &cs, 0); if(cs == string){ bad: fprint(2, "dd: bad number %s\n", string); exits("badnum"); } for(;;){ switch(ch = *cs++){ default: q = strchr(power, ch); if(q == nil) goto bad; for(c = q - power + 1; c--; ) n *= 1024; break; case 'b': n *= 512; break; case 'x': /* case '*':*/ string = cs; n *= number(VBIG); case '\0': if(n > big) { fprint(2, "dd: argument %llud out of range\n", n); exits("range"); } return n; } } } void cnull(int cc) { int c; c = cc; if((cflag&UCASE) && c>='a' && c<='z') c += 'A'-'a'; if((cflag&LCASE) && c>='A' && c<='Z') c += 'a'-'A'; null(c); } void null(int c) { *op = c; op++; if(++obc >= obs) { flsh(); op = obuf; } } void ascii(int cc) { int c; c = etoa[cc]; if(cbs == 0) { cnull(c); return; } if(c == ' ') { nspace++; goto out; } while(nspace > 0) { null(' '); nspace--; } cnull(c); out: if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; } } void unblock(int cc) { int c; c = cc & 0377; if(cbs == 0) { cnull(c); return; } if(c == ' ') { nspace++; goto out; } while(nspace > 0) { null(' '); nspace--; } cnull(c); out: if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; } } void ebcdic(int cc) { int c; c = cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = atoe[c]; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(atoe[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c); } void ibm(int cc) { int c;