add first WEGA commands
This commit is contained in:
parent
38593e202f
commit
dc4c1a9442
|
|
@ -0,0 +1,643 @@
|
||||||
|
/* WEGA P8000 'dump' Version 25.11.87 */
|
||||||
|
#define NI 16
|
||||||
|
#define DIRPB (BSIZE/sizeof(struct direct))
|
||||||
|
#define SEC 1
|
||||||
|
|
||||||
|
#include <sgtty.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/fblk.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <dumprestor.h> /* NTREC = 8 */
|
||||||
|
|
||||||
|
#define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
|
||||||
|
#define MBIT(i) (1<<((unsigned)(i-1)%MLEN))
|
||||||
|
#define BIS(i,w) (MWORD(w,i) |= MBIT(i))
|
||||||
|
#define BIC(i,w) (MWORD(w,i) &= ~MBIT(i))
|
||||||
|
#define BIT(i,w) (MWORD(w,i) & MBIT(i))
|
||||||
|
|
||||||
|
struct filsys sblock;
|
||||||
|
struct dinode itab[INOPB*NI];
|
||||||
|
short clrmap[MSIZ], dirmap[MSIZ], nodmap[MSIZ];
|
||||||
|
|
||||||
|
char *hdisk, *archiv, *increm;
|
||||||
|
char incno;
|
||||||
|
int uflag, dflag, fi, to;
|
||||||
|
ino_t ino;
|
||||||
|
int nsubdir, narchiv, nadded, dadded;
|
||||||
|
int density = 160;
|
||||||
|
int timeout;
|
||||||
|
|
||||||
|
char *ctime(), *prdate();
|
||||||
|
long atol();
|
||||||
|
int archivn, BLOCKS;
|
||||||
|
long tsize, esize, asize;
|
||||||
|
int mark(), add(), dump(), tapsrec();
|
||||||
|
int dmpspc(), dsrch(), nullf();
|
||||||
|
|
||||||
|
#define HOUR (60L*60L)
|
||||||
|
#define DAY (24L*HOUR)
|
||||||
|
#define YEAR (365L*DAY)
|
||||||
|
|
||||||
|
/* default: Disk.-Drive 1, cpi 96, double-sided, 9 sector */
|
||||||
|
/* Typ 6 = rfd196ds9 (Blocklaenge : 512 Byte ) */
|
||||||
|
/* (Blockanzahl : 1440 ) */
|
||||||
|
|
||||||
|
main(argc, argv)
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
char *arg;
|
||||||
|
register i;
|
||||||
|
|
||||||
|
time(&spcl.c_date);
|
||||||
|
|
||||||
|
tsize = 2300L*12L*10L;
|
||||||
|
archiv = "/dev/dumpdev"; /* default: dump-Ziel dumpdev (rfd1) */
|
||||||
|
hdisk = "/dev/rz"; /* default: dump-Quelle rz (rmd4) */
|
||||||
|
increm = "/etc/ddate";
|
||||||
|
incno = '9'; /* default: dump-level 0 */
|
||||||
|
uflag = 0;
|
||||||
|
arg = "u"; /* default: Datum eintragen */
|
||||||
|
if(argc > 1) {
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
arg = *argv; }
|
||||||
|
while(*arg)
|
||||||
|
switch (*arg++) {
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
if(argc > 1) {
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
archiv = *argv; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
dflag++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
if(argc > 1) {
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
tsize = atol(*argv);
|
||||||
|
tsize *= 12L*10L; }
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
incno = arg[-1];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
uflag++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("bad key '%c%'\n", arg[-1]);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argc > 1) {
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
hdisk = *argv; }
|
||||||
|
|
||||||
|
if (dflag) printf("dump: Version 25.11.87\n");
|
||||||
|
|
||||||
|
getitime();
|
||||||
|
printf(" date = %s\n", prdate(spcl.c_date));
|
||||||
|
printf("dump date = %s\n", prdate(spcl.c_ddate));
|
||||||
|
printf("dumping %s to %s\n", hdisk, archiv);
|
||||||
|
fi = open(hdisk, 0);
|
||||||
|
if(fi < 0) {
|
||||||
|
printf("dump: cannot open %s\n", hdisk);
|
||||||
|
exit(1); }
|
||||||
|
oarchiv();
|
||||||
|
printf("I\n");
|
||||||
|
esize = 0;
|
||||||
|
CLR(clrmap);
|
||||||
|
CLR(dirmap);
|
||||||
|
CLR(nodmap);
|
||||||
|
|
||||||
|
pass(mark, (short *)NULL);
|
||||||
|
do {
|
||||||
|
printf("II\n");
|
||||||
|
nadded = 0;
|
||||||
|
pass(add, dirmap);
|
||||||
|
} while(nadded);
|
||||||
|
|
||||||
|
bmapest(clrmap);
|
||||||
|
bmapest(nodmap);
|
||||||
|
if (BLOCKS) printf("estimated %D disk blocks on %d disk",
|
||||||
|
esize, archivn = (int)(esize/BLOCKS)+1);
|
||||||
|
else printf("estimated %D archiv blocks on %d archiv",
|
||||||
|
esize, archivn = (int)(esize/tsize)+1);
|
||||||
|
if (archivn > 1) printf("s");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
printf("III\n");
|
||||||
|
bitmap(clrmap, TS_CLRI);
|
||||||
|
pass(dump, dirmap);
|
||||||
|
printf("IV\n");
|
||||||
|
pass(dump, nodmap);
|
||||||
|
putitime();
|
||||||
|
printf("DONE\n");
|
||||||
|
spcl.c_type = TS_END;
|
||||||
|
for(i=0; i<NTREC; i++)
|
||||||
|
spclrec();
|
||||||
|
printf("%D ", asize/4+(spcl.c_volume-1)*BLOCKS); /* original: spcl.c_tapea); */
|
||||||
|
printad();
|
||||||
|
printf("blocks on ");
|
||||||
|
printf("%d ", spcl.c_volume);
|
||||||
|
printad();
|
||||||
|
if (spcl.c_volume > 1) printf("s");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printad()
|
||||||
|
{
|
||||||
|
if (BLOCKS) printf("disk");
|
||||||
|
else printf("archiv");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hole BLOCKS ueber ioctl() */
|
||||||
|
inBL()
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
if (i=ioctl(to,SHOWFD,&BLOCKS)) BLOCKS = 0;
|
||||||
|
if (dflag && BLOCKS) fprintf(stderr, "tar: disk capacity %d blocks\n", BLOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
printf("dump: usage dump [Lufs] [archivdev] [archivsize] [filesystem]\n");
|
||||||
|
printf(" Level\(0,...,9\) _/ || \\_ set archiv size\n");
|
||||||
|
printf(" update __/ \\__ give archiv device\n");
|
||||||
|
exit(1); }
|
||||||
|
|
||||||
|
pass(fn, map)
|
||||||
|
int (*fn)();
|
||||||
|
short *map;
|
||||||
|
{
|
||||||
|
register i, j;
|
||||||
|
int bits;
|
||||||
|
ino_t mino;
|
||||||
|
daddr_t d;
|
||||||
|
|
||||||
|
sync();
|
||||||
|
bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
|
||||||
|
mino = (sblock.s_isize-2) * INOPB;
|
||||||
|
ino = 0;
|
||||||
|
for(i=2;; i+=NI) {
|
||||||
|
if(ino >= mino)
|
||||||
|
break;
|
||||||
|
d = (unsigned)i;
|
||||||
|
for(j=0; j<INOPB*NI; j++) {
|
||||||
|
if(ino >= mino)
|
||||||
|
break;
|
||||||
|
if((ino % MLEN) == 0) {
|
||||||
|
bits = ~0;
|
||||||
|
if(map != NULL) bits = *map++; }
|
||||||
|
ino++;
|
||||||
|
if(bits & 1) {
|
||||||
|
if(d != 0) {
|
||||||
|
bread(d, (char *)itab, sizeof(itab));
|
||||||
|
d = 0; }
|
||||||
|
(*fn)(&itab[j]); }
|
||||||
|
bits >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
icat(ip, fn1, fn2)
|
||||||
|
struct dinode *ip;
|
||||||
|
int (*fn1)(), (*fn2)();
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
daddr_t d[NADDR];
|
||||||
|
|
||||||
|
l3tol(&d[0], &ip->di_addr[0], NADDR);
|
||||||
|
(*fn2)(d, NADDR-3);
|
||||||
|
for(i=0; i<NADDR; i++) {
|
||||||
|
if(d[i] != 0) {
|
||||||
|
if(i < NADDR-3)
|
||||||
|
(*fn1)(d[i]); else
|
||||||
|
indir(d[i], fn1, fn2, i-(NADDR-3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
indir(d, fn1, fn2, n)
|
||||||
|
daddr_t d;
|
||||||
|
int (*fn1)(), (*fn2)();
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
daddr_t idblk[NINDIR];
|
||||||
|
|
||||||
|
bread(d, (char *)idblk, sizeof(idblk));
|
||||||
|
if(n <= 0) {
|
||||||
|
spcl.c_type = TS_ADDR;
|
||||||
|
(*fn2)(idblk, NINDIR);
|
||||||
|
for(i=0; i<NINDIR; i++) {
|
||||||
|
d = idblk[i];
|
||||||
|
if(d != 0)
|
||||||
|
(*fn1)(d); } }
|
||||||
|
else {
|
||||||
|
n--;
|
||||||
|
for(i=0; i<NINDIR; i++) {
|
||||||
|
d = idblk[i];
|
||||||
|
if(d != 0) indir(d, fn1, fn2, n); } }
|
||||||
|
}
|
||||||
|
|
||||||
|
mark(ip)
|
||||||
|
struct dinode *ip;
|
||||||
|
{
|
||||||
|
register f;
|
||||||
|
|
||||||
|
f = ip->di_mode & IFMT;
|
||||||
|
if(f == 0)
|
||||||
|
return;
|
||||||
|
BIS(ino, clrmap);
|
||||||
|
if(f == IFDIR)
|
||||||
|
BIS(ino, dirmap);
|
||||||
|
if(ip->di_mtime >= spcl.c_ddate ||
|
||||||
|
ip->di_ctime >= spcl.c_ddate) {
|
||||||
|
BIS(ino, nodmap);
|
||||||
|
if (f != IFREG)
|
||||||
|
return;
|
||||||
|
est(ip); }
|
||||||
|
}
|
||||||
|
|
||||||
|
add(ip)
|
||||||
|
struct dinode *ip;
|
||||||
|
{
|
||||||
|
|
||||||
|
if(BIT(ino, nodmap))
|
||||||
|
return;
|
||||||
|
nsubdir = 0;
|
||||||
|
dadded = 0;
|
||||||
|
icat(ip, dsrch, nullf);
|
||||||
|
if(dadded) {
|
||||||
|
BIS(ino, nodmap);
|
||||||
|
est(ip);
|
||||||
|
nadded++; }
|
||||||
|
if(nsubdir == 0)
|
||||||
|
if(!BIT(ino, nodmap))
|
||||||
|
BIC(ino, dirmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
dump(ip)
|
||||||
|
struct dinode *ip;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
if(narchiv) {
|
||||||
|
narchiv = 0;
|
||||||
|
bitmap(nodmap, TS_BITS); }
|
||||||
|
BIC(ino, nodmap);
|
||||||
|
spcl.c_dinode = *ip;
|
||||||
|
spcl.c_type = TS_INODE;
|
||||||
|
spcl.c_count = 0;
|
||||||
|
i = ip->di_mode & IFMT;
|
||||||
|
if(i != IFDIR && i != IFREG) {
|
||||||
|
spclrec();
|
||||||
|
return; }
|
||||||
|
icat(ip, tapsrec, dmpspc);
|
||||||
|
}
|
||||||
|
|
||||||
|
dmpspc(dp, n)
|
||||||
|
daddr_t *dp;
|
||||||
|
{
|
||||||
|
register i, t;
|
||||||
|
|
||||||
|
spcl.c_count = n;
|
||||||
|
for(i=0; i<n; i++) {
|
||||||
|
t = 0;
|
||||||
|
if(dp[i] != 0)
|
||||||
|
t++;
|
||||||
|
spcl.c_block.c_addr[i] = t; }
|
||||||
|
spclrec();
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap(map, typ)
|
||||||
|
short *map;
|
||||||
|
{
|
||||||
|
register i, n;
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
n = -1;
|
||||||
|
for(i=0; i<MSIZ; i++)
|
||||||
|
if(map[i])
|
||||||
|
n = i;
|
||||||
|
if(n < 0)
|
||||||
|
return;
|
||||||
|
spcl.c_type = typ;
|
||||||
|
spcl.c_count = (n*sizeof(map[0]) + BSIZE)/BSIZE;
|
||||||
|
spclrec();
|
||||||
|
cp = (char *)map;
|
||||||
|
for(i=0; i<spcl.c_count; i++) {
|
||||||
|
if (dflag == 2) printf("bitmap -> ");
|
||||||
|
taprec(cp);
|
||||||
|
cp += BSIZE; }
|
||||||
|
}
|
||||||
|
|
||||||
|
spclrec()
|
||||||
|
{
|
||||||
|
register i, *ip, s;
|
||||||
|
|
||||||
|
spcl.c_inumber = ino;
|
||||||
|
spcl.c_magic = MAGIC;
|
||||||
|
spcl.c_checksum = 0;
|
||||||
|
ip = (int *)&spcl;
|
||||||
|
s = 0;
|
||||||
|
for(i=0; i<BSIZE/sizeof(*ip); i++)
|
||||||
|
s += *ip++;
|
||||||
|
spcl.c_checksum = CHECKSUM - s;
|
||||||
|
if (dflag == 2) printf("spclrec -> ");
|
||||||
|
taprec((char *)&spcl);
|
||||||
|
}
|
||||||
|
|
||||||
|
dsrch(d)
|
||||||
|
daddr_t d;
|
||||||
|
{
|
||||||
|
register char *cp;
|
||||||
|
register i;
|
||||||
|
register ino_t in;
|
||||||
|
struct direct dblk[DIRPB];
|
||||||
|
|
||||||
|
if(dadded)
|
||||||
|
return;
|
||||||
|
bread(d, (char *)dblk, sizeof(dblk));
|
||||||
|
for(i=0; i<DIRPB; i++) {
|
||||||
|
in = dblk[i].d_ino;
|
||||||
|
if(in == 0) continue;
|
||||||
|
cp = dblk[i].d_name;
|
||||||
|
if(cp[0] == '.') {
|
||||||
|
if(cp[1] == '\0')
|
||||||
|
continue;
|
||||||
|
if(cp[1] == '.' && cp[2] == '\0')
|
||||||
|
continue; }
|
||||||
|
if(BIT(in, nodmap)) {
|
||||||
|
dadded++;
|
||||||
|
return; }
|
||||||
|
if(BIT(in, dirmap))
|
||||||
|
nsubdir++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nullf()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bread(da, ba, c)
|
||||||
|
daddr_t da;
|
||||||
|
char *ba;
|
||||||
|
{
|
||||||
|
register n;
|
||||||
|
|
||||||
|
lseek(fi, da*512, 0);
|
||||||
|
n = read(fi, ba, c);
|
||||||
|
if(n != c)
|
||||||
|
printf("asked %d; got %d\n", c, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLR(map)
|
||||||
|
register short *map;
|
||||||
|
{
|
||||||
|
register n;
|
||||||
|
|
||||||
|
n = MSIZ;
|
||||||
|
do
|
||||||
|
*map++ = 0;
|
||||||
|
while(--n);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char tblock[NTREC][BSIZE];
|
||||||
|
daddr_t tdaddr[NTREC];
|
||||||
|
int trecno;
|
||||||
|
|
||||||
|
taprec(dp)
|
||||||
|
char *dp;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
for(i=0; i<BSIZE; i++)
|
||||||
|
tblock[trecno][i] = *dp++;
|
||||||
|
tdaddr[trecno] = 0;
|
||||||
|
trecno++;
|
||||||
|
spcl.c_tapea++;
|
||||||
|
if (dflag == 2) printf("taprec\n");
|
||||||
|
if(trecno >= NTREC) flusht();
|
||||||
|
}
|
||||||
|
|
||||||
|
tapsrec(d)
|
||||||
|
daddr_t d;
|
||||||
|
{
|
||||||
|
|
||||||
|
if(d == 0)
|
||||||
|
return;
|
||||||
|
tdaddr[trecno] = d;
|
||||||
|
trecno++;
|
||||||
|
spcl.c_tapea++;
|
||||||
|
if (dflag == 2) printf("tapsrec");
|
||||||
|
if (dflag == 2 && trecno >= NTREC) printf("\n");
|
||||||
|
if (dflag == 2 && trecno < NTREC) printf("; ");
|
||||||
|
if(trecno >= NTREC) flusht();
|
||||||
|
}
|
||||||
|
|
||||||
|
flusht()
|
||||||
|
{
|
||||||
|
int time_out();
|
||||||
|
char place[100];
|
||||||
|
register i, si;
|
||||||
|
daddr_t d;
|
||||||
|
|
||||||
|
while(trecno < NTREC)
|
||||||
|
tdaddr[trecno++] = 1;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
d = 0;
|
||||||
|
for(i=0; i<NTREC; i++)
|
||||||
|
if(tdaddr[i] != 0)
|
||||||
|
if(d == 0 || tdaddr[i] < d) {
|
||||||
|
si = i;
|
||||||
|
d = tdaddr[i]; }
|
||||||
|
if(d != 0) {
|
||||||
|
bread(d, tblock[si], BSIZE);
|
||||||
|
tdaddr[si] = 0;
|
||||||
|
goto loop; }
|
||||||
|
trecno = 0;
|
||||||
|
if (dflag == 2) printf("flusht: schreibe Block %D bis %D\n",asize/4,asize/4+7);
|
||||||
|
write(to, tblock[0], sizeof(tblock));
|
||||||
|
asize += sizeof(tblock)/density;
|
||||||
|
asize += 7;
|
||||||
|
if(asize+sizeof(tblock)/density+7 > tsize) {
|
||||||
|
close(to);
|
||||||
|
signal(SIGALRM,time_out);
|
||||||
|
timeout=0;
|
||||||
|
alarm(SEC);
|
||||||
|
while (!timeout) getchar();
|
||||||
|
alarm(0);
|
||||||
|
if (BLOCKS) printf("insert disk %d: ",spcl.c_volume+1);
|
||||||
|
else printf("change archiv : ");
|
||||||
|
read(0, place, sizeof(place));
|
||||||
|
oarchiv(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
time_out()
|
||||||
|
{
|
||||||
|
signal(SIGALRM,time_out);
|
||||||
|
timeout++;
|
||||||
|
}
|
||||||
|
|
||||||
|
oarchiv()
|
||||||
|
{
|
||||||
|
|
||||||
|
nonex1:
|
||||||
|
if ((to = open(archiv, 1)) < 0) {
|
||||||
|
printf("dump: cannot open %s\n", archiv);
|
||||||
|
if (strcmp(archiv,"/dev/dumpdev") == 0) {
|
||||||
|
archiv = "/dev/rfd1";
|
||||||
|
printf("dump: tries open %s\n", archiv);
|
||||||
|
goto nonex1; }
|
||||||
|
exit(1); }
|
||||||
|
inBL();
|
||||||
|
if (BLOCKS) tsize = BLOCKS * 4;
|
||||||
|
asize = 0;
|
||||||
|
narchiv++;
|
||||||
|
spcl.c_volume++;
|
||||||
|
spcl.c_type = TS_TAPE;
|
||||||
|
spclrec();
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
prdate(d)
|
||||||
|
time_t d;
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if(d == 0)
|
||||||
|
return("the epoch");
|
||||||
|
p = ctime(&d);
|
||||||
|
p[24] = 0;
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
getitime()
|
||||||
|
{
|
||||||
|
register i, df;
|
||||||
|
struct idates idbuf;
|
||||||
|
char *fname;
|
||||||
|
|
||||||
|
fname = hdisk;
|
||||||
|
l1:
|
||||||
|
for(i=0; fname[i]; i++)
|
||||||
|
if(fname[i] == '/') {
|
||||||
|
fname += i+1;
|
||||||
|
goto l1; }
|
||||||
|
|
||||||
|
spcl.c_ddate = 0;
|
||||||
|
|
||||||
|
if ((df = open(increm, 2)) < 0) {
|
||||||
|
if ((df = creat(increm, 0600)) < 0) {
|
||||||
|
printf("dump: cannot open %s\n", increm);
|
||||||
|
printf(" You are superuser ???\n");
|
||||||
|
exit(1); } }
|
||||||
|
|
||||||
|
l2:
|
||||||
|
i = read(df, (char *)&idbuf, sizeof(idbuf));
|
||||||
|
if(i != sizeof(idbuf)) {
|
||||||
|
close(df);
|
||||||
|
return; }
|
||||||
|
for(i=0;; i++) {
|
||||||
|
if(fname[i] != idbuf.id_name[i]) goto l2;
|
||||||
|
if(fname[i] == '\0') break; }
|
||||||
|
if(idbuf.id_incno >= incno) goto l2;
|
||||||
|
if(idbuf.id_ddate <= spcl.c_ddate) goto l2;
|
||||||
|
spcl.c_ddate = idbuf.id_ddate;
|
||||||
|
goto l2;
|
||||||
|
}
|
||||||
|
|
||||||
|
putitime()
|
||||||
|
{
|
||||||
|
register i, n, df;
|
||||||
|
struct idates idbuf;
|
||||||
|
char *fname;
|
||||||
|
|
||||||
|
if(uflag == 0)
|
||||||
|
return;
|
||||||
|
fname = hdisk;
|
||||||
|
l1:
|
||||||
|
for(i=0; fname[i]; i++)
|
||||||
|
if(fname[i] == '/') {
|
||||||
|
fname += i+1;
|
||||||
|
goto l1; }
|
||||||
|
|
||||||
|
spcl.c_ddate = 0;
|
||||||
|
df = open(increm, 2);
|
||||||
|
if(df < 0) {
|
||||||
|
printf("cannot open %s\n", increm);
|
||||||
|
exit(1); }
|
||||||
|
n = 0;
|
||||||
|
l2:
|
||||||
|
i = read(df, (char *)&idbuf, sizeof(idbuf));
|
||||||
|
if(i != sizeof(idbuf)) goto l3;
|
||||||
|
n++;
|
||||||
|
for(i=0;; i++) {
|
||||||
|
if(fname[i] != idbuf.id_name[i]) goto l2;
|
||||||
|
if(fname[i] == '\0') break; }
|
||||||
|
if(idbuf.id_incno != incno) goto l2;
|
||||||
|
l3:
|
||||||
|
lseek(df, (long)n*sizeof(idbuf), 0);
|
||||||
|
for(i=0;; i++) {
|
||||||
|
idbuf.id_name[i] = fname[i];
|
||||||
|
if(fname[i] == '\0')
|
||||||
|
break; }
|
||||||
|
idbuf.id_incno = incno;
|
||||||
|
idbuf.id_ddate = spcl.c_date;
|
||||||
|
write(df, (char *)&idbuf, sizeof(idbuf));
|
||||||
|
close(df);
|
||||||
|
printf("level %c dump on %s\n", incno, prdate(spcl.c_date));
|
||||||
|
}
|
||||||
|
|
||||||
|
est(ip)
|
||||||
|
struct dinode *ip;
|
||||||
|
{
|
||||||
|
long s;
|
||||||
|
|
||||||
|
esize++;
|
||||||
|
s = (ip->di_size + BSIZE-1) / BSIZE;
|
||||||
|
esize += s;
|
||||||
|
if(s > NADDR-3) {
|
||||||
|
s -= NADDR-3;
|
||||||
|
s = (s + (BSIZE/sizeof(daddr_t))-1) / (BSIZE/sizeof(daddr_t));
|
||||||
|
esize += s; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bmapest(map)
|
||||||
|
short *map;
|
||||||
|
{
|
||||||
|
register i, n;
|
||||||
|
|
||||||
|
n = -1;
|
||||||
|
for(i=0; i<MSIZ; i++)
|
||||||
|
if(map[i])
|
||||||
|
n = i;
|
||||||
|
if(n < 0)
|
||||||
|
return;
|
||||||
|
esize++;
|
||||||
|
esize += (n + (BSIZE/sizeof(short))-1) / (BSIZE/sizeof(short));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,470 @@
|
||||||
|
/* WEGA P8000 'dumpdir' 1.Version (6.11.87) */
|
||||||
|
#define MAXINO 3000
|
||||||
|
#define BITS 8
|
||||||
|
#define MAXXTR 60
|
||||||
|
#define NCACHE 3
|
||||||
|
|
||||||
|
#include <sgtty.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/inode.h>
|
||||||
|
#include <sys/ino.h>
|
||||||
|
#include <sys/fblk.h>
|
||||||
|
#include <sys/filsys.h>
|
||||||
|
#include <sys/dir.h>
|
||||||
|
#include <dumprestor.h>
|
||||||
|
|
||||||
|
#define MWORD(m,i) (m[(unsigned)(i-1)/MLEN])
|
||||||
|
#define MBIT(i) (1<<((unsigned)(i-1)%MLEN))
|
||||||
|
#define BIS(i,w) (MWORD(w,i) |= MBIT(i))
|
||||||
|
#define BIC(i,w) (MWORD(w,i) &= ~MBIT(i))
|
||||||
|
#define BIT(i,w) (MWORD(w,i) & MBIT(i))
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
char archiv[] = "/dev/dumpdev";
|
||||||
|
char devrfd1[] = "/dev/rfd1";
|
||||||
|
char *readfrom = archiv;
|
||||||
|
|
||||||
|
daddr_t seekpt;
|
||||||
|
int ofile;
|
||||||
|
FILE *df;
|
||||||
|
char dirfile[] = "rstXXXXXX";
|
||||||
|
|
||||||
|
struct {
|
||||||
|
ino_t t_ino;
|
||||||
|
daddr_t t_seekpt;
|
||||||
|
} inotab[MAXINO];
|
||||||
|
int ipos;
|
||||||
|
|
||||||
|
#define ONTAPE 1
|
||||||
|
#define XTRACTD 2
|
||||||
|
#define XINUSE 4
|
||||||
|
|
||||||
|
short dumpmap[MSIZ]; /* MSIZ = 4096 */
|
||||||
|
short clrimap[MSIZ];
|
||||||
|
|
||||||
|
|
||||||
|
int bct = NTREC+1;
|
||||||
|
char tbf[NTREC*BSIZE];
|
||||||
|
|
||||||
|
char prebuf[512];
|
||||||
|
|
||||||
|
int dflag;
|
||||||
|
int BLOCKS, nblock;
|
||||||
|
int volno = 1;
|
||||||
|
|
||||||
|
main(argc, argv)
|
||||||
|
char *argv[];
|
||||||
|
{
|
||||||
|
register char *cp;
|
||||||
|
extern char *ctime();
|
||||||
|
|
||||||
|
mktemp(dirfile);
|
||||||
|
argv++;
|
||||||
|
if (argc >= 2) {
|
||||||
|
argc -= 2;
|
||||||
|
for (cp = *argv++; *cp; cp++) {
|
||||||
|
switch (*cp) {
|
||||||
|
case 'd':
|
||||||
|
dflag++;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
readfrom = *argv++;
|
||||||
|
argc--;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("bad key '%c%'\n", *cp);
|
||||||
|
usage(); } } }
|
||||||
|
|
||||||
|
if (dflag) printf("dumpdir: Version 6.11.87\n");
|
||||||
|
|
||||||
|
nonex:
|
||||||
|
if ((fd = open(readfrom, 0)) < 0) {
|
||||||
|
printf("dumpdir: cannot open %s\n", readfrom);
|
||||||
|
if (strcmp(readfrom,archiv) == 0) {
|
||||||
|
readfrom = devrfd1;
|
||||||
|
printf("dumpdir: tries open %s\n", readfrom);
|
||||||
|
goto nonex; }
|
||||||
|
exit(1); }
|
||||||
|
inBL();
|
||||||
|
|
||||||
|
if (readhdr(&spcl) == 0) {
|
||||||
|
printf("Not a dump-archiv\n");
|
||||||
|
exit(1); }
|
||||||
|
|
||||||
|
df = fopen(dirfile, "w");
|
||||||
|
if (df == NULL) {
|
||||||
|
printf("dumpdir: %s - cannot create directory temporary\n", dirfile);
|
||||||
|
exit(1); }
|
||||||
|
|
||||||
|
printf("Dump date: %s", ctime(&spcl.c_date));
|
||||||
|
printf("Dumped from: %s", ctime(&spcl.c_ddate));
|
||||||
|
if (checkvol(&spcl, 1) == 0) {
|
||||||
|
printf("Tape is not volume 1 of the dump\n");
|
||||||
|
exit(1); }
|
||||||
|
pass1(); /* This sets the various maps on the way by */
|
||||||
|
freopen(dirfile, "r", df);
|
||||||
|
strcpy(prebuf, "/");
|
||||||
|
printem(prebuf, (ino_t) 2);
|
||||||
|
unlink(dirfile);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
printf("dumpdir: usage dumpdir [f archivdev]\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hole BLOCKS ueber ioctl() */
|
||||||
|
inBL()
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
if (i=ioctl(fd,SHOWFD,&BLOCKS)) BLOCKS = 0;
|
||||||
|
if (dflag && BLOCKS) fprintf(stderr, "tar: disk capacity %d blocks\n", BLOCKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the archiv, bulding up a directory structure for extraction
|
||||||
|
* by name
|
||||||
|
*/
|
||||||
|
pass1()
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
struct dinode *ip;
|
||||||
|
int putdir(), null();
|
||||||
|
|
||||||
|
while (gethead(&spcl) == 0) {
|
||||||
|
printf("Can't find directory header!\n"); }
|
||||||
|
for (;;) {
|
||||||
|
if (checktype(&spcl, TS_BITS) == 1) {
|
||||||
|
readbits(dumpmap);
|
||||||
|
continue; }
|
||||||
|
if (checktype(&spcl, TS_CLRI) == 1) {
|
||||||
|
readbits(clrimap);
|
||||||
|
continue; }
|
||||||
|
if (checktype(&spcl, TS_INODE) == 0) {
|
||||||
|
finish:
|
||||||
|
fflush(df);
|
||||||
|
close(fd);
|
||||||
|
return; }
|
||||||
|
ip = &spcl.c_dinode;
|
||||||
|
i = ip->di_mode & IFMT;
|
||||||
|
if (i != IFDIR) goto finish;
|
||||||
|
inotab[ipos].t_ino = spcl.c_inumber;
|
||||||
|
inotab[ipos++].t_seekpt = seekpt;
|
||||||
|
getfile(spcl.c_inumber, putdir, null, spcl.c_dinode.di_size);
|
||||||
|
putent("\000\000/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printem(prefix, inum)
|
||||||
|
char *prefix;
|
||||||
|
ino_t inum;
|
||||||
|
{
|
||||||
|
struct direct dir;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXINO; i++)
|
||||||
|
if (inotab[i].t_ino == inum) goto found;
|
||||||
|
printf("PANIC - can't find directory %d\n", inum);
|
||||||
|
return;
|
||||||
|
found:
|
||||||
|
mseek(inotab[i].t_seekpt);
|
||||||
|
for (;;) {
|
||||||
|
getent((char *) &dir);
|
||||||
|
if (direq(dir.d_name, "/"))
|
||||||
|
return;
|
||||||
|
if (search(dir.d_ino) != 0 &&
|
||||||
|
direq(dir.d_name, ".") == 0 &&
|
||||||
|
direq(dir.d_name, "..") == 0) {
|
||||||
|
int len;
|
||||||
|
FILE *tdf;
|
||||||
|
|
||||||
|
tdf = df;
|
||||||
|
df = fopen(dirfile, "r");
|
||||||
|
len = strlen(prefix);
|
||||||
|
strncat(prefix, dir.d_name, sizeof(dir.d_name));
|
||||||
|
strcat(prefix, "/");
|
||||||
|
printem(prefix, dir.d_ino);
|
||||||
|
prefix[len] = '\0';
|
||||||
|
fclose(df);
|
||||||
|
df = tdf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (BIT(dir.d_ino, dumpmap))
|
||||||
|
printf("%5d %s%-.14s\n", dir.d_ino, prefix, dir.d_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Do the file extraction, calling the supplied functions
|
||||||
|
* with the blocks
|
||||||
|
*/
|
||||||
|
getfile(n, f1, f2, size)
|
||||||
|
ino_t n;
|
||||||
|
int (*f2)(), (*f1)();
|
||||||
|
long size;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
struct spcl addrbl;
|
||||||
|
char buf[BSIZE];
|
||||||
|
|
||||||
|
addrbl = spcl;
|
||||||
|
goto start;
|
||||||
|
for (;;) {
|
||||||
|
if (gethead(&addrbl) == 0) {
|
||||||
|
printf("Missing address (header) block\n");
|
||||||
|
goto eloop; }
|
||||||
|
if (checktype(&addrbl, TS_ADDR) == 0) {
|
||||||
|
spcl = addrbl;
|
||||||
|
return; }
|
||||||
|
start:
|
||||||
|
for (i = 0; i < addrbl.c_count; i++) {
|
||||||
|
if (addrbl.c_block.c_addr[i]) {
|
||||||
|
readarchiv(buf);
|
||||||
|
(*f1)(buf, size > BSIZE ? (long) BSIZE : size); }
|
||||||
|
else {
|
||||||
|
clearbuf(buf);
|
||||||
|
(*f2)(buf, size > BSIZE ? (long) BSIZE : size); }
|
||||||
|
if ((size -= BSIZE) <= 0) {
|
||||||
|
eloop:
|
||||||
|
while (gethead(&spcl) == 0) ;
|
||||||
|
if (checktype(&spcl, TS_ADDR) == 1)
|
||||||
|
goto eloop;
|
||||||
|
return; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the archiv i\/o, dealling with volume changes
|
||||||
|
* etc..
|
||||||
|
*/
|
||||||
|
readarchiv(b)
|
||||||
|
char *b;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
struct spcl tmpbuf;
|
||||||
|
|
||||||
|
if (bct >= NTREC) {
|
||||||
|
for (i = 0; i < NTREC; i++)
|
||||||
|
((struct spcl *)&tbf[i*BSIZE])->c_magic = 0;
|
||||||
|
bct = 0;
|
||||||
|
if (BLOCKS && nblock < BLOCKS)
|
||||||
|
if ((i = read(fd, tbf, NTREC*BSIZE)) < 0) exit(1);
|
||||||
|
if (dflag > 1 && BLOCKS) printf("Ich las Block %d bis %d\n",nblock*NTREC,(nblock+1)*NTREC-1);
|
||||||
|
nblock++;
|
||||||
|
if (i == 0 || (BLOCKS && nblock > BLOCKS)) {
|
||||||
|
bct = NTREC+1;
|
||||||
|
volno++;
|
||||||
|
loop:
|
||||||
|
bct = NTREC+1; /* ehemals: flsht(); */
|
||||||
|
close(fd);
|
||||||
|
nblock = 0;
|
||||||
|
if (BLOCKS) printf("insert disk %d : ",volno);
|
||||||
|
else printf("change archiv %d : ", volno);
|
||||||
|
while (getchar() != '\n') ;
|
||||||
|
if ((fd = open(readfrom, 0)) == -1)
|
||||||
|
printf("Cannot open archiv!\n");
|
||||||
|
if (readhdr(&tmpbuf) == 0) {
|
||||||
|
printf("Not a dump-archiv. Try again\n");
|
||||||
|
goto loop; }
|
||||||
|
if (checkvol(&tmpbuf, volno) == 0) {
|
||||||
|
printf("Wrong archiv. Try again\n");
|
||||||
|
goto loop; }
|
||||||
|
readarchiv(b);
|
||||||
|
return; }
|
||||||
|
}
|
||||||
|
copy(&tbf[(bct++*BSIZE)], b, BSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
copy(f, t, s)
|
||||||
|
register char *f, *t;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
i = s;
|
||||||
|
do *t++ = *f++; while (--i);
|
||||||
|
}
|
||||||
|
|
||||||
|
clearbuf(cp)
|
||||||
|
register char *cp;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
i = BSIZE;
|
||||||
|
do *cp++ = 0; while (--i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put and get the directory entries from the compressed
|
||||||
|
* directory file
|
||||||
|
*/
|
||||||
|
putent(cp)
|
||||||
|
char *cp;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ino_t); i++)
|
||||||
|
writec(*cp++);
|
||||||
|
for (i = 0; i < DIRSIZ; i++) {
|
||||||
|
writec(*cp);
|
||||||
|
if (*cp++ == 0) return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
getent(bf)
|
||||||
|
register char *bf;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(ino_t); i++)
|
||||||
|
*bf++ = readc();
|
||||||
|
for (i = 0; i < DIRSIZ; i++)
|
||||||
|
if ((*bf++ = readc()) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read/write te directory file
|
||||||
|
*/
|
||||||
|
writec(c)
|
||||||
|
char c;
|
||||||
|
{
|
||||||
|
seekpt++;
|
||||||
|
fwrite(&c, 1, 1, df);
|
||||||
|
}
|
||||||
|
|
||||||
|
readc()
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
|
||||||
|
fread(&c, 1, 1, df);
|
||||||
|
return(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
mseek(pt)
|
||||||
|
daddr_t pt;
|
||||||
|
{
|
||||||
|
fseek(df, pt, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* search the directory inode ino
|
||||||
|
* looking for entry cp
|
||||||
|
*/
|
||||||
|
search(inum)
|
||||||
|
ino_t inum;
|
||||||
|
{
|
||||||
|
register low, high, probe;
|
||||||
|
|
||||||
|
low = 0;
|
||||||
|
high = ipos-1;
|
||||||
|
|
||||||
|
while (low != high) {
|
||||||
|
probe = (high - low + 1)/2 + low;
|
||||||
|
/*
|
||||||
|
printf("low = %d, high = %d, probe = %d, ino = %d, inum = %d\n", low, high, probe, inum, inotab[probe].t_ino);
|
||||||
|
*/
|
||||||
|
if (inum >= inotab[probe].t_ino)
|
||||||
|
low = probe;
|
||||||
|
else
|
||||||
|
high = probe - 1; }
|
||||||
|
return(inum == inotab[low].t_ino);
|
||||||
|
}
|
||||||
|
|
||||||
|
direq(s1, s2)
|
||||||
|
register char *s1, *s2;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
for (i = 0; i < DIRSIZ; i++)
|
||||||
|
if (*s1++ == *s2) {
|
||||||
|
if (*s2++ == 0)
|
||||||
|
return(1); }
|
||||||
|
else return(0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read the archiv into buf, then return whether or
|
||||||
|
* or not it is a header block.
|
||||||
|
*/
|
||||||
|
gethead(buf)
|
||||||
|
struct spcl *buf;
|
||||||
|
{
|
||||||
|
readarchiv((char *)buf);
|
||||||
|
if (buf->c_magic != MAGIC || checksum((int *) buf) == 0)
|
||||||
|
return(0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return whether or not the buffer contains a header block
|
||||||
|
*/
|
||||||
|
checktype(b, t)
|
||||||
|
struct spcl *b;
|
||||||
|
int t;
|
||||||
|
{
|
||||||
|
return(b->c_type == t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
checksum(b)
|
||||||
|
int *b;
|
||||||
|
{
|
||||||
|
register i, j;
|
||||||
|
|
||||||
|
j = BSIZE/sizeof(int);
|
||||||
|
i = 0;
|
||||||
|
do i += *b++; while (--j);
|
||||||
|
if (i != CHECKSUM) {
|
||||||
|
printf("Checksum error %o\n", i);
|
||||||
|
return(0); }
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkvol(b, t)
|
||||||
|
struct spcl *b;
|
||||||
|
int t;
|
||||||
|
{
|
||||||
|
if (b->c_volume == t) return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
readhdr(b)
|
||||||
|
struct spcl *b;
|
||||||
|
{
|
||||||
|
if (gethead(b) == 0) return(0);
|
||||||
|
if (checktype(b, TS_TAPE) == 0) return(0);
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
putdir(b)
|
||||||
|
char *b;
|
||||||
|
{
|
||||||
|
register struct direct *dp;
|
||||||
|
register i;
|
||||||
|
|
||||||
|
for (dp = (struct direct *)b, i = 0; i < BSIZE; dp++, i += sizeof(*dp)) {
|
||||||
|
if (dp->d_ino == 0)
|
||||||
|
continue;
|
||||||
|
putent((char *) dp); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read a bit mask from the archiv into m.
|
||||||
|
*/
|
||||||
|
readbits(m)
|
||||||
|
short *m;
|
||||||
|
{
|
||||||
|
register i;
|
||||||
|
|
||||||
|
i = spcl.c_count;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
readarchiv((char *) m);
|
||||||
|
m += (BSIZE/(MLEN/BITS)); }
|
||||||
|
while (gethead(&spcl) == 0) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
null() { ; }
|
||||||
|
|
@ -0,0 +1,237 @@
|
||||||
|
/* getud P8000 - Datei Laden von 8-Bit-Teil unter UDOS */
|
||||||
|
|
||||||
|
#define SOH 0x01 /* ascii start-of-header character */
|
||||||
|
#define STX 0x02 /* ascii start-of-text character */
|
||||||
|
#define ETX 0x03 /* ascii end-of-text character */
|
||||||
|
#define EOT 0x04 /* ascii end-of-transmission character */
|
||||||
|
#define ACK 0x06 /* ascii acknowledge character */
|
||||||
|
#define NAK 0x15 /* ascii non-acknowledge character */
|
||||||
|
#define CAN 0x18 /* ascii cancel character (ctrl-x) */
|
||||||
|
#define ESC 0x1b /* ascii escape character */
|
||||||
|
#define RETRIES 3 /* number of allowable transmission errors */
|
||||||
|
#define XFER_SIZE 64 /* max number of characters sent as a block */
|
||||||
|
#define CMODE 0644 /* creation mode for transmitted files */
|
||||||
|
|
||||||
|
#define BINARY 0x01 /* flag byte bit settings */
|
||||||
|
#define FATAL 0x04
|
||||||
|
#define ALLBIN 0x08
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
char bufw[20], bufr[2];
|
||||||
|
int dd, k;
|
||||||
|
|
||||||
|
char c, acknak, checksum, buffer[XFER_SIZE];
|
||||||
|
int high_count, low_count;
|
||||||
|
int i, j, n_to_read, n_written, fd, tflags, success, unsuccess;
|
||||||
|
|
||||||
|
int verbose=0;
|
||||||
|
int del=0;
|
||||||
|
int del_pro();
|
||||||
|
|
||||||
|
char *fname;
|
||||||
|
char flags = 0;
|
||||||
|
|
||||||
|
main (argc, argv)
|
||||||
|
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
signal(SIGINT, del_pro); /* Interrupt-Signal (DEL-Taste) einfangen */
|
||||||
|
signal(SIGHUP, SIG_IGN); /* weitere Signale ignorieren */
|
||||||
|
signal(SIGQUIT,SIG_IGN);
|
||||||
|
signal(SIGILL, SIG_IGN);
|
||||||
|
signal(SIGTRAP,SIG_IGN);
|
||||||
|
signal(SIGIOT, SIG_IGN);
|
||||||
|
signal(SIGSEGV,SIG_IGN);
|
||||||
|
signal(SIGSYS, SIG_IGN);
|
||||||
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
signal(SIGALRM,SIG_IGN);
|
||||||
|
signal(SIGTERM,SIG_IGN);
|
||||||
|
|
||||||
|
if((dd=open("/dev/ud",2))==-1) {
|
||||||
|
printf("\nunable to open /dev/ud\n"); goto ende; }
|
||||||
|
|
||||||
|
while (--argc > 0) /* process all command line args */
|
||||||
|
{
|
||||||
|
if ((*++argv)[0] == '-') /* test for command line option */
|
||||||
|
switch ((*argv)[1])
|
||||||
|
{
|
||||||
|
case 'b':
|
||||||
|
flags |= BINARY; /* set binary file type */
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
flags |= FATAL; /* udos-procedure file */
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
flags |= ALLBIN; /* all files are binary */
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else /* argument is a file name */
|
||||||
|
{
|
||||||
|
bufw[0]='S'; write(dd,bufw,1);
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
|
||||||
|
if (flags & ALLBIN) /* set binary if all files binary */
|
||||||
|
flags |= BINARY;
|
||||||
|
bufw[0]=flags; write(dd,bufw,1);
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
|
||||||
|
checksum = 0; /* compute checksum to send */
|
||||||
|
fname = *argv; /* pointer to file name */
|
||||||
|
for (; **argv; (*argv)++) /* loop until end of name string */
|
||||||
|
if (**argv == '/') /* strip path name from string */
|
||||||
|
{
|
||||||
|
fname = *argv; /* fname points to char after '/' */
|
||||||
|
fname++;
|
||||||
|
checksum = 0; /* start checksum over */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
checksum ^= **argv; /* checksum is xor of filename chars */
|
||||||
|
acknak = NAK; /* no acknowledge so far */
|
||||||
|
|
||||||
|
/* send the filename first and get an ACK. Try RETRIES times */
|
||||||
|
|
||||||
|
for (i=0; i<RETRIES && acknak!=ACK; i++)
|
||||||
|
{
|
||||||
|
bufw[0]=STX; k=1;
|
||||||
|
while((bufw[k++]=(fname[k-1]))!='\0');
|
||||||
|
bufw[k-1]=ETX; write(dd,bufw,k);
|
||||||
|
bufw[0]=checksum; write(dd,bufw,1);
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
if (acknak != ACK)
|
||||||
|
if (acknak == CAN) /* abort this file */
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acknak != ACK) { /* abort this file, go to next */
|
||||||
|
bufw[0]=CAN; write(dd,bufw,1);
|
||||||
|
}
|
||||||
|
else /* filename rcvd, now get the file */
|
||||||
|
{
|
||||||
|
if ((fd = creat(fname, CMODE)) == - 1) /* create or truncate file */
|
||||||
|
{
|
||||||
|
look_for_etx(); /* flush chars coming from local sys */
|
||||||
|
bufw[0]=CAN; write(dd,bufw,1);
|
||||||
|
printf ("\nunable to open file\n");
|
||||||
|
read(dd,bufr,1); c=bufr[0];
|
||||||
|
c &= 0177;
|
||||||
|
}
|
||||||
|
|
||||||
|
else /* file was opened with no error */
|
||||||
|
{
|
||||||
|
|
||||||
|
if(verbose) printf("\nfile %s is read from udos-disk\n", fname);
|
||||||
|
|
||||||
|
/* local will send EOT at eof, CAN for error, or ESC to end all */
|
||||||
|
read(dd,bufr,1); c=bufr[0]&0177;
|
||||||
|
while ((c!=CAN) && (c!=ESC) && (c!=EOT))
|
||||||
|
{
|
||||||
|
/* try RETRIES times to get a good record */
|
||||||
|
acknak = NAK; /* no acknowledge so far */
|
||||||
|
|
||||||
|
for (i=0; i<RETRIES && acknak!=ACK;)
|
||||||
|
{
|
||||||
|
if (c != STX) look_for_etx(); /* first char should be stx */
|
||||||
|
|
||||||
|
else /* stx found */
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
read(dd,bufr,2);
|
||||||
|
high_count = bufr[0]; low_count = bufr[1];
|
||||||
|
n_to_read = (high_count*256) + low_count;
|
||||||
|
|
||||||
|
|
||||||
|
checksum = 0; /* start checksum at zero */
|
||||||
|
for (j=0; j<n_to_read; j++)
|
||||||
|
{
|
||||||
|
read(dd,bufr,1); buffer[j]=bufr[0];
|
||||||
|
checksum ^= buffer[j]; /* checksum is xor of buffer chars */
|
||||||
|
if (buffer[j] == '\r') /* replace cr's with newlines */
|
||||||
|
if (!(flags & (BINARY | ALLBIN)))
|
||||||
|
buffer[j] = '\n'; /* do not change binary file */
|
||||||
|
}
|
||||||
|
|
||||||
|
aread(); /* next char should be etx */
|
||||||
|
if (c != ETX)
|
||||||
|
look_for_etx(); /* flush rest of chars */
|
||||||
|
else /* etx found */
|
||||||
|
{
|
||||||
|
aread(); /* next char should be chksum */
|
||||||
|
if((char)c == checksum) /* compare */
|
||||||
|
{
|
||||||
|
n_written = write (fd, buffer, n_to_read); /* write */
|
||||||
|
acknak = ACK; /* only now will an ACK be sent */
|
||||||
|
if(verbose) putchar('.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
i++; /* increment try number */
|
||||||
|
|
||||||
|
if(del)
|
||||||
|
{
|
||||||
|
bufw[0]=CAN; write(dd,bufw,1);
|
||||||
|
c=ESC; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (acknak == ACK)
|
||||||
|
{ bufw[0]=acknak; write(dd,bufw,1); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufw[0]=CAN; write(dd,bufw,1);
|
||||||
|
}
|
||||||
|
read(dd,bufr,1); c=bufr[0]&0177;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close (fd); /* close the file */
|
||||||
|
if (c == EOT) success++; /* update the success count */
|
||||||
|
else unsuccess++;
|
||||||
|
|
||||||
|
if (c == ESC) /* user wants to end the whole thing */
|
||||||
|
{
|
||||||
|
read(dd,bufr,1); c=bufr[0];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
read(dd,bufr,1); c=bufr[0];
|
||||||
|
|
||||||
|
flags &= ~BINARY; /* default to ascii type next file */
|
||||||
|
if(verbose) putchar('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(dd);
|
||||||
|
ende:
|
||||||
|
return(unsuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
del_pro()
|
||||||
|
{
|
||||||
|
signal(SIGINT, del_pro);
|
||||||
|
del=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
look_for_etx() /* look for etx and chksum */
|
||||||
|
{
|
||||||
|
while (c != ETX)
|
||||||
|
{
|
||||||
|
aread();
|
||||||
|
}
|
||||||
|
aread(); /* look for chksum */
|
||||||
|
}
|
||||||
|
|
||||||
|
aread()
|
||||||
|
{
|
||||||
|
read(dd,bufr,1); c=bufr[0];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,201 @@
|
||||||
|
/* putud P8000 Datei Schreiben auf 8-Bit-Teil unter UDOS */
|
||||||
|
|
||||||
|
|
||||||
|
#define SOH 0x01 /* ascii start-of-header character */
|
||||||
|
#define STX 0x02 /* ascii start-of-text character */
|
||||||
|
#define ETX 0x03 /* ascii end-of-text character */
|
||||||
|
#define ACK 0x06 /* ascii acknowledge character */
|
||||||
|
#define NAK 0x15 /* ascii non-acknowledge character */
|
||||||
|
#define CAN 0x18 /* ascii cancel character (ctrl-x) */
|
||||||
|
#define ESC 0x1b /* ascii escape character */
|
||||||
|
#define RETRIES 3 /* number of allowable transmission errors */
|
||||||
|
#define XFER_SIZE 64 /* max number of characters sent as a block */
|
||||||
|
|
||||||
|
#define BINARY 0x01 /* flag byte bit settings */
|
||||||
|
#define FATAL 0x04
|
||||||
|
#define ALLBIN 0x08
|
||||||
|
#define EXEC 0x10
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
struct stat stbuf;
|
||||||
|
|
||||||
|
char bufw[20], bufr[2];
|
||||||
|
int dd, k;
|
||||||
|
|
||||||
|
char acknak, checksum, buffer[XFER_SIZE], high_count, low_count;
|
||||||
|
int i, n_read, fd, tflags, success, unsuccess;
|
||||||
|
|
||||||
|
int verbose=0;
|
||||||
|
int del=0;
|
||||||
|
int del_pro();
|
||||||
|
|
||||||
|
char *fname;
|
||||||
|
char flags = 0;
|
||||||
|
|
||||||
|
main (argc, argv)
|
||||||
|
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
signal(SIGINT, del_pro); /* Interrupt-Signal (DEL-Taste) einfangen */
|
||||||
|
signal(SIGHUP, SIG_IGN); /* weitere Signale ignorieren */
|
||||||
|
signal(SIGQUIT,SIG_IGN);
|
||||||
|
signal(SIGILL, SIG_IGN);
|
||||||
|
signal(SIGTRAP,SIG_IGN);
|
||||||
|
signal(SIGIOT, SIG_IGN);
|
||||||
|
signal(SIGSEGV,SIG_IGN);
|
||||||
|
signal(SIGSYS, SIG_IGN);
|
||||||
|
signal(SIGPIPE,SIG_IGN);
|
||||||
|
signal(SIGALRM,SIG_IGN);
|
||||||
|
signal(SIGTERM,SIG_IGN);
|
||||||
|
|
||||||
|
if((dd=open("/dev/ud",2))==-1)
|
||||||
|
{printf("\nunable to open /dev/ud\n");goto ende;}
|
||||||
|
|
||||||
|
while (--argc > 0) /* process all command line args */
|
||||||
|
{
|
||||||
|
if ((*++argv)[0] == '-') /* test for command line option */
|
||||||
|
switch ((*argv)[1])
|
||||||
|
{
|
||||||
|
case 'b':
|
||||||
|
flags |= BINARY; /* set binary file type */
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
flags |= FATAL; /* udos-procedure file */
|
||||||
|
break;
|
||||||
|
case 'B': /* all files are binary */
|
||||||
|
flags |= ALLBIN;
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
verbose = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else /* argument is a file name */
|
||||||
|
{
|
||||||
|
if ((fd = open(*argv, 0)) == -1) /* open file and test for error */
|
||||||
|
printf ("\n%s unable to open file\n", *argv);
|
||||||
|
else /* file was opened with no error */
|
||||||
|
{
|
||||||
|
fstat (fd, &stbuf); /* is the file executable? */
|
||||||
|
if (stbuf.st_mode & S_IEXEC)
|
||||||
|
flags |= EXEC; /* if yes, set executable bit */
|
||||||
|
|
||||||
|
if(stbuf.st_size == 0L)
|
||||||
|
printf("\nfile %s has length of zero\n",*argv);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bufw[0]='L';write(dd,bufw,1);
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
|
||||||
|
if (flags & ALLBIN) /* set binary if all files binary */
|
||||||
|
flags |= BINARY;
|
||||||
|
bufw[0]=flags; write(dd,bufw,1);
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
|
||||||
|
checksum = 0; /* compute checksum to send */
|
||||||
|
fname = *argv; /* pointer to file name */
|
||||||
|
for (; **argv; (*argv)++) /* loop until end of name string */
|
||||||
|
if (**argv == '/') /* strip path name from string */
|
||||||
|
{
|
||||||
|
fname = *argv; /* fname points to char after '/' */
|
||||||
|
fname++;
|
||||||
|
checksum = 0; /* start checksum over */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
checksum ^= **argv; /* checksum is xor of filename chars */
|
||||||
|
acknak = NAK; /* no acknowledge so far */
|
||||||
|
|
||||||
|
/* send the filename first and get an ACK. Try RETRIES times */
|
||||||
|
|
||||||
|
for (i=0; i<RETRIES && acknak!=ACK; i++)
|
||||||
|
{
|
||||||
|
bufw[0]=STX; k=1;
|
||||||
|
while((bufw[k++]=(fname[k-1]))!='\0');
|
||||||
|
bufw[k-1]=ETX; write(dd,bufw,k);
|
||||||
|
bufw[0]=checksum; write(dd,bufw,1);
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
if (acknak != ACK)
|
||||||
|
if (acknak == CAN) /* abort this file */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* filename received, now send file */
|
||||||
|
if (acknak == ACK)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(verbose) printf("\nfile %s is written to udos-disk\n", fname);
|
||||||
|
|
||||||
|
/* read the file in blocks of XFER_SIZE chars. format record and send */
|
||||||
|
while ((n_read = read(fd, buffer, XFER_SIZE)) > 0)
|
||||||
|
{
|
||||||
|
high_count = n_read/256; /* compute the two bytes containing */
|
||||||
|
low_count = n_read - (high_count*256); /* the data length */
|
||||||
|
acknak = NAK; /* no acknowledge so far */
|
||||||
|
checksum = 0; /* compute checksum to send */
|
||||||
|
for (i=0; i<n_read; i++) /* checksum is xor of buffer chars */
|
||||||
|
{
|
||||||
|
if (buffer[i] == '\n') /* turn newlines into returns */
|
||||||
|
if (!(flags & (BINARY | ALLBIN)))
|
||||||
|
buffer[i] = '\r'; /* do not change binary file */
|
||||||
|
checksum ^= buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send one block of characters and try RETRIES times to get ACK */
|
||||||
|
|
||||||
|
for (i=0; i<RETRIES && acknak!=ACK; i++)
|
||||||
|
{
|
||||||
|
bufw[0]=STX; bufw[1]=high_count; bufw[2]=low_count;
|
||||||
|
write(dd,bufw,3);
|
||||||
|
write(dd,buffer,n_read);
|
||||||
|
bufw[0]=ETX; bufw[1]=checksum;
|
||||||
|
write(dd,bufw,2);
|
||||||
|
if(verbose) putchar('.');
|
||||||
|
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
|
||||||
|
if (del) acknak=ESC;
|
||||||
|
if ((acknak==CAN) || (acknak==ESC)) /* abort requested */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (acknak != ACK) /* send local sys the abort message */
|
||||||
|
break; /* abort this file, go to next */
|
||||||
|
}
|
||||||
|
if (acknak == ACK) success++; /* count successful transfers */
|
||||||
|
else unsuccess++;
|
||||||
|
}
|
||||||
|
bufw[0]=CAN; write(dd,bufw,1);
|
||||||
|
close (fd); /* close file */
|
||||||
|
if (acknak == ESC) /* abort everything */
|
||||||
|
{
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
read(dd,bufr,1); acknak=bufr[0];
|
||||||
|
acknak &= 0177;
|
||||||
|
flags &= ~(BINARY | EXEC); /* default to ascii type next file */
|
||||||
|
if(verbose) putchar('\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(dd);
|
||||||
|
ende:
|
||||||
|
return(unsuccess);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
del_pro()
|
||||||
|
{
|
||||||
|
signal(SIGINT, del_pro);
|
||||||
|
del=1;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue