AUSAM/source/S/dd.c
#define LCASE 01
#define UCASE 02
#define SWAB 04
#define NERR 010
#define SYNC 020
int cflag;
int fflag;
char *string;
char *ifile;
char *ofile;
char *ibuf;
char *obuf;
unsigned count;
unsigned skip;
unsigned iseek;
unsigned oseek;
unsigned ibs 512;
unsigned obs 512;
unsigned bs;
unsigned cbs;
unsigned ibc;
unsigned obc;
unsigned cbc;
int nifr;
int nipr;
int nofr;
int nopr;
int ntrunc;
int ibf;
int obf;
char *op;
int nspace;
char etoa[]
{
0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
};
char atoe[]
{
0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
};
main(argc, argv)
int argc;
char **argv;
{
register (*conv)();
register char *ip;
register c;
int ebcdic(), ascii(), null(), cnull(), term();
int a;
long offset;
conv = null;
for(c = 1; c < argc; c++)
{
string = argv[c];
if(match("ibs="))
{
ibs = number();
continue;
}
if(match("obs="))
{
obs = number();
continue;
}
if(match("cbs="))
{
cbs = number();
continue;
}
if(match("bs="))
{
bs = number();
continue;
}
if(match("if="))
{
ifile = string;
continue;
}
if(match("of="))
{
ofile = string;
continue;
}
if(match("skip="))
{
skip = number();
continue;
}
if(match("oseek="))
{
oseek = number();
continue;
}
if(match("iseek="))
{
iseek = number();
continue;
}
if(match("count="))
{
count = number();
continue;
}
if(match("conv="))
{
cloop:
if(match(","))
goto cloop;
if(*string == '\0')
continue;
if(match("ebcdic"))
{
conv = ebcdic;
goto cloop;
}
if(match("ascii"))
{
conv = ascii;
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;
}
}
printf("bad arg: %s\n", string);
exit();
}
if(conv == null && cflag&(LCASE|UCASE))
conv = cnull;
if(ifile)
ibf = open(ifile, 0);
else
ibf = dup(0);
if(ibf < 0)
{
printf("cannot open: %s\n", ifile);
exit();
}
if(oseek)
obf = open(ofile, 1);
else if(ofile)
obf = creat(ofile, 0600);
else
obf = dup(1);
if(obf < 0)
{
printf("cannot %s %s\n", (oseek?"open":"create"), ofile);
exit();
}
if(bs)
{
ibs = obs = bs;
}
if(ibs == obs && conv == null)
fflag++;
if(ibs == 0 || obs == 0)
{
printf("counts: cannot be zero\n");
exit();
}
if(iseek)
{
offset = iseek;
offset = offset*ibs;
lseek(ibf, offset, 0);
}
if(oseek)
{
offset = oseek;
offset = offset*obs;
lseek(obf, offset, 0);
}
ibuf = sbrk(ibs);
if(fflag)
obuf = ibuf;
else
obuf = sbrk(obs);
if(ibuf == -1 || obuf == -1)
{
printf("not enough memory\n");
exit();
}
ibc = 0;
obc = 0;
cbc = 0;
op = obuf;
if((signal(2, 1) & 01) == 0)
signal(2, term);
while(skip)
{
read(ibf, ibuf, ibs);
skip--;
}
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)
{
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++;
(*conv)(c);
goto loop;
}
flsh()
{
register c;
if(obc)
{
if(obc == obs)
nofr++;
else
nopr++;
c = write(obf, obuf, obc);
if(c != obc)
{
perror("write");
term();
}
obc = 0;
}
}
match(s)
char *s;
{
register char *cs;
cs = string;
while(*cs++ == *s)
if(*s++ == '\0')
goto true;
if(*s != '\0')
return(0);
true:
cs--;
string = cs;
return(1);
}
number()
{
register char *cs;
register 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 =* 2;
continue;
case 'b':
n =* 512;
continue;
case '*':
case 'x':
string = cs;
n =* number();
case '\0':
return(n);
}
printf("not a number: %s\n", string);
exit();
}
cnull(cc)
{
register 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);
}
null(c)
{
*op = c;
op++;
if(++obc >= obs)
{
flsh();
op = obuf;
}
}
ascii(cc)
{
register c;
c = 0;
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;
}
}
ebcdic(cc)
{
register 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] & 0377;
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);
}
term()
{
stats();
exit();
}
stats()
{
printf("%l+%l records in\n", nifr, nipr);
printf("%l+%l records out\n", nofr, nopr);
if(ntrunc)
printf("%l truncated records\n", ntrunc);
}
putchar(c)
{
write(2, &c, 1);
}