mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-24 08:54:17 +00:00
349 lines
6.5 KiB
C
349 lines
6.5 KiB
C
#include "tp.h"
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/dir.h>
|
|
|
|
struct direct direct;
|
|
struct stat statb;
|
|
|
|
clrdir()
|
|
{
|
|
register j, *p;
|
|
|
|
j = ndirent * (DIRSZ/sizeof(int));
|
|
p = (int *)dir;
|
|
do (*p++ = 0); while (--j);
|
|
lastd = 0;
|
|
}
|
|
|
|
clrent(ptr)
|
|
struct dent *ptr;
|
|
{
|
|
register *p, j;
|
|
|
|
p = (int *)ptr;
|
|
j = DIRSZ/sizeof(int);
|
|
do *p++ = 0;
|
|
while (--j);
|
|
if (++ptr == lastd) do {
|
|
if (--lastd < dir) {
|
|
lastd = 0;
|
|
return;
|
|
}
|
|
} while (lastd->d_namep == 0);
|
|
}
|
|
|
|
|
|
rddir()
|
|
{
|
|
register struct tent *tp;
|
|
register struct dent *p1;
|
|
struct dent *dptr;
|
|
struct tent *tptr;
|
|
int count, i, sum;
|
|
short reg, *sp;
|
|
|
|
sum = 0;
|
|
clrdir();
|
|
rseek(0);
|
|
tread(); /* Read the bootstrap block */
|
|
if ((tpentry[TPB-1].cksum != 0) && (flags & flm)) {
|
|
ndirent = tpentry[TPB-1].cksum;
|
|
if(flags & fls) swab((char *)&ndirent, (char *)&ndirent, sizeof(ndirent));
|
|
if(ndirent < 0 || ndirent > MDIRENT) ndirent = MDIRENT;
|
|
ndentb = ndirent/TPB;
|
|
}
|
|
dptr = &dir[0];
|
|
count = ndirent;
|
|
do {
|
|
if ((count % TPB) == 0) { /* next block */
|
|
tread();
|
|
tptr = &tpentry[0];
|
|
}
|
|
if(flags & fls)
|
|
swab((char *)tptr, (char *)tptr, sizeof(*tptr));
|
|
sp = (short *)tptr;
|
|
reg = 0;
|
|
for(i=0;i<sizeof(struct tent)/sizeof(short);i++)
|
|
reg += *sp++;
|
|
if(flags & fls) {
|
|
swab((char *)tptr, (char *)tptr, sizeof(*tptr));
|
|
swabdir(tptr);
|
|
}
|
|
sum |= reg;
|
|
p1 = dptr;
|
|
if (reg == 0) {
|
|
tp = tptr;
|
|
if(tp->pathnam[0] != '\0') {
|
|
lastd = p1;
|
|
encode(tp->pathnam,p1);
|
|
p1->d_mode = tp->mode;
|
|
p1->d_uid = tp->uid;
|
|
p1->d_gid = tp->gid;
|
|
p1->d_size = (((long)tp->size0&0377L)<<16)+(tp->size1&0177777L);
|
|
p1->d_time = tp->time;
|
|
p1->d_tapea = tp->tapea;
|
|
}
|
|
}
|
|
++tptr; /* bump to next tent */
|
|
(dptr++)->d_mode &= ~OK;
|
|
} while (--count);
|
|
if(sum != 0)
|
|
if(flags & (fls|fli)) {
|
|
printf("Directory checksum\n");
|
|
if ((flags & fli) == 0) done();
|
|
} else {
|
|
flags |= fls;
|
|
rddir();
|
|
printf("Warning: swabbing required\n");
|
|
return;
|
|
}
|
|
bitmap();
|
|
}
|
|
|
|
|
|
wrdir()
|
|
{
|
|
register struct tent *tp;
|
|
register struct dent *dp;
|
|
struct dent *dptr;
|
|
int count, i;
|
|
short reg, *sp;
|
|
|
|
wseek(0);
|
|
if (flags & flm)
|
|
reg = open(mheader,0);
|
|
else reg = open(theader,0);
|
|
if (reg >= 0) {
|
|
read(reg,(char *)tapeb,BSIZE);
|
|
close(reg);
|
|
if(flags & fls)
|
|
swab((char *)&ndirent, (char *)&tpentry[TPB-1].cksum, sizeof(ndirent));
|
|
else
|
|
tpentry[TPB-1].cksum = ndirent;
|
|
} else
|
|
printf("\7\7\7Warning: cannot read prototype boot block.\n");
|
|
dptr = &dir[0];
|
|
count = ndirent;
|
|
for (;;) {
|
|
twrite();
|
|
if (count == 0) return;
|
|
tp = &tpentry[0];
|
|
do {
|
|
dp = dptr++; /* dptr set to next entry */
|
|
if (dp->d_namep) {
|
|
decode(tp->pathnam,dp);
|
|
tp->mode = dp->d_mode;
|
|
tp->uid = dp->d_uid;
|
|
tp->gid = dp->d_gid;
|
|
tp->time = dp->d_time;
|
|
tp->size0 = dp->d_size >> 16;
|
|
tp->size1 = dp->d_size;
|
|
tp->tapea = dp->d_tapea;
|
|
if(flags & fls) {
|
|
swabdir(tp);
|
|
swab((char *)tp, (char *)tp, sizeof(*tp));
|
|
}
|
|
reg = 0;
|
|
sp = (short *)tp;
|
|
for(i=0;i<sizeof(struct tent)/sizeof(short)-1;i++)
|
|
reg -= *sp++;
|
|
*sp = reg;
|
|
if(flags & fls)
|
|
swab((char *)tp, (char *)tp, sizeof(*tp));
|
|
} else {
|
|
sp = (short *)tp;
|
|
for(i=0;i<sizeof(struct tent)/sizeof(short);i++)
|
|
*sp++ = 0;
|
|
}
|
|
tp++;
|
|
} while (--count % TPB);
|
|
}
|
|
}
|
|
|
|
tread()
|
|
{
|
|
register j, *ptr;
|
|
|
|
if (read(fio,(char *)tapeb,BSIZE) != BSIZE) {
|
|
printf("Tape read error\n");
|
|
if ((flags & fli) == 0) done();
|
|
ptr = (int *)tapeb;
|
|
j = BSIZE/sizeof(int);
|
|
while(j--) *ptr++ = 0;
|
|
}
|
|
rseeka++;
|
|
}
|
|
|
|
twrite()
|
|
{
|
|
if (write(fio, (char *)tapeb,BSIZE) != BSIZE) {
|
|
printf("Tape write error\n");
|
|
done();
|
|
}
|
|
++wseeka;
|
|
}
|
|
|
|
rseek(blk)
|
|
{
|
|
rseeka = blk;
|
|
if (lseek(fio,(long)blk*BSIZE,0) < 0) seekerr();
|
|
}
|
|
|
|
wseek(blk)
|
|
{
|
|
register amt, b;
|
|
|
|
amt = b = blk;
|
|
if ((amt -= wseeka) < 0) amt = -amt;
|
|
if (amt > 25 && b) {
|
|
lseek(fio, (long)(b-1)*BSIZE, 0); /* seek previous block */
|
|
read(fio, (char *)&wseeka, 1); /* read next block */
|
|
}
|
|
wseeka = b;
|
|
if (lseek(fio, (long)b*BSIZE, 0) < 0) seekerr();
|
|
}
|
|
|
|
seekerr()
|
|
{
|
|
printf("Tape seek error\n");
|
|
done();
|
|
}
|
|
|
|
verify(key)
|
|
{
|
|
register c;
|
|
|
|
if ((flags & (flw | flv)) == 0)
|
|
return(0);
|
|
repeat: printf("%c %s ", key, name);
|
|
if ((flags & flw) == 0) {
|
|
printf("\n");
|
|
return(0);
|
|
}
|
|
c = getchar();
|
|
if (c == 'n' && getchar() == '\n')
|
|
done();
|
|
if (c == '\n')
|
|
return(-1);
|
|
if (c == 'y' && getchar() == '\n')
|
|
return(0);
|
|
while (getchar() != '\n');
|
|
goto repeat;
|
|
}
|
|
|
|
getfiles()
|
|
{
|
|
|
|
if ((narg -= 2) == 0) {
|
|
strcpy(name, ".");
|
|
callout();
|
|
} else while (--narg >= 0) {
|
|
strcpy(name, *parg++);
|
|
callout();
|
|
}
|
|
}
|
|
|
|
|
|
expand()
|
|
{
|
|
register char *p0, *save0;
|
|
int n, fid;
|
|
|
|
if ((fid = open(name,0)) < 0) fserr();
|
|
for (;;) {
|
|
if ((n = read(fid, (char *)&direct, sizeof(direct))) != sizeof(direct)) {
|
|
if (n == 0) {
|
|
close(fid);
|
|
return;
|
|
}
|
|
fserr();
|
|
}
|
|
if (direct.d_ino == 0) /* null entry */
|
|
continue;
|
|
p0 = name;
|
|
if (direct.d_name[0] == '.') /* don't save .xxxx */
|
|
continue;
|
|
while (*p0++);
|
|
save0 = --p0; /* save loc of \0 */
|
|
if (p0[-1] != '/')
|
|
*p0++ = '/';
|
|
strcpy(p0, direct.d_name);
|
|
callout();
|
|
*save0 = 0; /* restore */
|
|
}
|
|
}
|
|
|
|
fserr()
|
|
{
|
|
printf("%s -- Cannot open file\n", name);
|
|
done();
|
|
}
|
|
|
|
callout()
|
|
{
|
|
register struct dent *d;
|
|
register char *ptr1, *ptr0;
|
|
struct dent *empty;
|
|
int mode;
|
|
|
|
if (stat(name,&statb) < 0) fserr();
|
|
mode = statb.st_mode;
|
|
if ((mode &= S_IFMT) != 0) {
|
|
if (mode == S_IFDIR) /* directory */
|
|
expand();
|
|
if(mode != S_IFREG) return;
|
|
}
|
|
/* when we reach here we have recursed until we found
|
|
* an ordinary file. Now we look for it in "dir".
|
|
*/
|
|
empty = 0;
|
|
d = &dir[0];
|
|
do {
|
|
if (d->d_namep == 0) { /* empty directory slot */
|
|
if (empty == 0) /* remember the first one */
|
|
empty = d;
|
|
continue;
|
|
}
|
|
decode(name1,d);
|
|
ptr0 = name;
|
|
ptr1 = name1;
|
|
do if (*ptr0++ != *ptr1) goto cont;
|
|
while (*ptr1++);
|
|
/* veritably the same name */
|
|
if (flags & flu) { /* check the times */
|
|
if (d->d_time >= statb.st_mtime)
|
|
return;
|
|
}
|
|
if (verify('r') < 0) return;
|
|
goto copydir;
|
|
cont: continue;
|
|
} while (++d <= lastd);
|
|
/* name not found in directory */
|
|
if ((d = empty) == 0) {
|
|
d = lastd +1;
|
|
if (d >= edir) {
|
|
printf("Directory overflow\n");
|
|
done();
|
|
}
|
|
}
|
|
if (verify('a') < 0) return;
|
|
if (d > lastd) lastd = d;
|
|
encode(name,d);
|
|
copydir:
|
|
d->d_mode = statb.st_mode | OK;
|
|
d->d_uid = statb.st_uid;
|
|
d->d_gid = statb.st_gid;
|
|
d->d_size = statb.st_size;
|
|
d->d_time = statb.st_mtime;
|
|
}
|
|
|
|
swabdir(tp)
|
|
register struct tent *tp;
|
|
{
|
|
swab((char *)tp, (char *)tp, sizeof(*tp));
|
|
swab(tp->pathnam, tp->pathnam, NAMELEN);
|
|
swab((char *)&tp->uid, (char *)&tp->uid, 4); /* uid,gid,spare,size0 */
|
|
}
|