Interdata_v6/usr/source/wgong/import.c
/*
* import dev filename [newname]
*
* - read file <filename> from OS-formatted disc <dev> and
* copy it to file <newname> (default - standard output)
*/
struct osfile { /* information about os file */
int iscontig; /* contiguous file */
int size; /* size of file (in bytes) */
int sector; /* current sector */
int offset; /* current offset in bytes */
int nleft; /* sectors left in current block */
int *indexbuf; /* buffer for index block */
int *indexp; /* ¤t index */
int ibsize; /* sectors per index block */
int dbsize; /* sectors per data block */
} osfile;
struct dir { /* OS file directory */
char fnm[12]; /* filename */
int flba; /* sector no. of first block */
int llba; /* sector no. of last block */
int keyl; /* protect keys / lrecl */
int date[2];
int counts;
char atrb; /* filetype */
char dbsz; /* sectors per data block */
char ibsz; /* sectors per index block */
char flro;
int csec; /* no. of records in file */
int filler;
};
struct dirblk { /* directory block */
int nextdir;
struct dir dirent[5];
};
int disc;
char buffer[512];
main(argc, argv)
char *argv[];
{
register fd, len;
if (argc < 3)
error("Arg count");
if ((disc = open(argv[1], 0)) < 0)
error("Can't open %s", argv[1]);
if ((osopen(&osfile, argv[2])) < 0)
error("Can't find %s", argv[2]);
fd = 1;
if (argc > 3 && (fd = creat(argv[3], 0666)) < 0)
error("Can't create %s", argv[3]);
while ((len = osread(&osfile, buffer)) > 0)
write(fd, buffer, len);
}
error(s, x)
{
printf(s, x);
putchar('\n');
exit(1);
}
/*
* Find the OS file and initialize information
*/
osopen(afp, name)
struct osfile *afp;
{
register struct osfile *fp;
register struct dir *dp;
extern int *sbrk();
fp = afp;
if ((dp = getdir(name)) == 0)
return(-1);
switch((dp->atrb)>>5) {
case 00: /* contiguous file */
fp->iscontig = 1;
fp->size = (dp->llba - dp->flba + 1)*256;
fp->sector = dp->flba;
break;
case 02: /* indexed file */
fp->ibsize = dp->ibsz;
fp->dbsize = dp->dbsz;
fp->size = dp->csec * (dp->keyl & 077777);
fp->indexbuf = sbrk(fp->ibsize * 256);
fp->indexbuf[1] = dp->flba;
fp->indexp = &fp->indexbuf[fp->ibsize * 256/4];
break;
default:
error("Illegal os file type %o", dp->atrb);
}
}
/*
* Find directory entry for given file
*/
getdir(name)
{
char namebuff[11];
struct dirblk dirbuff;
int sect;
register struct dir *dp;
register i;
register char *p, c;
/* convert filename to form in which it appears in directory */
i = 0;
for (p=name; (c = *p) != '\0' && c != '.'; p++)
if (i < 8) {
if (c >= 'a' && c <= 'z') c =+ 'A'-'a';
namebuff[i++] = c;
}
while (i < 8)
namebuff[i++] = ' ';
if (c = '.')
for (p++; (c = *p) != '\0'; p++)
if (i < 11) {
if (c>='a' && c<='z') c =+ 'A'-'a';
namebuff[i++] = c;
}
while (i < 11)
namebuff[i++] = ' ';
seek(disc, 8, 0); /* pointer to first directory block */
xread(disc, §, sizeof sect);
while (sect) {
xseek(disc, sect);
if (xread(disc, &dirbuff, sizeof dirbuff))
error("Directory block read error");
for (dp = &dirbuff.dirent[0]; dp < &dirbuff.dirent[5]; dp++)
if ((dp->atrb&020) && match(dp, namebuff))
return(dp);
sect = dirbuff.nextdir;
}
return(0);
}
/*
* String comparison
*/
match(dirname, name)
char *dirname, *name;
{
register char *p, *q;
register count;
p = dirname; q = name;
for (count = 0; count < 11; count++)
if (*p++ != *q++)
return(0);
return(1);
}
/*
* Read a sector from OS file
*/
osread(afp, buff)
struct osfile *afp;
{
register struct osfile *fp;
register len;
fp = afp;
len = fp->size - fp->offset;
if (len > 256)
len = 256;
if (len <= 0)
return(len);
if (!fp->iscontig && --fp->nleft < 0)
nextblk(fp);
xseek(disc, fp->sector++);
if (xread(disc, buff, len))
printf("Read error - offset %o", fp->offset);
fp->offset =+ len;
return(len);
}
/*
* Find next block of indexed file
*/
nextblk(afp)
struct osfile *afp;
{
register struct osfile *fp;
fp = afp;
if (fp->indexp >= &fp->indexbuf[fp->ibsize * 256/4]) {
xseek(disc, fp->indexbuf[1]);
if (xread(disc, fp->indexbuf, fp->ibsize * 256))
error("Index block read error");
fp->indexp = &fp->indexbuf[2];
}
fp->sector = *fp->indexp++;
fp->nleft = fp->dbsize - 1;
}
xseek(fd, sect)
{
seek(fd, sect*256, 0);
}
xread(fd, addr, len)
int *addr;
{
extern int errno;
register io;
if ((io = read(fd, addr, len)) < 0)
return(1);
return(0);
}