#include <u.h>#include <libc.h> #define BIG 2147483647#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;long skip;long oseekn;long iseekn;long 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 ibf;int obf;char *op;int nspace;uchar etoa[256];uchar atoe[256];uchar atoibm[256]; void flsh(void);int match(char *s);long number(long 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(void);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("skip")) { skip = number(BIG); continue; } if(iskey("seek") || iskey("oseek")) { oseekn = number(BIG); continue; } if(iskey("iseek")) { iseekn = number(BIG); continue; } if(iskey("count")) { count = number(BIG); 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 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){ obf = create(ofile, 1, 0664); 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: %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(); } ibc = 0; for(c=0; c<ibs; c++) if(ibuf[c] != 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { flsh(); term(); } 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) { if(obc == obs) nofr++; else nopr++; c = write(obf, obuf, obc); if(c != obc) { perror("write"); term(); } 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;} longnumber(long big){ char *cs; long n; cs = string; n = 0; while(*cs >= '0' && *cs <= '9') n = n*10 + *cs++ - '0'; for(;;) switch(*cs++) { case 'k': n *= 1024; continue; /* case 'w': n *= sizeof(int); continue;*/ case 'b': n *= 512; continue; /* case '*':*/ case 'x': string = cs; n *= number(BIG); case '\0': if(n>=big || n<0) { fprint(2, "dd: argument %ld out of range\n", n); exits("range"); } return n; } /* never gets here */} 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; c = cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = atoibm[c] & 0377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(atoibm[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c);} voidblock(int cc){ int c;Lines 1–500 of 649. Load more
#include <u.h> #include <libc.h> #define BIG 2147483647 #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; long skip; long oseekn; long iseekn; long 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 ibf; int obf; char *op; int nspace; uchar etoa[256]; uchar atoe[256]; uchar atoibm[256]; void flsh(void); int match(char *s); long number(long 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(void); 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("skip")) { skip = number(BIG); continue; } if(iskey("seek") || iskey("oseek")) { oseekn = number(BIG); continue; } if(iskey("iseek")) { iseekn = number(BIG); continue; } if(iskey("count")) { count = number(BIG); 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 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){ obf = create(ofile, 1, 0664); 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: %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(); } ibc = 0; for(c=0; c<ibs; c++) if(ibuf[c] != 0) ibc = c; stats(); } if(ibc == 0 && --files<=0) { flsh(); term(); } 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) { if(obc == obs) nofr++; else nopr++; c = write(obf, obuf, obc); if(c != obc) { perror("write"); term(); } 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; } long number(long big) { char *cs; long n; cs = string; n = 0; while(*cs >= '0' && *cs <= '9') n = n*10 + *cs++ - '0'; for(;;) switch(*cs++) { case 'k': n *= 1024; continue; /* case 'w': n *= sizeof(int); continue; */ case 'b': n *= 512; continue; /* case '*':*/ case 'x': string = cs; n *= number(BIG); case '\0': if(n>=big || n<0) { fprint(2, "dd: argument %ld out of range\n", n); exits("range"); } return n; } /* never gets here */ } 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; c = cc; if(cflag&UCASE && c>='a' && c<='z') c += 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c += 'a'-'A'; c = atoibm[c] & 0377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(atoibm[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c); } void block(int cc) { int c;