1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-04 15:43:38 +00:00
Files
rcornwell.sims/SEL32/taptools/disk2tap.c
James C. Bevier fbf62937ef SEL32: Backup commits before new push to SEL32.
SEL32: Add initial MPX 3.5 and MPX 3.6 support in SEL32.
SEL32: Add larger disk support; 500, 600, 700, 1200 MB.
SEL32: Fix clock interrupt and console attention trap interaction error.
SEL32: Redo STPIO processing for MPX 3X changes.
SEL32: Add GRABIO processing for MPX 3X system debugger support.
SEL32: Correct disk mount error for MPX 3X.
SEL32: Allow taptools to be built on Windows.
2021-05-30 18:33:17 -07:00

269 lines
10 KiB
C

/*
* MPX uses 2 EOF in a row to separate sections of MPX3.x master SDT tapes.
* It uses 3 EOF in a row to indicate the EOT on MPX 3.X tapes. So we
* cannot assume EOT is at the 1st or 2nd EOF in a row. Keep looking
* for a third one. Comment out the #define FMGRTAPE below to read an
* MPX 3.x master SDT. For user SDT tapes or MPX 1.X master SDT tapes
* leave the #define FMGRTAPE uncommented so it will be defined. The
* program will stop on two EOFs. For non MPX tapes, the 2nd EOF means
* EOT. Some tapes have only one EOT and will terminate on EOT detected.
* Leave off the output file name to just scan the tape and output record
* sizes and counts.
*/
#include <stdio.h>
//#include <signal.h>
//#include <sys/types.h>
//#include <sys/file.h>
//#include <sys/fcntl.h>
//#include <sys/mtio.h>
#include <stdlib.h>
//#include <unistd.h>
//#include <limits.h>
//#include <errno.h>
//#define FMGRTAPE /* defined for filemgr tapes, undefined for volmgr tape */
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef unsigned __int8 uint8;
typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
typedef signed __int64 t_int64;
typedef unsigned __int64 t_uint64;
typedef t_int64 off_t;
#else
/* All modern/standard compiler environments */
/* any other environment needa a special case above */
#include <stdint.h>
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
#endif /* end standard integers */
char *buff; /* buffer for read/write */
int filen = 1; /* file number being processed */
long count=0, lcount=0; /* number of blocks for file */
extern void RUBOUT(); /* handle user DELETE key signal */
off_t size=0, tsize=0; /* number of bytes in file, total */
int ln;
char *inf, *outf;
int copy;
int32 size_1K = 1024;
#if 0
int32_t size_128K = 128 * 1024;
int32_t size_256K = 256 * 1024;
#endif
int main(argc, argv)
int argc;
char **argv;
{
// int n, nw, inp, outp;
int n, nw;
FILE *inp, *outp;
// struct mtop op;
// int32_t buf_size = size_256K;
int32 buf_size = size_1K;
int EOFcnt = 0; /* count the number of EOFs in a row. */
if (argc <= 1 || argc > 3) {
(void)fprintf(stderr, "Usage: disk2tap src [dest]\n");
return (1);
}
inf = argv[1];
if (argc == 3) {
outf = argv[2];
copy = 1;
}
// if ((inp = open(inf, O_RDONLY, 0666)) < 0) {
if ((inp = fopen(inf, "r")) == NULL) {
(void)fprintf(stderr, "Can't open %s\n", inf);
return (1);
}
if (copy) {
/* open output file, create it if necessary */
// if ((outp = open(outf, O_WRONLY|O_CREAT, 0666)) < 0) {
if ((outp = fopen(outf, "w")) == NULL) {
(void)fprintf(stderr, "Can't open %s\n", outf);
return (3);
}
}
/* get a 1k buffer */
if ((buff = malloc(buf_size)) == NULL) {
(void)fprintf(stderr, "Can't allocate memory for disk2tap\n");
return (4);
}
// if (signal(SIGINT, SIG_IGN) != SIG_IGN)
// (void)signal(SIGINT, RUBOUT);
ln = -2;
for (;;) {
count++;
// errno = 0;
/* read first record to get size for buffer, doubling each time unsuccessful */
// while ((n = read(inp, buff, buf_size)) < 0) {
while ((n = fread(buff, (size_t)1, (size_t)buf_size, inp)) <= 0) {
#if 0
if (errno == ENOMEM) {
#if 0
if (buf_size < size_256K)
buf_size = size_256K;
else
buf_size *= 2;
#endif
free(buff);
if ((buff = malloc(buf_size)) == NULL) {
(void)fprintf(stderr, "Can't allocate memory for tapecopy\n");
return (4);
}
op.mt_op = MTFSF; /* Rewind to start of file */
op.mt_count = (daddr_t) 0;
if (ioctl(inp, MTIOCTOP, (char *)&op) < 0) {
perror("Read buffer size error");
return (6);
}
errno = 0;
continue;
}
#endif
perror("Unknown read error");
// errno = 0;
return (6); /* abort on error, comment out to ignore taoe errors */
}
if (n > 0) {
/* we read some data, see if scanning or writing */
EOFcnt = 0; /* not at EOF anymore */
if (copy) {
int32 n1, n2;
/* we have data to write */
int32 hc = (n + 1) & ~1; /* make byte count even */
int32 wc = n; /* get actual byte count */
/* write actual byte count to 32 bit word as header */
// n1 = write(outp, (char *)(&wc), (int32_t)4);
n1 = fwrite((char *)(&wc), (size_t)1, (size_t)4, outp);
/* write the data mod 2 */
// nw = write(outp, buff, (int32_t)hc);
nw = fwrite(buff, (size_t)1, (size_t)hc, outp);
/* write the byte count in 32 bit word as footer */
// n2 = write(outp, (char *)(&wc), (int32_t)4);
n2 = fwrite((char *)(&wc), (size_t)1, (size_t)4, outp);
if (n1 != 4 || nw != hc || n2 != 4) {
fprintf(stderr, "write (%d) !=" " read (%d)\n", nw, n);
fprintf(stderr, "COPY " "Aborted\n");
return (5);
}
}
size += n; /* update bytes read */
if (n != ln) { /* must be last record of file if different */
if (ln > 0) {
/* we read something */
if ((count - lcount) > 1)
(void)printf("file %d: records %ld to %ld: size %d\n",
filen, lcount, count - 1, ln);
else
(void)printf("file %d: record %ld: size %d\n",
filen, lcount, ln);
}
ln = n; /* save last record size */
lcount = count; /* also record count */
}
} else {
/* we did not read data, it must be an EOF */
/* if ln is -1, last operation was EOF, now we have a second */
#ifdef FMGRTAPE
/* filemgr has 2 EOF's at end of tape */
if (++EOFcnt > 1) {
/* two EOFs mean we are at EOT */
(void)printf("fmgr eot\n");
break;
}
#else
/* volmgr has 3 EOF's at end of tape */
if (++EOFcnt > 2) {
/* three EOFs mean we are at EOT on MPX */
(void)printf("volm eot\n");
break;
}
#endif
if (ln > 0) {
if (count - lcount > 1)
(void)printf("file %d: records %ld to %ld: size %d\n",
filen, lcount, count - 1, ln);
else
(void)printf("file %d: record %ld: size %d\n",
filen, lcount, ln);
}
#ifdef FMGRTAPE
(void)printf("file %d: eof after %ld records: %ld bytes\n",
filen, count - 1, size);
#else
if (EOFcnt == 2) /* if 2nd EOF, print file info */
(void)printf("second eof after %d files: %ld bytes\n",
filen, size);
#endif
if (copy) {
/* write a sudo EOF to disk file as a zero 4 byte record */
int n1, hc = 0;
/* write the EOF */
/* write a zero as the byte count in 32 bit word as EOF */
// n1 = write(outp, (char *)(&hc), (int32_t)4);
n1 = fwrite((char *)(&hc), (size_t)1, (size_t)4, outp);
if (n1 != 4) {
perror("Write EOF");
return (6);
}
}
#ifdef FMGRTAPE
filen++; /* advance number of files */
#else
if (EOFcnt < 2) /* not really a file if 2nd EOF */
filen++; /* advance number of files */
#endif
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 = n; /* set ln to -1 showing we are at EOF */
}
}
if (copy) {
/* write a sudo EOM to disk file as a -1 4 byte record */
int32 n1, hc = 0xffffffff;
/* write the EOM to disk */
/* write a -1 as the byte count in 32 bit word as EOM */
// n1 = write(outp, (char *)(&hc), (int32_t)4);
n1 = fwrite((char *)(&hc), (size_t)1, (size_t)4, outp);
if (n1 != 4) {
perror("Write EOM");
return (6);
}
// (void)close(outp);
fclose(outp);
}
/* print out total tape size in bytes */
(void)printf("total length: %ld bytes\n", tsize);
return (0);
}
#if 0
/* entered when user hit the DELETE key */
void RUBOUT()
{
if (count > lcount)
--count;
if (count)
if (count > lcount)
(void)printf("file %d: records %ld to %ld: size" " %d\n", filen, lcount, count, ln);
else
(void)printf("file %d: record %ld: size %d\n", filen, lcount, ln);
(void)printf("interrupted at file %d: record %ld\n", filen, count);
(void)printf("total length: %ld bytes\n", tsize + size);
exit(1);
}
#endif