1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-04-25 19:51:57 +00:00
Files
rcornwell.sims/SEL32/taptools/sdtfmgrcopy.c
AZBevier eb75e1ce54 SEL32: Add updates for MPX 3.X support.
SEL32: Add VOLMGR tape creator for MPX 3.X SDT and save tapes.
SEL32: Add MFP SCSI disk support.
SEL32: Change device status returns to 16 bits.
SEL32: Update README.md for current project status.
SEL32: Update .ini files for latest simulator configurations.
SEL32: Update taptools to correct odd record byte count error.
SEL32: Update interval timer code to pass SEL diagnostics.
SEL32: Correct single/double floating point arithmetic.
2020-04-21 16:10:34 -07:00

366 lines
14 KiB
C

/*
* sdtfmgrcopy.c
*
* This program scans a metatape file and prints file count and sizes.
* input - stdin or specified filename
* output - stdout
*/
#include <stdio.h>
#include <sys/file.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
int lfilen, filen = 1;
int smd = 0;
int EOFcnt = 0;
int count=0, lcount=0;
int size=0, tsize=0;
int size_512K = 512 * 1024;
int ln;
#ifdef USE_READ
FILE *infp;
#else
int inp, outp;
#endif
#define PRINTABLE(x) ((x < 32) || (x > 126)) ? '.' : x
/* get a line of input. */
int getloi(char *s, int lim)
{
int c, i;
int n1, n2, hc, tc, n;
errno = 0;
/* read the byte count in 32 bit word as header */
n1 = read(inp, (char *)(&hc), (size_t)4);
if (n1 <= 0)
hc = -1; /* at EOM on disk file */
/* check for EOF & EOM on tape data */
if (hc & 0xffff0000) /* check for garbage, assume EOM */
hc = -1; /* at EOM on disk file */
/* check for EOF & EOM on tape data */
if (hc == 0) {
/* we are at tape EOF */
if (++EOFcnt < 2) { /* if 1st EOF, print file info */
// printf("EOF found after file %d\n", filen);
lfilen = filen;
filen++; /* set next file number */
smd = 1; /* look for smd again */
}
count = 0; /* file record count back to zero */
lcount = 0; /* last record count back to zero */
tsize += size; /* add to total tape size */
size = 0; /* file size back to zero */
ln = -1; /* set ln to -1 showing we are at EOF */
/* we have EOF */
return 0; /* return EOF on tape data */
}
if (hc == -1) {
printf("EOM found after file %d\n", filen);
return -1; /* at EOM on disk file */
}
/* read the data */
n = read(inp, s, (size_t)hc);
/* if odd byte record, read extra byte and throw it away */
if (n & 0x1) {
n2 = read(inp, (char *)(&tc), (size_t)1);
if (n2 <= 0)
return -1; /* at EOM on disk file */
}
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)4);
count++; /* bump record count */
size += n; /* update bytes read */
EOFcnt = 0; /* not an EOF */
if (n != ln) {
ln = n;
lcount = count;
}
/* return bytes in buffer */
return n;
}
int main (int argc, char *argv[])
{
char *buf;
size_t size_512K = 512 * 1024;
size_t buf_size = 512 * 1024;
char *cp, *np;
int ll;
char path[64], command[128];
// int sdt = 1;
int sdt = 0;
smd = 1;
if (argc != 2) {
//fprintf(stderr, "usage: %s infile\n", argv[0]);
printf("usage: %s infile\n", argv[0]);
exit(1);
} /* end of if */
if ((inp = open(argv[1], O_RDONLY, 0666)) < 0) {
//fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
printf("%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
return (1);
}
outp = -1;
/* get a 512k buffer */
if ((buf = malloc(buf_size)) == NULL) {
//fprintf(stderr, "Can't allocate memory for tscan\n");
printf("Can't allocate memory for tscan\n");
return (4);
}
/* init counts */
ln = -2; /* look for 2 eof */
count = 0;
size = 0;
tsize = 0;
lcount = 0;
filen = 1;
lfilen = 0;
printf("\nfile %d:\n", filen);
/* get lines until eof */
while ((ll=getloi(buf, buf_size)) != EOF) {
printf("got ll = %d filen %d\n", ll, filen);
if (ll == 1920) {
sdt = 1; /* process SDT tape */
smd = 0;
printf("process sdt ll = %d\n", ll);
}
if (ll == 4608) {
sdt = 0; /* process SMD tape */
smd = 1;
printf("process smd ll = %d\n", ll);
}
if (ll == 0) {
/* eof found, process new file */
printf("\nfile %d:\n", filen);
smd = 1;
sdt = 0;
continue; /* go look for another SDT bootfile or SMD entry */
} else
if (ll != 1920 && ll != 4608) {
printf("File is not in MPX filemgr format and can not be processed!\n");
break;
} else {
int cc = 0;
unsigned int curchar;
char filename[16];
int i, j, m;
/* SDT entries have 1920 bytes as first record. This is */
/* followed by multiple 768 byte records to finish the SDT image */
/* read the boot data from the sdt tape */
/* check for SDT entry instead of SMD entry */
// if (ll == 1920)
// if (sdt == 1 && filen == 1)
if (sdt == 1) {
int no, ct = 0;;
/* get more sdt data */
/* open output file, create it if necessary */
if (outp == -1) {
sprintf(filename, "bootfile%d\0", filen);
// if ((outp = open("bootfile", O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
if ((outp = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
printf("Can't open bootfile\n");
close(inp);
free(buf);
return (3);
}
}
printf("got2 ll = %d writing to bootfile -> %s\n", ll, filename);
no = write(outp, buf, ll);
if (no != ll)
// fprintf(stderr, "write (%d) != read (%d) on file %s\n", no, ll, path);
printf("write (%d) != read (%d) on file bootfile\n", no, ll);
/* get lines until eof */
while ((ll=getloi(buf, buf_size)) > 0) {
ct++;
no = write(outp, buf, ll);
if (no != ll)
// fprintf(stderr, "write (%d) != read (%d) on file %s\n", no, ll, path);
printf("write (%d) != read (%d) on file bootfile\n", no, ll);
}
sdt = 0;
smd = 1;
close(outp);
outp = -1;
printf("wrote %d records to bootfile %s\n", ct, filename);
continue; /* go look for another SDT bootfile or SMD entry */
} else
/* filemgr smd entries are 8 words, and are in 1152 words (4608 bytes)
* (6 sector) blocks. Saved data files are modulo 1152 words also */
/* 8 wds per SMD entry, 24 entries per sector, 144 entries per 6 sector
* block. */
// printf("gotx ll = %d filen %d\n", ll, filen);
// if (filen == 1)
if (smd == 1) {
/* check for SMD entry instead of SDT entry */
/* read smd entry */
char file[20], dir[20];
int l = 0;
int smddone = 0;
int totent = 0;
char *buf2 = buf;
// printf("\nfile %d: %d\n", filen, ll);
/* see how many entries here */
while(!smddone) {
/* process entries in this record */
for (j=0; j<144; j++) {
int k = l++ * 32;
int w1 = (buf[k+13] & 0xff) << 16 | (buf[k+14] & 0xff) << 8 | (buf[k+15] & 0xff);
/* stop processing on first zero smd entry */
if (w1 <= 0) {
smddone = 1;
break;
}
totent++;
/* get file/dir name */
for (i=0; i<8; i++) {
file[i] = tolower(buf[k+0+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[8] = '\0';
for (i=0; i<8; i++) {
dir[i] = tolower(buf[k+0+16+i]);
if (dir[i] == ' ')
dir[i] = '\0';
}
dir[8] = '\0';
if (dir[0] == '\0')
sprintf(dir, "%s", "system");
sprintf(path, "./%s/%s", dir, file);
// see if active file
if ((buf[k+12] & 0x80) == 0)
// not active goon
printf("inactive file: w1 = %d path = %s\n", w1, path);
else
printf("active file: w1 = %d path = %s\n", w1, path);
}
if (smddone)
break;
buf2 += 4608; /* next buffer */
ll=getloi(buf2, 4608);
}
printf("%d smd entries found\n", totent);
/* we have directory entries */
for (j=0; j<totent; j++) {
int k = j * 32;
/* get file size in blocks */
int w1 = (buf[k+13] & 0xff) << 16 | (buf[k+14] & 0xff) << 8 | (buf[k+15] & 0xff);
int blks = w1; /* save block count */
/* get file/dir name */
for (i=0; i<8; i++) {
file[i] = tolower(buf[k+0+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[8] = '\0';
for (i=0; i<8; i++) {
dir[i] = tolower(buf[k+0+16+i]);
if (dir[i] == ' ')
dir[i] = '\0';
}
dir[8] = '\0';
if (dir[0] == '\0')
sprintf(dir, "%s", "system");
sprintf(path, "./%s", dir);
// see if active file
if ((buf[k+12] & 0x80) == 0) {
// not active goon
printf("inactive file: w1 = %d\n", w1);
}
printf("active file: w1 = %d\n", w1);
if (w1 <= 0)
break;
/* create the directory/file */
// printf("path = %s\n", path);
sprintf(command, "mkdir -p %s", path);
// printf("command = %s\n", command);
system(command);
sprintf(path, "./%s/%s", dir, file);
printf("file %d = %s\n", j+1, path);
sprintf(command, "touch %s", path);
// printf("command = %s\n", command);
system(command);
if (outp >= 0)
close(outp);
outp = -1;
#ifndef DO_LATER
/* open output file, create it if necessary */
if ((outp = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) {
//fprintf(stderr, "Can't open %s\n", path);
printf("Can't open %s\n", path);
close(inp);
free(buf);
return (3);
}
#endif
/* get the file data */
for (m=0; m<((w1+5)/6); m++) {
char data[5000]; /* data buffer */
ll=getloi(data, 4608);
/* process file data for file */
if (ll == 4608) {
#ifndef DO_LATER
/* blks/w1 have number of blocks to write */
int bcnt, no; /* block count */
if (blks >= 6) {
blks -= 6; /* enough for 6 block, write them */
bcnt = 6*768; /* write all 6 blocks */
} else {
bcnt = blks*768;/* just write what we need */
blks = 0;
}
/* only write number of sectors on save tape, not all 4608 */
/* if zero, just reading excess blocks */
if (bcnt != 0) {
no = write(outp, data, bcnt);
if (no != bcnt)
// fprintf(stderr, "write (%d) != read (%d) on file %s\n", no, bcnt, path);
printf("write (%d) != read (%d) on file %s\n", no, bcnt, path);
}
#else
if (m == 0)
printf("reading file %s\n", path);
#endif
} else {
printf("Bad file size read! %d instead of 4608\n", ll);
/// if (ll == -1) break;
if (ll == -1)
goto dostop;
}
} /* end writing file */
} /* end of smd scan */
} /* read smd entries 4608 byte records */
} /* process read of smd or sdt */
} /* end of getloi read */
dostop:
close(inp);
free(buf);
if (outp >= 0)
close(outp);
exit(0);
}