1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-03-10 04:24:44 +00:00

SEL32: Added tape tools.

This commit is contained in:
Richard Cornwell
2019-07-23 20:37:41 -04:00
parent 284a7586ca
commit 84fe5127a0
18 changed files with 4549 additions and 0 deletions

171
SEL32/taptools/README.md Normal file
View File

@@ -0,0 +1,171 @@
This directory contains several utilites to work with .tap metadata
files used by the simh simulators. Some of these would be usable
for any simulator, not just the SEL32 simulator. General use MPX
utilities are also attached that help with file format conversion
between MPX and UNIX files.
Users should create the directories /system and /system/bin to hold
the utilities. The directories should be world readable/writable.
chmod 777 /system /system/bin
The following two lines should be added to your ~/.bashrc so you
will be able to execute the utilities from anywhere:
PATH=$PATH:/system/bin
export PATH
You can test to see if correct by typing 'echo $PATH' and you
should get a response with /system/bin in the directory list.
Compile and install the utilities by typing 'make install' to
install utilities into the /system/bin directory.
cutostap - This program scans a metadata .tap file and copies files
until an EOF is found. This program is used to remove
the sdt image from a .tap file to be used in another
.tap sdt image. The mkfmcopy can be used to create a
user sdt tape with files following the sdt image.
command filelist <file.tap >stdout
input - stdin <file to remove sdt from
output - stdout >file to be written with sdt image
diskload - This program reads an MPX load module and stores it into
simulated diskfile. The MPX-1.x SMD entry for the file
is entered into the SMD for the file. Will not work for
MPX 3.x file systems.
command: diskload -la program diskfile
option -a - add filename to diskfile
option -l - list files in diskfile SMD, ignore filename
input - filename - file to copy to system disk
- diskfile - simulated system disk
output - modified system disk
filelist - This program scans a metadata .tap file and prints the
file count and sizes. Used to determine the file
format contained in the metadata .tap file.
command filelist <file.tap >stdout
input - stdin <file to dump
output - stdout
fmgrcopy - This program reads a MPX 1.x filemgr save tape. The tape
must contain a filemgr save image with 4608 byte records.
SMD entries and file data are modulo 1152 32 bit words or
4608 bytes. The program will create a directory in the
current directory for each different username. Null user
name will be the system directory. Within each directory
each file contained on the tape is extracted and written
as binary data to the named file. The .tap file MUST be
a filemgr save tape and not a MPX-1.x SDT tape.
command fmgrcopy file.tap >stdout
input - file.tap file to dump
output - stdout filelist and sizes
output - directory/files extracted to current directory
sdtfmgrcopy - This program reads a MPX 1.x filemgr save tape or a
user SDT followed by filemgr saves. The filemgr tape
must contain a filemgr save image with 4608 byte records.
A sdt tape starts with a 1920 byte record followed by
multiple 768 byte records to finish the sdt system image.
A sdt tape can be followed by one or more filemgr save
images of 4608 bytes. The boot image is put into bootfile1
in the current directory. The program will create a
directory in the current directory for each different
username. A null username will be the system directory.
Within each directory each file contained on the tape is
extracted and written as binary data to the named file.
The .tap file MUST be a filemgr save tape and not a
MPX 3.x volmgr save tape.
command sdtfmgrcopy file.tap >stdout
input - file.tap file to dump
output - stdout filelist and sizes
output - if tape contains a sdt image, it will be output
to the file bootfil1
output - directory/files extracted to current directory
tapdump - This program reads a metadata .tap file and prints a side
by side hexdump of the file contents. The records are
displayed as 256 byte chuncks. After each record if 256
bytes are displayed, hitting <cr> will continue dump,
hitting <q> will terminate the display, and hitting <s>
will skip to the next file on the simulated tape.
command tapdump <file.tap >stdout
input - stdin <file to dump
output - stdout
tape2disk - This program reads a tape assigned as input device. It
generated a .tap metadata file. Stdout will contain a
listing of the files and sizes written to disk. The define
#define FILEMGR must be compiled in for tapes ending with
two EOFs. Unix and MPX 1.x filemgr tapes use that format.
MPX 3.x volmgr save tapes contain three EOFs so comment out
the define for that case.
command - tape2disk mt00 [file.tap]
input - mag tape device being read
output - list of files and sizes read from input tape
output - metadata .tap file optionally specified
tapscan - This program scans a metadata .tap file and prints the
file count and sizes. Used to determine the file
format contained in the metadata .tap file.
command - tapscan file.tap >stdout
input - file.tap file to scan
output - stdout filelist and sizes
volmcopy - This program reads a MPX 3.x volmgrr save tape. The tape
must contain a volmgr save image with 6144 byte records
containing a list of saved files. Followed by directdory
entries of 1536 bytes and finally file data of 1 to 8 768
byte records. Files larger than 6144 bytes will be output
as modulo 6144 bytes. There is an EOF after each file
definition. The program will create a directory in the
current directory for each different directory. Within
each directory each file contained on the tape is extracted
and written as binary data to the named file. The .tap
file MUST be a volmgr save tape and not a MPX-1.x SDT/save
tape.
command fmgrcopy file.tap >stdout
input - file.tap file to dump
output - stdout filelist and sizes
output - directory/files extracted to current directory
General utilities for MPX
ddump - Create a sys by side ascii dump of a file. Same operation
as the DDUMP utility in MPX. 256 bytes are displayed at
a time. Hitting <cr> will continue to next 256 bytes. A
hex address can be input to display data at a given offset
in the file. Optionall, the file data can be modified.
command - ddump -r filename
option - -r means open file read only
input - filename file to read
output - side by size ascii dump of file
deblk - read and convert mpx blocked ifile to unblocked unix file
format. Compressed and uncompressed files records can be
read. Output is an ascii string with '\n' termination.
command - deblk [filename]
input - filename or if non specified, stdin
output - ascii sting to stdout
mpxblk - Create an MPX blocked file from a '\n' terminated ascii
character string file. Trailing blanks are not deleted
from the source file. Max line size is 254 bytes.
command - mpxblk <filein >fileout
input - read ascii file from stdin
output - write mpx blocked file to stdout
renum - Create a numbered file from a '\n' terminated ascii file.
The input file is assumed to be a standard unix file. The
input lines are truncated or expaned to lines of 72 chars.
A line number in the form of XXXX.000 are appended to
create 80 char '\n' terminated lines.
command - renum <filein >fileout
input - read ascii file from stdin
output - write numbered ascii file to stdout
small - Remove line numbers and trailing blanks from an ascii '\n'
terminated file. Lines are terminated at 72 chars and then
stripped of trailing blanks. Output is '\n' terminated
ascii files.
command - small <filein >fileout
input - read ascii file from stdin
output - write stripped ascii file to stdout

213
SEL32/taptools/cutostap.c Normal file
View File

@@ -0,0 +1,213 @@
/*
* cutostap.c
*
* This program scans a metatape file and copies files until EOF is found.
* This program has the net effect of removing the sdt image from a file.
* The program will make sure 2 eof's and 1 eom are written to the tape.
* input - specified filename
* output - specified filename
*/
#include <stdio.h>
#include <sys/file.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int filen = 1;
int EOFcnt = 0;
int count=0, lcount=0;
int size=0, tsize=0;
int oldsize, newsize;
FILE *outfp;
int inp;
int ln;
/* get a line of input. */
int getloi(char *s, int lim)
{
int c, i;
int32_t n1, n2, hc, tc, n;
/* 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 */
return hc; /* return EOM */
}
/* check for EOF & EOM on tape data */
if (hc & 0xffff0000) { /* check for garbage, assume EOF */
hc = -1; /* at EOM on disk file */
return hc; /* return EOM */
}
/* check for EOF & EOM on tape data */
if (hc == 0) {
/* we are at tape EOF */
if (++EOFcnt < 2) /* if 1st EOF, print file info */
{
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
fprintf(stderr, "file %d: EOF after %d records: %d bytes\n\n", filen, count, size);
filen++; /* set next file number */
}
else
{
fprintf(stderr, "second EOF after %d files: %d bytes\n", filen-1, tsize+size);
}
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 */
return 0; /* return EOF on tape data */
}
/* check for EOM */
if (hc == -1) {
return -1; /* at EOM on disk file */
}
/* read the data */
n = read(inp, s, (size_t)hc);
if (n <= 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);
if (n2 <= 0)
return -1; /* at EOM on disk file */
count++; /* bump record count */
size += n; /* update bytes read */
EOFcnt = 0; /* not an EOF */
if (n != ln)
{
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
ln = n;
lcount = count;
}
/* return bytes in buffer */
return n;
}
void putrec(int cnt, char *buf)
{
int32_t n1, n2, nw;
int32_t hc = (cnt + 1) & ~1; /* make byte count even */
//printf("writing %d chars\n", cnt);
/* write actual byte count to 32 bit word as header */
n1 = fwrite((char *)(&hc), (size_t)1, (size_t)4, outfp);
/* write the data mod 2 */
nw = fwrite((char *)buf, (size_t)1, (size_t)hc, outfp);
/* write the byte count in 32 bit word as footer */
n2 = fwrite((char *)(&hc), (size_t)1, (size_t)4, outfp);
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
fprintf(stderr, "write (%d) failure\n", nw);
fprintf(stderr, "Operation aborted\n");
fclose(outfp);
close(inp);
free(buf);
exit(1);
}
}
int main (int argc, char *argv[])
{
char *buf;
size_t buf_size = 256 * 1024;
int ll, gotboth = 0;
int32_t zero = 0;
if (argc != 3) {
fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
exit(1);
}
/* open input file */
if ((inp = open(argv[1], O_RDONLY, 0666)) < 0) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
return (1);
}
close(inp); /* close input */
outfp = fopen(argv[1],"r"); /* reopen */
fseek(outfp, 0, SEEK_END); /* seek to end */
oldsize = ftell(outfp); /* get filesize in bytes */
fclose(outfp); /* now close it */
/* open input file */
if ((inp = open(argv[1], O_RDONLY, 0666)) < 0) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
return (1);
}
/* open output file */
outfp = fopen(argv[2],"w");
if (outfp == NULL) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[2]);
exit(1);
}
/* init counts */
// ln = -2; /* look for 2 eof */
ln = -1; /* look for 2 eof */
count = 0;
size = 0;
tsize = 0;
lcount = 0;
/* get a 256k buffer */
if ((buf = malloc(buf_size)) == NULL) {
fprintf(stderr, "Can't allocate memory for %s\n", argv[0]);
return (4);
}
/* get buffers until eof */
domore:
while ((ll=getloi(buf, buf_size)) > 0) {
//printf("got %d char\n", ll);
/* we have data to write */
putrec(ll, buf); /* write the buffer */
gotboth = 0;
}
//printf("we have EOF or EOM, DONE\n");
/* We have EOM, see if EOF's needed */
switch (gotboth) {
case 0: /* we have written no EOFs, so write two */
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
/* drop through */
case 1: /* we have written 1 EOF, so write one more */
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
/* drop through */
default:
case 2: /* we have written 2 EOFs, now do EOM */
zero = -1;
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
}
fprintf(stderr, "EOM after 2 EOFs %d files: %d bytes\n", filen-1, tsize);
newsize = ftell(outfp); /* get filesize in bytes */
fprintf(stderr, "Size of file changed from %d to %d\n", oldsize, newsize);
/* we done */
fclose(outfp);
close(inp);
free(buf);
exit(0);
}

220
SEL32/taptools/ddump.c Normal file
View File

@@ -0,0 +1,220 @@
/*
ddump - file dump utility for listing files in side-by-side hex
and ascii, plus having the option to modify the file giving
a hexadecimal byte offset into the file and the hex data
which will be written to the supplied address.
Usage is:
ddump file
where:
file1 is the file to dump and/or modify.
written by Rick Beery
modified many times by Jim Bevier
The program fd.c written by M. Kraieski has been incorporated
into this program.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void dodump();
int modify();
void modify_file();
int main(argc,args)
int argc;
char *args[];
{
FILE *fp, *fopen();
int i;
char *tempstring;
if ((argc < 2) || (argc > 3)) {
printf("usage: %s [-r] file\n", args[0]);
printf(" -r uses read-only mode\n");
exit(1);
} /* end of if */
if (argc == 3)
#ifdef mpx
/* open read and unblocked */
if (strcmp("-r",args[1]) == 0) fp = fopen(args[2],"ru");
#else
if (strcmp("-r",args[1]) == 0) fp = fopen(args[2],"r");
#endif
else {
printf("Invalid option %s ignored\n", args[1]);
#ifdef mpx
/* open read/write unblocked */
fp = fopen(args[2],"r+u");
#else
fp = fopen(args[2],"r+");
#endif
}
#ifdef mpx
/* open read/write unblocked */
else fp = fopen(args[1],"r+u");
#else
else fp = fopen(args[1],"r+");
#endif
if (fp == NULL) {
fprintf(stderr,"%s: fopen: unable to open file %s\n", args[0], args[1]);
exit(1);
} /* end of if */
dodump(fp,0);
fclose(fp);
} /* end of main */
#define PRINTABLE(x) ((x < 32) || (x > 126)) ? '.' : x
void dodump(fp, fileadr)
FILE *fp;
int fileadr;
{
char buff[257];
int file_byte_count=0, curchar, buffptr, bufflen;
buffptr = 0;
bufflen = 16;
fseek(fp,fileadr,0);
while ((curchar = getc(fp)) != EOF) {
file_byte_count++;
if (!buffptr) printf(" %06x : ",fileadr);
printf("%02x",curchar);
buff[buffptr++] = PRINTABLE(curchar);
if (!(buffptr % 4)) printf(" ");
if (buffptr >= bufflen) {
buff[buffptr] = 0;
printf(" |%s|\n",buff);
buffptr = 0;
fileadr += bufflen;
if (!(file_byte_count % 256)) {
modify_file(fp);
} /* end of if */
} /* end of if */
} /* end of while */
if (buffptr) {
buff[buffptr] = 0;
while (buffptr++ < bufflen) {
printf(" ");
if (!(buffptr % 4)) printf(" ");
} /* end of while */
printf(" |%s|\n",buff);
} /* end of if */
modify_file(fp);
return;
} /* end of dodump */
int modify(fp1)
FILE *fp1;
{
char hexstring[33];
int num_chars, digit, i, byte=0, stat, file_offset=0, indx=0;
int power();
void gethex_string();
int asciihex_digit_to_decimal();
gethex_string(hexstring);
num_chars = strlen(hexstring);
for (i=num_chars-1; i>=0; i--) {
digit = asciihex_digit_to_decimal(hexstring[indx++]);
file_offset += digit*power(16,i);
} /* end of for */
if ((fseek(fp1,file_offset,0)) != -1) {
/* read characters from the terminal */
printf("\nenter new hex data > ");
gethex_string(hexstring);
num_chars = strlen(hexstring);
/* convert character to numeric field and
new set of data at offset in file specified */
for (i=0; i<num_chars; i++) {
digit = asciihex_digit_to_decimal(hexstring[i]);
if ((i%2)) {
byte = byte*16 + digit;
fputc(byte, fp1);
byte = 0;
}
else {
byte = digit;
}
} /* end of for */
} /* end of "if" part of if - else */
else {
printf("Unable to seek to that address\n");
file_offset = 0;
} /* end of if - else */
return(file_offset);
} /* end of modify */
void gethex_string(hex)
char *hex;
{
char c;
int indx=0;
while ((c=getchar()) != '\n' ) {
if ((c>='0' && c<='9') || (c>='a' && c<='f'))
hex[indx++] = c;
else {
while ((c=getchar()) != '\n' );
indx = 0;
printf("Invalid hex number; please re-enter > ");
}
}
hex[indx] = '\0';
} /* end of gethex_string */
int asciihex_digit_to_decimal(c)
char c;
{
int digit;
if (c >= 'a' && c <= 'f') digit = c - 'a' + 10;
else if (c>= '0' && c <= '9') digit = c -'0';
else digit = -1; /* error */
return(digit);
} /* end of asciihex_digit_to_decimal */
int power(x,n)
int x, n;
{
int p;
for (p=1; n>0; --n)
p = p*x;
return (p);
} /* end of routine power */
void modify_file(fp)
FILE *fp;
{
int ans, modify(),modified_addr;
printf("\n hex address, <cr> - continue, q = quit > ");
ans = getchar();
if ((ans>='0' && ans<='9') || (ans>='a' && ans<='f')) {
ungetc(ans, stdin);
modified_addr = modify(fp);
printf("\n");
dodump(fp, (modified_addr/256)*256);
} /* end of "if" part of if - then */
else {
if (ans == 'q') {
fclose(fp);
exit(1);
}
else {
if (ans != '\n') while ((ans=getchar()) != '\n' );
}
} /* end of if -then */
} /* end of modify_file */

603
SEL32/taptools/deblk.c Normal file
View File

@@ -0,0 +1,603 @@
/*
* deblk.c
*
* This program reads MPX blocked and/or MPX compressed files and
* deblocks blocked files and uncompresses compressed files and
* deletes trailing blanks from a source file. The program will
* also process standard ASCII newline ('\n') terminated files.
* input - stdin / filename
* output - stdout
*/
/*
* MPX blocked file format
* bytes 0-1 - not used and are zero
* bytes 2-3 - next record position in buffer
* byte 4 - start/end of block flag
* - 0x20 - EOB end of block
* - 0x40 - BOB start of block
* byte 5 - last record byte count
* byte 6 - this blocks flags
* - 0x00 - valid data
* - 0x20 - EOB end of block
* - 0x80 - EOF end of file
* - 0xa0 - EOB/EOF end of file
* byte 7 - bytes in this record
* data byte - cnt data bytes
* byte cnt+4- 0x20 EOB status
* byte cnt+5- last record count
*/
/*
* Compressed record
* byte 0 - 0xbf -> start of record
* 0x9f -> start of next record
* byte 1 - record count
* byte 2 - high order byte of 16 bit checksum
* byte 3 - low order byte of 16 bit checksum
*
*/
/*
*
* AN O.S. COMPRESSED RECORD CONSISTS OF 120 BYTES:
*
* 6 CONTROL BYTES AND 114 BYTES OF COMPRESSED SOURCE
*
* (THE LAST RECORD CAN BE LESS THAN 120 BYTES, ON THAT
* RECORD THE COMPRESSED SOURCE WILL BE FROM 4-114 BYTES).
*
* 6 CONTROL BYTES
*
* 1 BYTE- DATA TYPE CODE BF OR 9F (9F MEANS THIS IS LAST RECORD)
* 1 BYTE- SIZE OF COMPRESSED RECORD (- 6 FOR CONTROL BYTES)
* (USUALLY 114 (72(X)) IS THE SIZE EXCEPT LAST RECORD)
* 2 BYTE- CHECKSUM
* 2 BYTE- RECORD SEQUENCE NUMBER (STARTING FROM ZERO)
*
* 4-114 BYTES OF ONE OR MORE GROUPS OF COMPRESSED SOURCE AS FOLLOWS:
*
* A COMPRESSED GROUP CONSISTS OF:
* A BLANK COUNT BYTE, A DATA COUNT BYTE, DATA
*
* COMPRESSED GROUPS ARE REPEATED AND TERMINATED BY AN FF CHAR.
* COMPRESSED GROUPS ARE USUALLY TERMINATED AT 114 CHARS BY
* THE FF CHAR UNLESS THIS IS THE LAST RECORD IN THE FILE
*
* A LINE OF TEXT USUALLY IS COMPRESSED AS FOLLOWS:
* A BLANK COUNT BYTE, A DATA COUNT BYTE, COMPRESSED DATA
* (ONE OR MORE OF THESE COMPRESSED GROUPS FOR UP TO 72 CHARS OF SOURCE)
* FOLLOWED BY A BLANK COUNT BYTE,A DATA COUNT BYTE (OF 8),
* DATA (8 CHAR SEQUENCE NUMBER), TERMINATED BY A FF CHAR
*
* A WORKFILE LOGICAL COMPRESSED LINE IS SIMILIAR TO THE O.S.
* LOGICAL COMPRESSED LINE EXCEPT THAT AN 8 CHAR SEQUENCE NUMBER
* ALWAYS EXISTS IN THE WORKFILE FORMAT AND IT IS ALWAYS FIRST
* RATHER THAN AT THE END OF THE RECORD (IF SEQUENCE NUMBERS DID
* NOT EXIST IN COLUMNS 73-80 IN THE O.S. ORIGINAL COMPRESSED
* RECORDS THAN THE EDITOR GENERATES THEM). PRECEDING THE WORKFILE
* COMPRESSED RECORD IS A 2 BYTE PREVIOUS RECORD IN THE PAGE POINTER.
* ALSO NOTE THAT WORKFILES ARE NOT BLOCKED BY THE O.S., BUT HAVE
* THEIR OWN STRUCTURE OF HEADERS, DATA SPACE, AND FREE SPACE.
*
* IF THE SEQUENCE NUMBER DOES NOT EXIST OR THE PERIOD IS NOT IN
* THE PROPER PLACE (NNNN.NNN) OR THE SEQUENCE NUMBER CONTAINS
* ANYTHING OTHER THAN NUMBERS, THEN THE EDITOR WILL GENERATE
* ITS OWN SEQUENCE NUMBER
*
* THE FIRST BLANK COUNT CAN RANGE FROM 0-80 BLANK CHARS
* SUBSEQUENT BLANK COUNTS CAN RANGE FROM 3-79 MAX. THAT IS
* SINCE IT TAKES 2 BYTES TO DO BLANK COMPRESSION (A BLANK COUNT
* AND A DATA COUNT), ONLY 3 OR MORE BLANK CHARS AFTER THE FIRST
* NON-BLANK CHAR IN A LINE ARE COMPRESSED.
* RECORDS TO BE COMPRESSED ARE ASSUMED TO BE 80 CHARS OR LESS
* (INCLUDING AN 8 CHAR SEQUENCE NUMBER).
*
* THE CHECKSUM IS SIMPLY THE ADDITION OF ALL THE 120 CHARS IN THE
* COMPRESSED RECORD EXCEPT FOR THE 6 CONTROL BYTES
*
* THE SMALLEST COMPRESSED LINE CONSISTS OF 14 CHARS :
* A BLANK COUNT BYTE (OF 71), A DATA COUNT BYTE (OF 8),
* DATA (AN 8 CHAR SEQUENCE NUMBER, A BLANK COUNT BYTE (OF ZERO),
* A DATA COUNT BYTE (OF 1), DATA (ONE CHAR), AND AN FF TERMINATOR
* COMPRESSED RECORD FORMAT CAN BE PROCESSED ONLY BY THE FOLLOWING:
*
* ASSEMBLER,P4,SOURCE UPDATE,EDITOR AND SOME FUNCTIONS OF MEDIA
* AND OF COURSE SOME UTILITY PROGRAMS LIKE FLIP.
*
* NOTE THAT A TEXT LINE CAN BE SPREAD ACROSS SEVERAL COMPRESSED
* RECORDS.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define BLKSIZE 768 /* MPX block file sector size */
extern int rbl();
extern int getloi(); /* right from my mind */
extern int putloi(); /* write line */
/* read file and output to stdout */
int main(argc, argv)
int argc;
char *argv[];
{
FILE *fp, *fopen();
unsigned char s[BUFSIZ];
if(argc == 1) /* no args; copy std in */
{
while (1) {
if (rbl(stdin, s, BUFSIZ) <= 0) /* read til EOF */
exit(0);
putloi(s);
}
} else {
while (--argc > 0)
if ((fp = fopen(*++argv, "r")) == NULL) {
fprintf(stderr, "list: can't open %s\n", *argv);
exit(1);
} else {
while (1) {
if (rbl(fp, s, BUFSIZ) <= 0) /* read til EOF */
exit(0);
putloi(s);
}
fclose(fp);
}
}
exit(0);
}
/*
* This function computes and checks the checksum of a compressed file
*/
int checksum(buf)
char *buf;
{
int i = 0;
// unsigned int ccs = 0; /*zero checksum */
short int ccs = 0; /*zero checksum */
unsigned int rcs = (((buf[2] << 8) & 0xff00) | (buf[3] & 0xff)); /* get checksum */
int cnt = buf[1]; /* record count */
// fprintf(stderr, "checksum data %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
while (cnt > 0) {
// unsigned int v = buf[i+6];
short v = buf[i+6] & 0xff;
ccs += v; /* add the byte */
// fprintf(stderr, "checksum cnt %x val %x sum %x\n", i, v, ccs);
i++; /* bump address */
cnt--; /* reduce count */
}
// fprintf(stderr, "checksum size %x read %x calc %x\n", buf[1], rcs, ccs);
if (ccs == rcs)
return 0; /* return OK */
return 1; /* return error */
}
int bin = 0;
unsigned char si[BLKSIZE];
unsigned char bi[BLKSIZE];
int ubdp = 0; /* unblocked data pointer */
int ubdc = 0; /* unblocked data count */
int bdp = 0; /* blocked data pointer */
int bdc = 0; /* blocked data count */
short filetype = 0;
#define unknown 0x00
#define blocked 0x01
#define compress 0x02
#define ascii 0x04
/*
* This function reads MPX blocked files
*/
int readbb(fp, ip, cnt)
FILE *fp;
char *ip;
int cnt;
{
int c;
int i = 0;
if (bin == 0) {
//fprintf(stderr, "read sector a\n");
if (fread(si, 1, BLKSIZE, fp) <= 0)
return (0); /* this means eof */
bin = 6;
}
/* check for EOF */
if (si[bin] & 0x80) {
bin = 0;
return(0); /* we have EOF */
}
/* check for EOB in last record */
if (si[bin - 2] & 0x20) {
//fprintf(stderr, "read sector b\n");
if (fread(si, 1, BLKSIZE, fp) <= 0)
return (0); /* this means eof */
bin = 6;
}
//fprintf(stderr, "copy block from sector @ bin %x\n", bin);
/* copy the block into users buffer */
if ((c = si[bin+1]) > 0) {
for (i = 0; i < c; i++) {
ip[i] = si[bin + 2 + i];
if (i >= cnt)
break;
}
bin += (c + 4);
ip[i] = '\0';
return (i);
}
bin = 0;
return (i);
}
/* function to read a byte from an unblocked file */
int getb(fp)
FILE *fp;
{
int c;
/* file is unblocked, get next record */
if (ubdp >= ubdc) { /* is count exhausted */
/* need to read next block, if not first time */
/* we need a new buffer */
/* read in 768 byte block of the file */
if ((ubdc = fread(si, 1, BLKSIZE, fp)) <= 0)
return (-1); /* this means eof */
//fprintf(stderr, "getb - read unblocked file ubdc=%x\n", ubdc);
ubdp = 0;
}
c = si[ubdp++] & 0xff; /* copy char */
return (c);
}
/* get a line of input */
int getloi(fp, s, lim) /* right from my mind */
FILE *fp;
unsigned char s[];
int lim;
{
int c, i, cc, rc = 0;
/* see how we are to process data */
if (filetype & blocked) {
/* file is blocked, get next record */
if (bdp == 0) {
/* we need a new buffer */
newbuf:
if ((bdc = readbb(fp, bi, lim)) <= 0)
return (0); /* this means eof */
//fprintf(stderr, "getloi read blocked file %x\n", bdc);
bdp = 0;
}
/* check for compressed data */
if (filetype & compress) {
if ((bi[bdp] & 0x9f) != 0x9f) {
fprintf(stderr, "blocked compressed file read error %x\n", bi[bdp]);
return (0); /* this means error */
}
/* checksum the record */
if (checksum(&bi[bdp])) {
fprintf(stderr, "blocked compressed file checksum error\n");
return (0); /* this means error */
}
//fprintf(stderr, "getloi blocked compressed file checksum OK @ %x cnt %x\n", bdp, bdc);
/* copy in the next record */
/* get chars until EOF or limit reached */
cc = bi[bdp+1]+6; /* get count */
for (i = 0; (--lim > 0) && (i < cc); i++) {
s[rc++] = bi[bdp++]; /* copy char */
}
if ((bdp >= bdc) || (i == cc)) {
bdp = 0; /* read new buffer next time */
//fprintf(stderr, "getloi blocked compressed read return %x bdc %x bdp %x\n", rc, bdc, bdp);
}
return (rc); /* return data count */
}
/* file is uncompressed, so copy MPX records */
//fprintf(stderr, "getloi blocked data rc=%x bdc=%x\n", rc, bdc);
for (i=0; i<bdc; i++)
s[rc++] = bi[bdp++]; /* copy chars */
s[rc++] = 0; /* null terminate */
bdp = 0; /* read next buffer */
return (i); /* return data */
}
else {
/* check for compressed data */
if (filetype & compress) {
cc = 120;
rc = 0;
while ((c = getb(fp)) != -1) {
/* skip any optional newline from previous record */
// if ((rc == 0) && (c == '\n'))
// continue;
/* make sure this is a compressed record */
if ((rc == 0) && ((c & 0x9f) != 0x9f)) {
fprintf(stderr, "getloi - unblocked compressed file read error %x\n", c);
return (0); /* this means error */
}
if (rc == 1)
cc = c + 6; /* get 'real' record count */
s[rc++] = c; /* save the char */
if (rc == cc)
// if (rc == 120) /* compressed is always 120 char buffers */
break; /* done */
}
if (c == -1)
return (0); /* this means EOF */
/* skip any extra chars from short records */
while ((c = getb(fp)) != '\n')
;
/* checksum the record */
if (checksum(s)) {
fprintf(stderr, "getloi - unblocked compressed file checksum error\n");
//fprintf(stderr, "getloi A unblocked compressed read return rc=%x cc=%x %x %x\n", rc, cc, s[0], s[rc-1]);
//fprintf(stderr, "getloi C unblocked compressed read return %x ubdc %x ubdp %x\n", rc, ubdc, ubdp);
return (0); /* this means error */
}
//fprintf(stderr, "getloi B unblocked compressed read return rc=%x cc=%x %x\n", rc, cc, s[1]);
return (rc); /* return data count */
}
/* file is uncompressed, so copy UNIX records */
while ((c = getb(fp)) != -1) {
s[rc++] = c; /* save the char */
if (c == 0x0a) {
//fprintf(stderr, "getloi C unblocked compressed read return %x ubdc %x ubdp %x\n", rc, ubdc, ubdp);
s[rc++] = 0; /* terminate the line */
return (rc); /* return data */
}
}
return (0); /* EOF */
}
return (0);
#ifdef JUNK
/* get chars until EOF or limit reached */
for (i = 0; (--lim > 0) && ((c = getchar()) != EOF)) {
if ((i >= 6) && ((c == 0xbf) || (c == 0x9f)))
{
ungetc(c, stdin);
return (i);
}
s[i++] = c;
if ((*s != 0xbf) && (*s != 0x9f))
{
if (c == '\n')
{
if ((s[i - 1] == '\n') && (i > 1))
{
while ((s[i - 2] == ' ') && (i > 1))
--i;
s[i - 1] = '\n';
}
s[i] = '\0';
return (i);
}
}
}
#ifdef JUNK
for (i = 0; --lim > 0 && (c = getchar()) != EOF && (s[i++] = c) != '\n';);
if ((s[i - 1] == '\n') && (i > 1))
{
while ((s[i - 2] == ' ') && (i > 1))
--i;
s[i - 1] = '\n';
}
s[i] = '\0';
#endif
return (i);
#endif
}
/*
** output line of text from the source
*/
int putloi(s)
unsigned char *s;
{
printf("%s", s);
}
unsigned char line[BUFSIZ];
int cmpop = 0;
int cmpflg = 0;
int bcnt = 0;
unsigned char *bptr = 0;
int binary = 1;
int recl = 0;
int ubin = 0;
/* read lines of data from the source file */
/* files can be blocked w/wo compression */
/* files can be blocked ascii */
/* files can be byte strings, newline terminated */
int rbl(fp, buf, n)
FILE *fp;
unsigned char *buf;
int n;
{
register int count = 0;
register unsigned char *cp;
int i;
unsigned char *linadrs = line;
if (filetype == unknown) /* see if we know type of file to read */
{
bin = 0;
ubin = 0;
bdp = 0;
bdc = 0;
ubdp = 0;
ubdc = 0;
/* read in 1st 768 Byte block of the file */
if ((ubdc = fread(si, 1, BLKSIZE, fp)) <= 0)
return (0); /* this means eof */
/* test 1st byte for 0x06 and bytes 2, 3, and 4 zero */
if ((si[0] == 0x06) && (si[1] == 0) && (si[2] == 0) && (si[3] == 0)) {
/* we have a library file, giver error and abort */
fprintf(stderr, "deblk - Cannot list library file, aborting\n");
return (0); /* this means error exit */
}
/* test for a directory file, 8 ascii char then 4 zeros */
if ((si[8] == 0) && (si[9] == 0) && (si[10] == 0) && (si[11] == 0)) {
for (i=0; i<8; i++) {
if (!isprint(si[i])) {
/* unknown file type, abort */
fprintf(stderr, "deblk - Unknown binary file type, aborting\n");
return (0); /* this means error exit */
}
}
/* must be directory, abort */
fprintf(stderr, "deblk - Cannot list directory file, aborting\n");
return (0); /* this means error exit */
}
i = ((si[2] << 8) & 0xff00) | (si[3] & 0xff); /* get file offset pointer, bytes 2 & 3 */
/* test 1st 2 byte of file for zero */
if ((si[0] == 0) && (si[1] == 0) && (i < BLKSIZE)) {
/* most likely blocked file if 1st 2 bytes 0 and next 2 bytes are less than 768 */
filetype |= blocked; /* we have blocked file */
bin = 6; /* where we start for data block */
/* see if we have compressed data */
if ((si[bin + 2] == 0xbf) || (si[bin + 2] == 0x9f))
{
filetype |= compress; /* data is compressed */
bcnt = 0; /* no data in buffer */
}
else
{
/* data is not compressed, just ascii without newlines */
filetype |= ascii; /* blocked ascii data */
}
}
else
{
/* data is unblocked, see if compressed or not */
if ((si[ubin] == 0xbf) || (si[ubin] == 0x9f))
{
filetype |= compress; /* data is compressed */
bcnt = 0; /* no data in buffer */
}
else
if ((si[ubin] == 0xef) || (si[ubin] == 0xcf))
{
/* file is an macro library, so abort */
fprintf(stderr, "deblk - Cannot list macro library file, aborting\n");
return (0); /* this means error exit */
}
else
{
/* data is not compressed or blocked, just ascii with newlines */
filetype |= ascii; /* blocked ascii data */
}
}
}
if ((filetype & compress) && !cmpop) { /* see if we tested for compressed */
cmpop = 1; /* set comp tested flag */
/* read in the first record */
if ((recl = getloi(fp, line, BUFSIZ)) == 0)
return (0); /* this means eof */
linadrs = line;
if (*linadrs == 0xbf)
{ /* is this file compressed */
cmpflg = 1; /* set comp data flag */
bcnt = linadrs[1]; /* set record count */
bptr = &linadrs[6]; /* set data address */
//fprintf(stderr, "rbl - read 1st compressed record cnt %x %x\n", bcnt, linadrs[0]);
}
else
goto re00;
}
if (cmpflg) { /* reading compressed data? */
if (bcnt == 0) { /* any data left in buffer */
re18:
/* read in a data record */
if ((recl = getloi(fp, line, BUFSIZ)) == 0)
return (0); /* this means eof */
linadrs = line;
//fprintf(stderr, "rbl re18 - read compressed record cnt %x %x\n", bcnt, linadrs[0]);
if ((*linadrs & 0x9f) != 0x9f) /* is this valid rec */
return (EOF); /* error if not */
bcnt = linadrs[1]; /* set record count */
bptr = &linadrs[6]; /* set data address */
//fprintf(stderr, "rbl - read nth compressed record cnt %x %x\n", bcnt, linadrs[0]);
}
re20:
/* see if any blanks */
if (i = *bptr++) { /* next buffer pointer */
if (i == 0xff)
goto re60; /* if eol, get out */
while (i--) {
if (count < n) {
*buf++ = ' '; /* put blank in buffer */
count++;
}
}
}
if (--bcnt <= 0)
goto re18; /* read next record */
/* get character count */
if (i = *bptr++) { /* next buffer pointer */
while (i--) {
if (count < n)
*buf++ = *bptr; /* put char in buffer */
bcnt--; /* decr count */
bptr++; /* next buffer pointer */
count++;
}
}
if (--bcnt <= 0)
goto re18; /* read next record */
goto re20;
re60:
bcnt--; /* decr count */
if ((*--buf == ' ') && (count == 1)) {
*buf = '\n'; /* put new line at eol */
}
else {
*++buf = '\n'; /* put new line at eol */
count++;
}
}
else {
/* non compressed read here */
/* read the next record */
if ((recl = getloi(fp, line, BUFSIZ)) == 0)
return (0); /* this means eof */
linadrs = line; /* reset line pointer */
re00:
//fprintf(stderr, "rbl - read nth uncompressed record cnt %x %s\n", recl, line);
#if 0
/* here we need to strip off blank put in during write */
/* this is because mpx does not support zero length blocks */
if ((recl == 1) && (*linadrs == ' ')) {
recl = 0;
/* now append new line to end of buffer */
if (!binary)
line[recl] = '\n';
}
#endif
count = 0;
/* copy this layer buffer to upper caller's buffer */
while ((count < n) && (count < recl)) {
buf[count] = line[count];
count++;
}
/* if no newline, add one and null terminate */
if (line[count-1] != '\n')
buf[count++] = '\n';
buf[count] = '\0';
}
//fprintf(stderr, "rbl - read return cnt %x %s\n", count, line);
return (count);
}

357
SEL32/taptools/diskload.c Normal file
View File

@@ -0,0 +1,357 @@
/*
* diskload.c
*
* This program reads an MPX load module and stores it into the
* sumulated diskfile. The SMD entry is changed to reflect the
* new file entry.
* input - filename
* - simulated diskfile
* output - modified diskfile with SMD entry modified
* 08/11/2018
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define BLKSIZE 768 /* MPX file sector size */
unsigned char os[BLKSIZE * 100]; /* O/S code */
/* read program file and output to simulated mpx1.x diskfile using filemgr format */
/* dload file diskfile */
int main(argc, argv)
int argc;
char *argv[];
{
FILE *fp, *dp, *fopen();
unsigned char si[BUFSIZ];
char *p;
int i, j;
#define DOLIST 1
#define DOADD 2
unsigned int option = DOLIST; /* what to do */
unsigned char *fnp; /* file name pointer */
unsigned int size; /* size in 768 byte sectors */
unsigned int word,tmp; /* just a temp word variable */
unsigned char name[9]; /* LM name */
unsigned int lmname[2], passwd[2];
unsigned int smds; /* size of smd */
unsigned int smdd[2]; /* SMD space definition */
unsigned char *smd;
unsigned int hash1; /* SMD hash value for name */
unsigned int udtp; /* UDT pointer */
unsigned int *mptr; /* word ptr for SMD entries */
unsigned int boff;
unsigned int rem;
unsigned int blk;
unsigned int lmblk; /* sector addess of load module on disk */
unsigned int smdudt; /* smd udt index */
unsigned int spau; /* sectors per allocation unit */
unsigned int fileau; /* file size in allocation units */
unsigned int auptr; /* pointer to allocation unit on disk */
unsigned int lsblk; /* lowest block address of SMD entries */
if (argc <= 1) { /* see if correct # args */
// fprintf(stderr, "Error: incorrect number of parameters\n");
fprintf(stderr, "Usage: %s -la program diskfile\n", *argv);
exit(1);
}
if (--argc > 0) {
p = *++argv;
// printf("argv %s\n", p);
if (*p++ == '-') {
while (*p != '\0') {
switch (*p++) {
case 'l':
case 'L':
option |= DOLIST;
break;
case 'A':
case 'a':
option |= DOADD;
break;
default:
// fprintf(stderr, "Error: incorrect option %c specified\n", *--p);
fprintf(stderr, "Usage: %s -la program diskfile\n", *--argv);
exit(1);
break;
}
}
if (*--p == '-') {
fprintf(stderr, "Error: no option specified\n");
fprintf(stderr, "Usage: %s -la program diskfile\n", *--argv);
exit(1);
}
}
else {
argc++;
argv--;
}
if (--argc > 0) {
p = *++argv;
// printf("argv2 %s\n", p);
if ((fp = fopen(*argv, "r")) == NULL) {
fprintf(stderr, "error: can't open load module %s\n", *argv);
exit(1);
}
fnp = *argv; /* get file name pointer */
fseek(fp, 0, SEEK_END); /* seek to end */
word = ftell(fp); /* get filesize in bytes */
fseek(fp, 0, SEEK_SET); /* rewind file */
}
}
if (--argc <= 0) {
fprintf(stderr, "Error: incorrect number of parameters\n");
fprintf(stderr, "Usage: %s -la program diskfile\n", *argv);
exit(1);
}
/* open diskfile */
if ((dp = fopen(*++argv, "r+")) == NULL) {
fprintf(stderr, "error: can't open disk file %s\n", *argv);
exit(1);
}
/* determine size of file */
size = word/BLKSIZE; /* get sector count */
if ((word % BLKSIZE) != 0)
size++; /* add in 1 for partial sector */
/* size now has load module size in sectors */
/* we need the file name and password for entry */
for (i=0; i<8; i++)
name[i] = 0x20; /* pre blank name */
name[8] = '\0'; /* NULL terminate */
for (i=0; (i<8) && (fnp[i] != 0); i++)
name[i] = toupper(fnp[i]); /* upper case name */
// fprintf(stderr, "file %s is size %d sectors\n", name, size);
lmname[0] = (name[0] << 24) | (name[1] << 16) | (name[2] << 8) | (name[3]);
lmname[1] = (name[4] << 24) | (name[5] << 16) | (name[6] << 8) | (name[7]);
passwd[0] = passwd[1] = 0; /* no password */
/* the disk data has the O/S starting at 0x780 in the file */
/* add 0x780 to any O/S location you want to load */
/* C.SMDS (#smd entries) is at 0xb00 + 0x780 = 0x1280 */
/* read the O/S diskfile into buffer, 7680 bytes */
// fprintf(stderr, "reading 100*BLKSIZE bytes from disk\n", 100*BLKSIZE);
if (fread(os, 1, BLKSIZE*100, dp) <= 0)
return (0); /* this means bad read */
smds = (os[0x780+0xb00] << 24) | (os[0x780+0xb01] << 16) | (os[0x780+0xb02] << 8) | (os[0x780+0xb03]);
/* get udt index for SMD location */
smdudt = (os[0x780+0xc2c] << 8) | (os[0x780+0xc2d]);
/* udt size id 0x40, C.UDTA is at 0xb40 */
word = (os[0x780+0xb40] << 24) | (os[0x780+0xb41] << 16) | (os[0x780+0xb42] << 8) | (os[0x780+0xb43]);
udtp = (smdudt * 0x40 + word); /* get udt address */
/* spau is in byte 0x0f of udt */
spau = os[0x780+udtp+0x0f] & 0xff; /* get word with spau */
/* get file size in au's */
fileau = size / spau; /* get number of au's required for file */
if ((size % spau) != 0)
fileau++; /* round up to next au of overflow */
fprintf(stderr, "file %s is size %d sectors (%d au) requiring %d sectors on disk\n",
name, size, fileau, fileau*spau);
// fprintf(stderr, "UDTP 0x%x SPAU 0x%x\n", udtp, spau); /* display udtp & spau */
fprintf(stderr, "C.SMDS(0xB00) - SMD size is 0x%x %d entries C.SMDUDT is %x\n", smds, smds, smdudt);
/* get SMD space definition */
smdd[0] = (os[0x780+0x840] << 24) | (os[0x780+0x841] << 16) | (os[0x780+0x842] << 8) | (os[0x780+0x843]);
smdd[1] = (os[0x780+0x844] << 24) | (os[0x780+0x845] << 16) | (os[0x780+0x846] << 8) | (os[0x780+0x847]);
fprintf(stderr, "C.SMDD(0x840) - SMD space definition wd0 0x%x wd1 0x%x wd0 %d wd1 %d entries %d\n",
smdd[0], smdd[1], smdd[0] ,smdd[1], smdd[1] * 24);
fprintf(stderr, "SMD space def: blk 0x%x seek 0x%x size 0x%x (%d)\n",
smdd[0], smdd[0]*BLKSIZE, smdd[1], smdd[1]);
/* rewind the disk */
fseek(dp, 0, 0); /* seek home */
/* seek to the smd */
fseek(dp, smdd[0]*BLKSIZE, 0); /* seek smd */
if ((smd = (unsigned char *)malloc(smdd[1] * BLKSIZE)) < 0)
return (0); /* this means bad read */
/* read the SMD into memory */
if (fread(smd, 1, smdd[1]*BLKSIZE, dp) <= 0)
return (0); /* this means bad read */
/* use lowest space definition from SMD entries */
lsblk = smdd[0]; /* set lowest to start of SMD */
/* loop through the SMD looking for a match to the load module name */
for (i=0; i<(smds*32); i+=32) {
unsigned int sblk, len, udt, pw;
int yep = 0;
for (j=0; j<8; j++) {
if (smd[i+j] != 0) {
fprintf(stderr, "%c", smd[i+j]);
yep = 1;
}
}
if (yep) {
int bit;
unsigned int lmn[2]; /* load module name */
sblk = (smd[i+8] << 24) | (smd[i+9] << 16) | (smd[i+10] << 8) | (smd[i+11]);
if ((sblk & 0xffffff) < lsblk)
lsblk = sblk & 0xffffff;/* save the new lowest address */
len = (smd[i+12] << 24) | (smd[i+13] << 16) | (smd[i+14] << 8) | (smd[i+15]);
pw = (smd[i+24] << 8) | (smd[i+25]);
udt = (smd[i+26] << 8) | (smd[i+27]);
/* hash the name to see if pointer is to current SMD entry */
mptr = (unsigned int *)smd; /* get word pointer for SMD data */
j = i/32; /* offset in SMD file (entry #) */
lmn[0] = mptr[j*8]; /* get filename first 4 chars to R5 and shift right circular by 1 */
word = ((lmn[0] & 0xff) << 24) | ((lmn[0] & 0xff00) << 8) |
((lmn[0] & 0xff0000) >> 8) | ((lmn[0] & 0xff000000) >> 24);
bit = word & 1; /* save bit 31 */
word = word >> 1; /* shift right 1 */
if (bit)
word |= 0x80000000; /* copy old bit 31 to bit 0 */
lmn[1] = mptr[j*8+1]; /* get 2nd 4 chars of filename */
rem = ((lmn[1] & 0xff) << 24) | ((lmn[1] & 0xff00) << 8) |
((lmn[1] & 0xff0000) >> 8) | ((lmn[1] & 0xff000000) >> 24);
word = word ^ rem; /* EOR with 2nd half of load module name */
rem = word % smds; /* get remainder as relative entry number */
fprintf(stderr, " entry %d (calc %d) off 0x%x typ 0x%x blk 0x%x len 0x%x, pw 0x%x udt 0x%x\n",
j, rem, (sblk & 0xffffff)*BLKSIZE, sblk>>24, sblk, len, pw, udt);
// fprintf(stderr, "offset index %d calc %d\n", i/32, rem); /* display entry # */
}
}
/* see if user want list only */
if ((option & DOLIST) && !(option & DOADD))
goto doexit; // getout
#if 0
/* get file size in au's */
fileau = size / spau; /* get number of au's required for file */
if ((size % spau) != 0)
fileau++; /* round up to next au of overflow */
#endif
/* lsblk has the lowest space definition from SMD entries */
lmblk = lsblk - fileau * spau; /* get sector address of where to store lm */
fprintf(stderr, "lmblk 0x%x lsblk 0x%x fileau 0x%x spau 0x%x\n", lmblk, lsblk, fileau, spau);
/* hash filename into SMD entry number */
fprintf(stderr, "1 hashing lmname[0] %x lmname[1] %x\n", lmname[0], lmname[1]);
word = lmname[0]; /* get filename first 4 chars to R5 and shift right circular by 1 */
i = word & 1; /* save bit 31 */
word = word >> 1; /* shift right 1 */
if (i)
word |= 0x80000000; /* copy old bit 31 to bit 0 */
word = word ^ lmname[1]; /* EOR with 2nd half of load module name */
hash1 = word / smds; /* calc SMD hash number and save */
rem = word % smds; /* get remainder as relative entry number */
/* get relative 192W block in SMD */
blk = rem/24; /* divide entry # by # entries/block */
boff = (rem%24) * 32; /* get byte offset in block of entry */
tmp = (blk * 24 + (boff/32)); /* make word offset in smd array */
fprintf(stderr, "hash1 %x rem %x blk 0x%x %d boff %x index %d\n", hash1, rem, blk, blk, boff, tmp);
/* populate the 32 byte SMD entry */
/* smd has entire SMD in memory */
tmp = (blk * BLKSIZE + boff) >> 2; /* make word offset in smd array */
mptr = (unsigned int *)smd; /* get word pointer for smd data */
/* word 1 and 2 has filename */
blk = lmname[0]; /* 1st 4 char of lmname */
word = ((blk & 0xff) << 24) | ((blk & 0xff00) << 8) | ((blk & 0xff0000) >> 8) | ((blk & 0xff000000) >> 24);
mptr[tmp] = word; /* set 1st 4 char of name */
blk = lmname[1]; /* set 2nd 4 char of name */
word = ((blk & 0xff) << 24) | ((blk & 0xff00) << 8) | ((blk & 0xff0000) >> 8) | ((blk & 0xff000000) >> 24);
mptr[tmp+1] = word; /* set 2nd 4 char of name */
// blk = 0xca000000 | lmblk; /* type ca and blk address */
blk = 0xee000000 | lmblk; /* type ca and blk address */
word = ((blk & 0xff) << 24) | ((blk & 0xff00) << 8) | ((blk & 0xff0000) >> 8) | ((blk & 0xff000000) >> 24);
mptr[tmp+2] = word; /* set type and blk addr */
/* size now has load module size in sectors */
blk = 0x80000000 | size; /* file flags and size */
word = ((blk & 0xff) << 24) | ((blk & 0xff00) << 8) | ((blk & 0xff0000) >> 8) | ((blk & 0xff000000) >> 24);
mptr[tmp+3] = word; /* set flags and size */
mptr[tmp+4] = 0; /* no username */
mptr[tmp+5] = 0; /* no username */
blk = 0x00000000 | smdudt; /* no password and smd udt */
word = ((blk & 0xff) << 24) | ((blk & 0xff00) << 8) | ((blk & 0xff0000) >> 8) | ((blk & 0xff000000) >> 24);
mptr[tmp+6] = word; /* set password and udt index */
mptr[tmp+7] = 0; /* not used */
/* loop through the SMD looking for a match to the load module name */
for (i=0; i<(smds*32); i+=32) {
unsigned int sblk, len, udt, pw;
int yep = 0;
for (j=0; j<8; j++) {
if (smd[i+j] != 0) {
fprintf(stderr, "%c", smd[i+j]);
yep = 1;
}
}
if (yep) {
int bit;
unsigned int lmn[2]; /* load module name */
sblk = (smd[i+8] << 24) | (smd[i+9] << 16) | (smd[i+10] << 8) | (smd[i+11]);
len = (smd[i+12] << 24) | (smd[i+13] << 16) | (smd[i+14] << 8) | (smd[i+15]);
pw = (smd[i+24] << 8) | (smd[i+25]);
udt = (smd[i+26] << 8) | (smd[i+27]);
#if 0
fprintf(stderr, " entry %d blk # 0x%x off 0x%x len 0x%x, pw 0x%x udt 0x%x\n",
i/32, sblk, (sblk & 0xffffff) * BLKSIZE, len, pw, udt);
/* udt size id 0x40, C.UDTA is at 0xb40 */
word = (os[0x780+0xb40] << 24) | (os[0x780+0xb41] << 16) | (os[0x780+0xb42] << 8) | (os[0x780+0xb43]);
udtp = (udt * 0x40 + word); /* get udt address */
fprintf(stderr, "UDTP 0x%x\n", udtp); /* display word */
/* spau is in byte 0x0f */
spau = os[0x780+udtp+0x0f] & 0xff; /* get word with spau */
fprintf(stderr, "SPAU 0x%x\n", spau); /* display spau */
#endif
/* hash the name to see if pointer is to current SMD entry */
mptr = (unsigned int *)smd; /* get word pointer for SMD data */
j = i/32; /* offset in SMD file (entry #) */
lmn[0] = mptr[j*8]; /* get filename first 4 chars to R5 and shift right circular by 1 */
word = ((lmn[0] & 0xff) << 24) | ((lmn[0] & 0xff00) << 8) |
((lmn[0] & 0xff0000) >> 8) | ((lmn[0] & 0xff000000) >> 24);
bit = word & 1; /* save bit 31 */
word = word >> 1; /* shift right 1 */
if (bit)
word |= 0x80000000; /* copy old bit 31 to bit 0 */
lmn[1] = mptr[j*8+1]; /* get 2nd 4 chars of filename */
rem = ((lmn[1] & 0xff) << 24) | ((lmn[1] & 0xff00) << 8) |
((lmn[1] & 0xff0000) >> 8) | ((lmn[1] & 0xff000000) >> 24);
word = word ^ rem; /* EOR with 2nd half of load module name */
rem = word % smds; /* get remainder as relative entry number */
fprintf(stderr, " entry %d (calc %d) off 0x%x typ 0x%x blk 0x%x len 0x%x, pw 0x%x udt 0x%x\n",
j, rem, (sblk & 0xffffff)*BLKSIZE, sblk>>24, sblk, len, pw, udt);
// fprintf(stderr, "offset index %d calc %d\n", i/32, rem); /* display entry # */
}
}
fprintf(stderr, "file space def: blk 0x%x seek 0x%x size 0x%x %d\n", lmblk, lmblk*BLKSIZE, size, size);
if (option & DOADD) { /* see if user wants file written to disk */
/* write the load module to disk */
/* rewind the disk */
fseek(dp, 0, 0); /* seek home */
/* seek to where the load module is to be stored */
fseek(dp, lmblk*BLKSIZE, 0); /* seek sector for saving load module */
/* rewind the load module */
fseek(fp, 0, 0); /* seek home */
/* copy all of the sectors */
for (i=0; i<size; i++) {
/* read a block of the load module */
if (fread(si, 1, BLKSIZE, fp) <= 0)
return (0); /* this means eof */
/* write it to the disk file */
if (fwrite(si, 1, BLKSIZE, dp) <= 0)
return (0); /* this means eof */
}
/* write the updated smd to disk */
/* rewind the disk */
fseek(dp, 0, 0); /* seek home */
/* seek to the smd */
fseek(dp, smdd[0]*BLKSIZE, 0); /* seek smd */
/* write the SMD from memory to disk */
if (fwrite(smd, 1, smdd[1]*BLKSIZE, dp) <= 0)
return (0); /* this means bad write */
}
doexit:
fclose(fp);
fclose(dp);
exit(0);
}

225
SEL32/taptools/eomtap.c Normal file
View File

@@ -0,0 +1,225 @@
/*
* eomtap.c
*
* This program scans a metatape file and copies files until EOM is found.
* The program will make sure 2 eof's and 1 eom are written to the tape.
* input - specified filename
* output - specified filename
*/
#include <stdio.h>
#include <sys/file.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int filen = 1;
int EOFcnt = 0;
int count=0, lcount=0;
int size=0, tsize=0;
int oldsize, newsize;
FILE *outfp;
int inp;
int ln;
/* get a line of input. */
int getloi(char *s, int lim)
{
int c, i;
int32_t n1, n2, hc, tc, n;
/* 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 */
return hc; /* return EOM */
}
/* check for EOF & EOM on tape data */
if (hc & 0xffff0000) { /* check for garbage, assume EOF */
hc = -1; /* at EOM on disk file */
return hc; /* return EOM */
}
/* check for EOF & EOM on tape data */
if (hc == 0) {
/* we are at tape EOF */
if (++EOFcnt < 2) /* if 1st EOF, print file info */
{
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
fprintf(stderr, "file %d: EOF after %d records: %d bytes\n\n", filen, count, size);
filen++; /* set next file number */
}
else
{
fprintf(stderr, "second EOF after %d files: %d bytes\n", filen-1, tsize+size);
}
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 */
return 0; /* return EOF on tape data */
}
/* check for EOM */
if (hc == -1) {
return -1; /* at EOM on disk file */
}
/* read the data */
n = read(inp, s, (size_t)hc);
if (n <= 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);
if (n2 <= 0)
return -1; /* at EOM on disk file */
count++; /* bump record count */
size += n; /* update bytes read */
EOFcnt = 0; /* not an EOF */
if (n != ln)
{
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
ln = n;
lcount = count;
}
/* return bytes in buffer */
return n;
}
void putrec(int cnt, char *buf)
{
int32_t n1, n2, nw;
int32_t hc = (cnt + 1) & ~1; /* make byte count even */
//printf("writing %d chars\n", cnt);
/* write actual byte count to 32 bit word as header */
n1 = fwrite((char *)(&hc), (size_t)1, (size_t)4, outfp);
/* write the data mod 2 */
nw = fwrite((char *)buf, (size_t)1, (size_t)hc, outfp);
/* write the byte count in 32 bit word as footer */
n2 = fwrite((char *)(&hc), (size_t)1, (size_t)4, outfp);
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
fprintf(stderr, "write (%d) failure\n", nw);
fprintf(stderr, "Operation aborted\n");
fclose(outfp);
close(inp);
free(buf);
exit(1);
}
}
int main (int argc, char *argv[])
{
char *buf;
size_t buf_size = 256 * 1024;
int ll, gotboth = 0;
int32_t zero = 0;
if (argc != 3) {
fprintf(stderr, "usage: %s infile outfile\n", argv[0]);
exit(1);
}
/* open input file */
if ((inp = open(argv[1], O_RDONLY, 0666)) < 0) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
return (1);
}
close(inp); /* close input */
outfp = fopen(argv[1],"r"); /* reopen */
fseek(outfp, 0, SEEK_END); /* seek to end */
oldsize = ftell(outfp); /* get filesize in bytes */
fclose(outfp); /* now close it */
/* open input file */
if ((inp = open(argv[1], O_RDONLY, 0666)) < 0) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
return (1);
}
/* open output file */
outfp = fopen(argv[2],"w");
if (outfp == NULL) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[2]);
exit(1);
}
/* init counts */
ln = -2; /* look for 2 eof */
count = 0;
size = 0;
tsize = 0;
lcount = 0;
/* get a 256k buffer */
if ((buf = malloc(buf_size)) == NULL) {
fprintf(stderr, "Can't allocate memory for %s\n", argv[0]);
return (4);
}
/* get buffers until eof */
domore:
while ((ll=getloi(buf, buf_size)) > 0) {
//printf("got %d char\n", ll);
/* we have data to write */
putrec(ll, buf); /* write the buffer */
gotboth = 0;
}
//printf("we have EOF %d\n", gotboth+1);
/* we have an EOF or an EOM */
if (ll == 0) {
/* we have EOF, write a zero */
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
gotboth++; /* one more EOF */
if (gotboth == 2) {
/* we have written both EOF's, now write EOM */
ll = -1;
} else {
goto domore; /* get more data */
}
}
//printf("we have EOM, DONE\n");
/* We have EOM, see if EOF's needed */
switch (gotboth) {
case 0: /* we have written no EOFs, so write two */
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
/* drop through */
case 1: /* we have written 1 EOF, so write one more */
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
/* drop through */
default:
case 2: /* we have written 2 EOFs, now do EOM */
zero = -1;
fwrite((char *)(&zero), (size_t)1, (size_t)4, outfp);
}
fprintf(stderr, "EOM after 2 EOFs %d files: %d bytes\n", filen-1, tsize);
newsize = ftell(outfp); /* get filesize in bytes */
fprintf(stderr, "Size of file changed from %d to %d\n", oldsize, newsize);
/* we done */
fclose(outfp);
close(inp);
free(buf);
exit(0);
}

348
SEL32/taptools/filelist.c Normal file
View File

@@ -0,0 +1,348 @@
/*
* filelist.c
*
* This program scans a metatape file and prints file count and sizes.
* input - stdin or specified filename
* output - stdout
*/
#define NOTDUMP
#include <stdio.h>
#include <sys/file.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
int filen = 1;
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;
#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)sizeof(hc));
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 */
{
#ifdef NOTDUMP
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
fprintf(stderr, "file %d: eof after %d records: %d bytes\n", filen, count, size);
#endif
filen++; /* set next file number */
}
else
{
#ifdef NOTDUMP
fprintf(stderr, "second eof after %d files: %d bytes\n", filen, size);
#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 = -1; /* set ln to -1 showing we are at EOF */
/* we have EOF */
return 0; /* return EOF on tape data */
}
if (hc == -1)
{
#ifdef NOTDUMP
/* we have EOM */
fprintf(stderr, "mpx eot\n");
/* print out total tape size in bytes */
fprintf(stderr, "total length: %ld bytes\n", tsize);
#endif
return -1; /* at EOM on disk file */
}
/* read the data */
n = read(inp, s, (size_t)hc);
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)sizeof(tc));
count++; /* bump record count */
size += n; /* update bytes read */
EOFcnt = 0; /* not an EOF */
if (n != ln)
{
#ifdef NOTDUMP
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
#endif
ln = n;
lcount = count;
}
/* return bytes in buffer */
return n;
}
int main (int argc, char *argv[])
{
// char in[BUFSIZ], out[BUFSIZ];
char *buf;
size_t size_512K = 512 * 1024;
size_t buf_size = 512 * 1024;
char *cp, *np;
int ll, gotboth = 0;
int lfilen = filen;
unsigned int fileaddr, file_byte_count=0, curchar, buffptr, bufflen;
int skipfile = 0;
if (argc != 2)
{
fprintf(stderr, "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]);
return (1);
}
/* get a 512k buffer */
if ((buf = malloc(buf_size)) == NULL)
{
fprintf(stderr, "Can't allocate memory for %s\n", argv[0]);
return (4);
}
/* init counts */
ln = -2; /* look for 2 eof */
count = 0;
size = 0;
tsize = 0;
lcount = 0;
filen = 1;
lfilen = filen;
buffptr = 0;
bufflen = 16;
fileaddr = 0;
file_byte_count = 0;
printf("\nfile %d:\n", filen);
/* get lines until eof */
while ((ll=getloi(buf, buf_size)) != EOF)
{
if (ll == 0)
{
/* eof found, process new file */
skipfile = 0;
file_byte_count = 0;
fileaddr = 0;
printf("\nfile %d:\n", filen);
}
else
{
int cc = 0;
buffptr = 0;
char buff[257];
int ans;
{
/* dump first 2 words */
int w1, w2, i, j;
char path[64], command[128];
w1 = (buf[0] & 0xff) << 24 | buf[1] << 16 | buf[2] << 8 | (buf[3] & 0xff);
w2 = (buf[4] & 0xff) << 24 | buf[5] << 16 | buf[6] << 8 | (buf[7] & 0xff);
if (filen > 480)
printf("w1 = %x, w2 = %d count = %d\n", w1, w2, count);
if (count == 1 && w1 == 1)
{
char file[20], dir[20], vol[20];
int off = 8;
int l = 0;
/* we have directory entries */
for (j=0; j<w2; j++)
{
int k = l++ * 48;
if (k > (6144-48-off))
{
ll=getloi(buf, buf_size);
off = 0;
l = 0;
k = 0;
printf("reread: got ll= %d\n", ll);
for (i=0; i<16; i++)
{
file[i] = tolower(buf[k+off+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[16] = '\0';
printf("file %s\n", file);
}
for (i=0; i<16; i++)
{
file[i] = tolower(buf[k+off+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[16] = '\0';
for (i=0; i<16; i++)
{
dir[i] = tolower(buf[k+off+16+i]);
if (dir[i] == ' ')
dir[i] = '\0';
}
dir[16] = '\0';
for (i=0; i<16; i++)
{
vol[i] = tolower(buf[k+off+32+i]);
if (vol[i] == ' ')
vol[i] = '\0';
}
vol[16] = '\0';
sprintf(path, "./%s/%s", vol, dir);
/* create the directory/file */
// sprintf(command, "mkdir -p %s", path);
// system(command);
sprintf(path, "./%s/%s/%s", vol, dir, file);
printf("path %s\n", path);
sprintf(command, "touch %s", path);
// system(command);
}
} else
if (count == 1 && w1 == 2 && w2 == 0)
{
char file[20], dir[20], vol[20];
/* process file definition */
/* we have a file definition entry */
for (i=0; i<16; i++)
{
file[i] = tolower(buf[8+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[16] = '\0';
for (i=0; i<16; i++)
{
dir[i] = tolower(buf[24+i]);
if (dir[i] == ' ')
dir[i] = '\0';
}
dir[16] = '\0';
for (i=0; i<16; i++)
{
vol[i] = tolower(buf[40+i]);
if (vol[i] == ' ')
vol[i] = '\0';
}
vol[16] = '\0';
sprintf(path, "./%s/%s/%s", vol, dir, file);
printf("path2 = %s\n", path);
}
}
/* see if skipping to next file */
if (skipfile == 1)
{
continue;
}
#ifdef NODUMP
/* process the returned buffer */
while (cc < ll)
{
curchar = (unsigned int)buf[cc++] & 0xff;
file_byte_count++;
if (!buffptr)
printf(" %06x : ",fileaddr);
printf("%02x", curchar & 0xff);
buff[buffptr++] = PRINTABLE(curchar);
if (!(buffptr % 4))
printf(" ");
if (buffptr >= bufflen)
{
buff[buffptr] = 0;
printf(" |%s|\n",buff);
buffptr = 0;
fileaddr += bufflen;
if (!(file_byte_count % 256))
{
printf("\n<cr> - continue, q = quit, s = skip > ");
ans = getchar();
if (ans == 'q')
{
close(inp);
free(buf);
exit(1);
}
if (ans == 's')
skipfile = 1;
if (ans != '\n')
while ((ans=getchar()) != '\n' )
;
} /* end of if */
if (skipfile == 1)
break;
} /* end of if */
} /* end of while */
#endif
#ifdef NODUMP
if (buffptr && !skipfile)
{
buff[buffptr] = 0;
while (buffptr++ < bufflen)
{
printf(" ");
if (!(buffptr % 4))
printf(" ");
} /* end of while */
printf(" |%s|\n",buff);
/* see what user wants to do */
printf("\n<cr> - continue, q = quit > ");
ans = getchar();
if (ans == 'q')
{
close(inp);
free(buf);
exit(1);
}
if (ans != '\n')
while ((ans=getchar()) != '\n' )
;
} /* end of if */
#endif
}
}
close(inp);
free(buf);
exit(0);
}

288
SEL32/taptools/fmgrcopy.c Normal file
View File

@@ -0,0 +1,288 @@
/*
* fmgrcopy.c
*
* This program scans a metatape file and prints file count and sizes.
* In addition, it creats a director for each username specified in
* the filemanager tape and then creates a file containing the file
* contents. The file must be an filemgr save tape and not an SDT
* tape.
* 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 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;
int32_t n1, n2, hc, tc, n;
errno = 0;
/* read the byte count in 32 bit word as header */
n1 = read(inp, (char *)(&hc), (size_t)sizeof(hc));
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 */
lfilen = filen;
filen++; /* set next file number */
}
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)
return -1; /* at EOM on disk file */
/* read the data */
n = read(inp, s, (size_t)hc);
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)sizeof(tc));
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];
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) {
if (ll == 0) {
/* eof found, process new file */
printf("\nfile %d:\n", filen);
} else {
int cc = 0;
unsigned int curchar;
/* 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. */
int i, j, m;
// if (filen == 1)
{
/* read smd entry */
char file[20], dir[20];
int l = 0;
int smddone = 0;
int totent = 0;
char *buf2 = buf;
printf("\nfile %d:\n", filen);
/* see how man 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
printf("read (%d) on file %s\n", ll, 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);
}

178
SEL32/taptools/makefile Normal file
View File

@@ -0,0 +1,178 @@
# Makefile for taptools
SHELL = /bin/sh
# Adapt the flags in the following paragraph to your system
# for Linux
ROOT = .
OPTC = -O #-m32
#B = $(ROOT)
#B = $(ROOT)/bin
B = /system/bin
#I = $(ROOT)/include
I =
#L = $(ROOT)/lib
#D = $L/mylib.a
D =
##CFLAGS= $(OPTC) -I$I
CFLAGS= $(OPTC) -I$I -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
# For Linux
#LFLAGS= -L$L
LFLAGS=
PROGS = \
$(ROOT)/diskload \
$(ROOT)/filelist \
$(ROOT)/fmgrcopy \
$(ROOT)/mkfmtape \
$(ROOT)/sdtfmgrcopy \
$(ROOT)/tapdump \
$(ROOT)/tape2disk \
$(ROOT)/tapscan \
$(ROOT)/eomtap \
$(ROOT)/volmcopy \
$(ROOT)/ddump \
$(ROOT)/deblk \
$(ROOT)/mpxblk \
$(ROOT)/renum \
$(ROOT)/cutostap \
$(ROOT)/small
all: $(PROGS)
#install :$(PROGS)
# @cp $(@F) $B
# @echo $(@F) installed in $B
# @echo
## @chmod 755 $(@F)
##$(PROGS): $D $$(@F).c
## @-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
##$(PROGS): $D $$(@F).c
## @chmod 755 $@
## @cp $(@F) $B
## @echo $(@F) installed in $B
## @echo
$B/diskload: $D diskload.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/filelist: $D filelist.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/fmgrcopy: $D fmgrcopy.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/mkfmtape: $D mkfmtape.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/sdtfmgrcopy: $D sdtfmgrcopy.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/tapdump: $D tapdump.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/tape2disk: $D tape2disk.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/tapsca: $D tapscan.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/eomtap: $D eomtap.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/volmcopy: $D volmcopy.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/ddump: $D ddump.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/deblk: $D deblk.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/mpxblk: $D mpxblk.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/renum: $D renum.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/cutostap: $D cutostap.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
$B/small: $D small.c
@-$(CC) $(CFLAGS) $(@F).c $(LFLAGS) -o $@
@chmod 755 $@
@cp $(@F) $B
@echo $(@F) installed in $B
# Some makes don't understand the $$ notation above. In this case
# you have to type out the compile paragraph for each PROG. Sigh.
# Here's a start, good luck.
#
#$B/abshw: abshw.c
# $(CC) $(CFLAGS) $? $(LFLAGS) -o $@
# @chmod 751 $@
# @echo $(@F) installed in $B
remake : clobber
@make ROOT=$(ROOT) OPTC=$(OPTC)
clean :
@-rm -f a.out junk* JUNK* core
@-rm -f *.o
clobber : clean
@-rm -f $(PROGS)
install : $(PROGS)
@cp $(PROGS) $B
@echo $(PROGS) installed in $B
@echo
# @chmod 755 $(@F)

389
SEL32/taptools/mkfmtape.c Normal file
View File

@@ -0,0 +1,389 @@
/*
* mkfmtape.c
*
* This program reads MPX files and stores it into a simulated
* filemgr save tape. The tape may then be restored to a MPX
* running system using the filemgr.
* new file entry.
* intput - simulated fmgrtape filename, filename, etc.
* output - simulated fmgrtape, file list to stdout
* options - -p = file type 0xca for programs
* - -t = ascii text file 0xee
* - -l = library/directory file 0xff
* - -o = other 0x00
* - -a = append entries to current file
* - -u = username (directory)
* 11/26/2018
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define BLKSIZE 768 /* MPX file sector size */
u_int32_t dir[1152]; /* room for 144 8w smd entries */
unsigned char data[4608]; /* room for 6*768=(4608) 768 byte sectors per 4608 byte block */
unsigned char bigdata[19200]; /* room for 6*768=(4608) 768 byte sectors per 4608 byte block */
/* read program file and output to a simulated mpx1.x filemgr savetape */
/* mkfmtape -ltoa fmgrtape, filename, filename, ... */
int main(argc, argv)
int argc;
char *argv[];
{
FILE *fp, *dp, *fopen();
int targc;
char **targv;
unsigned char username[8];
char *p;
int i;
#define DOPROG 1
#define DOADD 2
#define DOOTHER 4
#define DOTEXT 8
#define DOLIB 16
#define DOUSER 32
unsigned int option = DOTEXT; /* what to do */
unsigned char *fnp; /* file name pointer */
unsigned int size; /* size in 768 byte sectors */
unsigned int word; /* just a temp word variable */
unsigned char name[9]; /* LM name */
unsigned int typ; /* file type requested by user */
char *userp = username; /* pointer to username */
int ofd; /* output file number */
int32_t filen; /* file number */
u_int32_t *dirp; /* directory entry pointer */
int32_t totent; /* total smd entries */
memset((char *)dir, 0, 4608); /* zero smd storage */
memset((char *)data, 0, 4608); /* zero data storage */
for (i=0; i<8; i++)
username[i] = 0; /* use zero for system username */
typ = 0xee000000; /* set type */
if (argc <= 1) { /* see if correct # args */
fprintf(stderr, "Usage: %s [-ptloa] [-uusername] fmgrtape file1 file2 ...\n", *argv);
exit(1);
}
while(--argc > 0) {
// printf("argc %d argv %s\n", argc, *argv);
p = *++argv;
if (*p++ == '-') {
if (*p == '\0') {
fprintf(stderr, "Error: no option specified\n");
fprintf(stderr, "Usage: %s [-ptloa] [-uusername] fmgrtape file1 file2 ...\n", *argv);
exit(1);
}
// printf("doing options %s\n", p);
while (*p != '\0') {
switch (*p++) {
case 'p':
case 'P':
option |= DOPROG; /* save program modules */
typ = 0xca; /* set type */
break;
case 'A':
case 'a':
option |= DOADD; /* append to save tape */
break;
case 'O':
case 'o':
option |= DOOTHER; /* other type files */
typ = 0x00; /* set type */
break;
case 'T':
case 't':
option |= DOTEXT; /* save text files */
typ = 0xee; /* set type */
break;
case 'L':
case 'l':
option |= DOLIB; /* save library files */
typ = 0xff; /* set type */
break;
case 'U':
case 'u':
option |= DOUSER; /* save username for files */
userp = p;
while (*p != '\0')
p++;
break;
default:
fprintf(stderr, "Error: no option specified\n");
fprintf(stderr, "Usage: %s [-ptloa] [-uusername] fmgrtape file1 file2 ...\n", *argv);
exit(1);
break;
} /* end switch */
continue;
} /* end while */
}
else {
// printf("option set to %x\n", option);
if (option & DOADD) {
long bytes;
/* open read/write */
if ((dp = fopen(*argv, "r+")) == NULL) {
/* file not there, create one by opening w+ */
if ((dp = fopen(*argv, "w")) == NULL) {
fprintf(stderr, "error: can't create/open simulated tape disk file %s\n", *argv);
exit(1);
}
// printf("1 opened output in w mode, write at start\n");
}
// else
// printf("2 opened output in r+ mode write at end\n");
fseek(dp, 0, SEEK_END); /* seek to end */
bytes = ftell(dp); /* get filesize in bytes */
printf("file length %ld bytes\n", bytes);
printf("start writing at %ld bytes offset\n", bytes-8);
fseek(dp, 0, SEEK_SET); /* rewind file to beginning */
if (bytes > 8) { /* see if file written to already */
/* we need to find the EOT */
int32_t n1, n2, hc, tc, n;
int EOFcnt = 0;
readmore:
n1 = fread((char *)(&hc), 1, (size_t)4, dp); /* read 4 byte record size */
if (n1 <=0) /* check for read error */
goto doabort; /* bad tape format */
if (hc & 0xffff0000) /* check for garbage */
hc = 0; /* assume EOF on disk */
if (hc == 0) { /* check for EOF on file */
/* EOF found */
if (++EOFcnt == 2) {
/* we have second EOF, we need to backup 4 bytes */
backup4:
bytes = ftell(dp); /* get file position in bytes */
fseek(dp, bytes-4, SEEK_SET); /* backspace over 2nd EOF */
goto getout; /* start our processing */
}
/* we have first EOF, keep reading */
goto readmore; /* read more records */
} else
if (hc == -1) { /* check for EOM */
if (EOFcnt == 1)
/* see if one EOF followed by EOM (-1) */
goto backup4; /* start write over the EOM */
/* we have an EOM without any EOF, so bad tape */
goto doabort; /* bad tape format */
}
/* we have data, so no EOF */
EOFcnt = 0; /* reset EOF count */
/* read the data */
tc = hc; /* save record size */
n = fread(bigdata, 1, (size_t)hc, dp); /* read in record size */
if (n <= 0) { /* check for read error */
goto doabort; /* bad tape format */
}
n2 = fread((char *)(&hc), 1, (size_t)4, dp); /* read 4 byte record size */
if (n2 <= 0) { /* check for read error */
doabort:
/* error, abort the operation */
fprintf(stderr, "error: formatting error on simulated tape disk file %s\n", *argv);
exit(1);
}
/* verify counts & sizes */
if ((tc != hc) || (hc != n))
goto doabort; /* bad tape format */
goto readmore; /* read more records */
}
}
else {
if ((dp = fopen(*argv, "w")) == NULL) {
fprintf(stderr, "error: can't create/open simulated tape disk file %s\n", *argv);
exit(1);
}
// printf("3 opened output in w mode, write at start\n");
}
getout:
// printf("opening %s file for tape\n", *argv);
*++argv;
break; /* go handle files now */
}
continue;
}
/* end while --argc */
if ((argc-1) <= 0) {
fprintf(stderr, "Error: incorrect number of parameters\n");
fprintf(stderr, "Usage: %s [-ptloa] [-uusername] fmgrtape, file1 file2 ...\n", *argv);
exit(1);
}
/* got tapefile and options, handle files now */
targc = argc; /* save argc to reread list */
targv = argv; /* save argv to reread list */
// printf("AT 3 argc %d argv %s\n", argc, *argv);
filen = 0; /* no files yet */
totent = 0; /* no files yet */
/* populate the 32 byte SMD entry */
dirp = (u_int32_t *)dir; /* get word pointer for smd data */
while (--argc > 0) {
u_int32_t smd[8]; /* smd entry data */
int blks;
for (i=0; i<8; i++) /* zero smd entry */
smd[i] = 0;
p = *argv++;
i = strlen(p); /* filename size */
if (i == 0 || i > 8) {
fprintf(stderr, "error: Filename too long (%d>8) %s, Aborting\n", i, p);
exit(1);
}
// printf("argc %d argv3 %s\n", argc, p);
if ((fp = fopen(p, "r")) == NULL) {
fprintf(stderr, "error: can't open user file %s\n", p);
exit(1);
}
fnp = p; /* get file name pointer */
fseek(fp, 0, SEEK_END); /* seek to end */
word = ftell(fp); /* get filesize in bytes */
fseek(fp, 0, SEEK_SET); /* rewind file */
size = (word/768); /* filesize in sectors */
if (word%768 != 0) /* see if byte left over */
size += 1; /* partial sector, add 1 */
blks = (word/4608); /* blocks */
if ((word%4608) != 0)
blks++;
printf("handle file %s user %s size %d bytes %d sect %d blocks\n",
fnp, userp, word, size, blks);
fclose(fp);
/* create smd entry for this file */
memset(name, ' ', 8); /* blank filename */
for (i=0; i<8; i++) {
if (p[i] == '\0') /* check for null termination char */
break;
name[i] = toupper(p[i]); /* uppercase filename */
}
/* populate the 32 byte SMD entry */
/* word 1 and 2 has filename */
smd[0] = name[3] << 24 | name[2] << 16 | name[1] << 8 | name[0];
smd[1] = name[7] << 24 | name[6] << 16 | name[5] << 8 | name[4];
/* type and smd loc in wd 2 */
smd[2] = typ; /* save the type of file */
/* size now has load module size in sectors */
size = 0x80000000 | (blks * 6); /* file flags and size */
smd[3] = (size & 0xff) << 24 | (size & 0xff00) << 8 |
(size & 0xff0000) >> 8 | (size & 0xff000000) >> 24;
memset(name, ' ', 8); /* blank username */
for (i=0; i<8; i++) {
if (userp[i] == '\0') /* check for null termination char */
break;
name[i] = toupper(userp[i]); /* uppercase username */
}
/* set username */
smd[4] = name[3] << 24 | name[2] << 16 | name[1] << 8 | name[0];
smd[5] = name[7] << 24 | name[6] << 16 | name[5] << 8 | name[4];
if ((smd[4] == 0x20202020 && smd[5] == 0x20202020) ||
(smd[4] == 0 & smd[5] == 0)) {
smd[4] = smd[5] = 0; /* use null for system */
}
smd[6] = 0x00080000; /* no password or udt index */
smd[7] = 0x00000080; /* fmgr has 0x80000000 in it so I will too */
for (i=0; i<8; i++)
*dirp++ = smd[i]; /* save smd entry */
filen++; /* bump the file count */
totent++; /* bump total count */
if (filen == 144) { /* see if entry is full */
/* we need to write out the directory entries */
int32_t n1, n2, nw;
/* we have data to write */
int32_t hc = (4608 + 1) & ~1; /* make byte count even */
/* write actual byte count to 32 bit word as header */
n1 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), dp);
/* write the data mod 2 */
nw = fwrite((unsigned char *)dir, 1, (size_t)hc, dp);
/* write the byte count in 32 bit word as footer */
n2 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), dp);
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
fprintf(stderr, "write (%d) failure\n", nw);
fprintf(stderr, "Operation aborted\n");
exit(1);
}
memset((char *)dir, 0, 4608); /* zero smd storage */
filen = 0; /* restart count */
}
}
/* write out the directory entries for the files to save */
if (filen != 0) {
/* we need to write out the directory entries */
int32_t n1, n2, nw;
/* we have data to write */
int32_t hc = (4608 + 1) & ~1; /* make byte count even */
/* write actual byte count to 32 bit word as header */
n1 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), dp);
/* write the data mod 2 */
nw = fwrite((unsigned char *)dir, 1, (size_t)hc, dp);
/* write the byte count in 32 bit word as footer */
n2 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), dp);
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
fprintf(stderr, "write (%d) failure\n", nw);
fprintf(stderr, "Operation aborted\n");
exit(1);
}
memset(dir, 0, 4608); /* zero smd storage */
filen = 0; /* restart count */
}
/* totcnt has total number of files to output */
memset((char *)data, 0, 4608); /* zero data storage */
argc = targc; /* restore argc for reread */
argv = targv; /* restore argv for reread */
/* read each file and output to save tape file in 6 sector blocks */
while (--argc > 0) {
int blks;
p = *argv++;
// printf("argc %d argv3 %s\n", argc, p);
if ((fp = fopen(p, "r")) == NULL) {
fprintf(stderr, "error: can't open user file %s\n", p);
exit(1);
}
fnp = p; /* get file name pointer */
fseek(fp, 0, SEEK_END); /* seek to end */
word = ftell(fp); /* get filesize in bytes */
fseek(fp, 0, SEEK_SET); /* rewind file */
size = (word/768); /* filesize in sectors */
if (word%768 != 0) /* see if byte left over */
size += 1; /* partial sector, add 1 */
blks = (word/4608); /* blocks */
if ((word%4608) != 0)
blks++;
// rewind(fp); /* back to beginning */
while (fread((char *)data, 1, 4608, fp) > 0) {
int32_t n1, n2, nw;
/* we have data to write */
int32_t hc = (4608 + 1) & ~1; /* make byte count even */
/* write actual byte count to 32 bit word as header */
n1 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), dp);
/* write the data mod 2 */
nw = fwrite((unsigned char *)data, 1, (size_t)hc, dp);
/* write the byte count in 32 bit word as footer */
n2 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), dp);
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
fprintf(stderr, "write (%d) failure\n", nw);
fprintf(stderr, "Operation aborted\n");
exit(1);
}
memset((char *)data, 0, 4608); /* zero data storage */
}
printf("handle file %s user %s (size %d bytes) (%d sect) (%d blocks)\n",
fnp, userp, word, size, blks);
fclose(fp);
}
/* write EOF (zero) to file */
filen = 0; /* zero count */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
/* do second EOF */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
filen = -1; /* make in -1 for EOM */
/* do EOM */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
// printf("setting at %ld bytes in file after EOM\n", ftell(dp));
fclose(dp);
exit(0);
}

174
SEL32/taptools/mpxblk.c Normal file
View File

@@ -0,0 +1,174 @@
/*
* mpxblk.c
*
* This program converts a unix/dos ascii file to an mpx blocked file
* trailing blanks are not deleted from the source file
* input - stdin
* output - stdout
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MPXMAX 254
int mpxbb();
int getloi();
#define BLKSIZE 768
int main (argc, argv)
int argc;
char *argv[];
{
char s[MPXMAX];
int i;
int fn = fileno(stdout);
while (1) {
if ((i = getloi(s, MPXMAX)) == 0) {
mpxbb(fn, s, 0, 1); /* last write to output */
exit(0);
}
if (i == 1 && s[0] == '\n')
s[0] = ' '; /* replace single n/l with blank */
if (s[i-1] == '\n')
i--; /* remove trailing n/l */
if (mpxbb(fn, s, i, 0) < 0) { /* last data record out */
fprintf(stderr, "output file error\n");
exit(1);
}
}
}
/* get a line of input. */
/* terminate line on \n or \r\n */
/* allow max of 254 chars in a line */
int getloi(s, lim)
char s[];
int lim;
{
int c, i;
for(i = 0; --lim > 0; ) {
c = getchar();
switch (c) {
case '\n':
/* terminate on \n */
s[i++] = c;
goto linedone;
case '\r':
c = getchar();
/* terminate on \r\n */
if (c == '\n') {
s[i++] = c;
goto linedone;
}
/* put back the character */
ungetc(c, stdin);
/* output the \r to the stream */
c = '\r';
/* drop through */
default:
s[i++] = c;
break;
case EOF:
return (0);
break;
}
}
linedone:
return (i);
}
/*
** output line of text from the source
*/
static unsigned char bb[BLKSIZE]; /* blocking buffer */
static char first = 0; /* 1st time thru flag */
/*
* mpxbb - make up mpx block file output
* input - buffer address
* - byte count
* - last write flag
*/
int
mpxbb(fd, buf, cnt, last)
int fd;
unsigned char *buf;
int cnt;
int last;
{
int boff; /* next write address offset */
if (!first) { /* is this 1st time thru */
first = 1; /* set the flag */
memset (bb, '\0', BLKSIZE); /* zero the buffer */
bb[3] = 4; /* next write byte offset */
bb[4] = 0x60; /* set beg/end of block */
bb[5] = 0; /* 1st block count is 0 bytes */
}
boff = (bb[2] << 8) | (bb[3]); /* get next write address offset */
if (last)
goto alldone; /* close out the file */
/* see if enough room in buffer for this record */
/* add current offset + 2 (for last record info) plus new */
/* record size plus 4 (2 for this rec, 2 for last) */
if ((boff + 2 + cnt + 4) >= BLKSIZE) {
/* not enough space, write out this record */
if (write(fd, bb, BLKSIZE) < 0)
return(-1);
memset (bb, '\0', BLKSIZE); /* zero the buffer */
bb[4] = 0x60; /* set beg/end of block */
bb[5] = 0; /* 1st block count is 0 bytes */
/* after 1st write */
boff = 4; /* init count at 4 bytes */
}
/* we have enough room, move in the record */
/* clear last record end of block flag, set up this record */
/* info and last rec info at end of data, and update cnt */
bb[boff] &= ~0x20; /* clear end of block flag */
bb[boff+2] = 0x00; /* clear this blocks flags */
bb[boff+3] = cnt; /* set this record count */
memcpy(&bb[boff+4], buf, cnt); /* copy in the data */
boff += (cnt+4); /* update count */
bb[boff] = 0x20; /* set eob status flag */
bb[boff+1] = cnt; /* set last rec byte count */
bb[2] = (boff & 0xff00) >> 8; /* set hi byte of count */
bb[3] = (boff & 0xff); /* set lo byte of count */
return(cnt); /* done */
alldone:
/* that was the last record, set eof flag in bb, write it and exit */
/* see if enough room in buffer for EOM record */
/* add current offset + 2 (for last record info) plus new */
/* EOF record size of 4 (2 for this rec, 2 for last) */
if ((boff + 2 + 4) >= BLKSIZE) {
/* not enough space, write out this record */
if (write(fd, bb, BLKSIZE) < 0)
return(-1);
memset (bb, '\0', BLKSIZE); /* zero the buffer */
bb[4] = 0x60; /* set beg/end of block */
bb[5] = 0; /* 1st block count is 0 bytes */
/* after 1st write */
boff = 4; /* init count at 4 bytes */
}
bb[boff] &= ~0x20; /* clear end of block flag */
/* bb[boff+2] = 0xa0; /* clear this blocks flags */
bb[boff+2] = 0x80; /* clear this blocks flags */
bb[boff+3] = 0; /* set record count of 0 */
bb[boff+4] = 0xa0; /* set EOF/EOB flags */
boff += 4; /* 4 more bytes */
bb[2] = (boff & 0xff00) >> 8; /* set hi byte of count */
bb[3] = (boff & 0xff); /* set lo byte of count */
/* write out EOF record */
if (write(fd, bb, BLKSIZE) < 0)
return(-1);
first = 0; /* reset 1st time flag */
return(cnt); /* get out, done */
}

58
SEL32/taptools/renum.c Normal file
View File

@@ -0,0 +1,58 @@
/*
* renum.c
*
* This program truncates a line or expands a line with blanks to
* have a line length of 72 chars. A 7 digit line number is then
* append to the line. Numbers are in the form XXXX.000.
* input - stdin
* output - stdout
*/
#include <stdio.h>
#include <stdlib.h>
/* get a line of input. */
int ln = 1;
int getloi(s, lim) /* right from the book. */
char s[];
int lim;
{
int c, i, j;
char line[12];
for (i=0; --lim > 0;)
{
if ((c = getchar()) == EOF)
return 0;
if (c == '\r')
continue;
if (c == '\n')
break;
s[i++] = c;
}
if (i > 72) /* truncate at char 72 */
i = 72;
for (; i<72; i++)
s[i] = ' ';
sprintf(line, "%04d.000", ln++);
for (j=0; j<8; j++)
s[72+j] = line[j];
s[80] = '\n';
s[81] = '\0';
return (i);
}
int main (argc, argv)
int argc;
char *argv[];
{
char s[BUFSIZ];
while (1) {
if (getloi(s, BUFSIZ) == 0)
exit(0);
/* output line of text from the source */
printf("%s", s);
}
}

View File

@@ -0,0 +1,357 @@
/*
* 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;
int32_t n1, n2, hc, tc, n;
errno = 0;
/* read the byte count in 32 bit word as header */
n1 = read(inp, (char *)(&hc), (size_t)sizeof(hc));
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);
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)sizeof(tc));
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);
}

63
SEL32/taptools/small.c Normal file
View File

@@ -0,0 +1,63 @@
/*
* small.c
*
* This program deletes trailing blanks from a source file
* input - stdin
* output - stdout
*/
#include <stdio.h>
#include <stdlib.h>
int getloi();
int putloi();
int main(argc, argv)
int argc;
char *argv[];
{
char s[BUFSIZ];
while(1) {
if (getloi(s, BUFSIZ) == 0)
exit(0);
putloi(s);
}
}
/* get a line of input. */
int getloi(s, lim) /* right from the book. */
char s[];
int lim;
{
int c, i;
for (i = 0; --lim > 0 && (c = getchar()) != EOF && (s[i++] = c) != '\n'; )
{
;
}
#define STRIP_LINE
#ifdef STRIP_LINE
if (i > 73)
i = 73;
s[72] = '\n';
s[73] = '\0';
#endif
if ((s[i-1] == '\n') && (i > 1))
{
while (((s[i-2] == ' ') || (s[i-2] == '\r')) && (i > 1))
--i;
s[i-1] = '\n';
}
s[i] = '\0';
return (i);
}
/*
** output line of text from the source
*/
int putloi(s)
char *s;
{
printf("%s", s);
}

245
SEL32/taptools/tapdump.c Normal file
View File

@@ -0,0 +1,245 @@
/*
* tapdump.c
*
* This program scans a metatape file and displays the file content as
* a side by side hex dump of the contents.
* input - stdin or specified filename
* output - stdout
*/
#include <stdio.h>
#include <sys/file.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int filen = 1;
int EOFcnt = 0;
int count=0, lcount=0;
int size=0, tsize=0;
int size_512K = 512 * 1024;
int ln;
int inp;
#define PRINTABLE(x) ((x < 32) || (x > 126)) ? '.' : x
/* get a line of input. */
int getloi(char *s, int lim)
{
int c, i;
int32_t n1, n2, hc, tc, n;
errno = 0;
/* read the byte count in 32 bit word as header */
n1 = read(inp, (char *)(&hc), (size_t)sizeof(hc));
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 */
if (hc == 0)
{
/* we are at tape EOF */
if (++EOFcnt < 2) /* if 1st EOF, print file info */
{
#ifndef NOTDUMP
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
fprintf(stderr, "file %d: eof after %d records: %d bytes\n", filen, count, size);
#endif
filen++; /* set next file number */
}
else
{
#ifndef NOTDUMP
fprintf(stderr, "second eof after %d files: %d bytes\n", filen, size);
#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 = -1; /* set ln to -1 showing we are at EOF */
/* we have EOF */
return 0; /* return EOF on tape data */
}
if (hc == -1)
{
#ifndef NOTDUMP
/* we have EOM */
fprintf(stderr, "mpx eot\n");
/* print out total tape size in bytes */
fprintf(stderr, "total length: %ld bytes\n", tsize);
#endif
return -1; /* at EOM on disk file */
}
/* read the data */
n = read(inp, s, (size_t)hc);
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)sizeof(tc));
count++; /* bump record count */
size += n; /* update bytes read */
EOFcnt = 0; /* not an EOF */
if (n != ln)
{
#ifndef NOTDUMP
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
#endif
ln = n;
lcount = count;
}
/* return bytes in buffer */
return n;
}
int main (int argc, char *argv[])
{
// char in[BUFSIZ], out[BUFSIZ];
char *buf;
size_t size_512K = 512 * 1024;
size_t buf_size = 512 * 1024;
char *cp, *np;
int ll, gotboth = 0;
int lfilen = filen;
unsigned int fileaddr, file_byte_count=0, curchar, buffptr, bufflen;
int skipfile = 0;
if (argc != 2)
{
fprintf(stderr, "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]);
return (1);
}
/* get a 512k buffer */
if ((buf = malloc(buf_size)) == NULL)
{
fprintf(stderr, "Can't allocate memory for %s\n", argv[0]);
return (4);
}
/* init counts */
ln = -2; /* look for 2 eof */
count = 0;
size = 0;
tsize = 0;
lcount = 0;
filen = 1;
lfilen = filen;
buffptr = 0;
bufflen = 16;
fileaddr = 0;
file_byte_count = 0;
printf("\nfile %d:\n", filen);
/* get lines until eof */
while ((ll=getloi(buf, buf_size)) != EOF)
{
if (ll == 0)
{
/* eof found, process new file */
skipfile = 0;
file_byte_count = 0;
fileaddr = 0;
printf("\nfile %d:\n", filen);
}
else
{
int cc = 0;
buffptr = 0;
char buff[257];
int ans;
/* see if skipping to next file */
if (skipfile == 1)
{
continue;
}
/* process the returned buffer */
while (cc < ll)
{
curchar = (unsigned int)buf[cc++] & 0xff;
file_byte_count++;
if (!buffptr)
printf(" %06x : ",fileaddr);
printf("%02x", curchar & 0xff);
buff[buffptr++] = PRINTABLE(curchar);
if (!(buffptr % 4))
printf(" ");
if (buffptr >= bufflen)
{
buff[buffptr] = 0;
printf(" |%s|\n",buff);
buffptr = 0;
fileaddr += bufflen;
if (!(file_byte_count % 256))
// if (!(file_byte_count % 768))
{
printf("\n<cr> - continue, q = quit, s = skip > ");
ans = getchar();
if (ans == 'q')
{
close(inp);
free(buf);
exit(1);
}
if (ans == 's')
skipfile = 1;
if (ans != '\n')
while ((ans=getchar()) != '\n' )
;
} /* end of if */
if (skipfile == 1)
break;
} /* end of if */
} /* end of while */
if (buffptr && !skipfile)
{
buff[buffptr] = 0;
while (buffptr++ < bufflen)
{
printf(" ");
if (!(buffptr % 4))
printf(" ");
} /* end of while */
printf(" |%s|\n",buff);
/* see what user wants to do */
printf("\n<cr> - continue, q = quit > ");
ans = getchar();
if (ans == 'q')
{
close(inp);
free(buf);
exit(1);
}
if (ans != '\n')
while ((ans=getchar()) != '\n' )
;
} /* end of if */
}
}
close(inp);
free(buf);
exit(0);
}

244
SEL32/taptools/tape2disk.c Normal file
View File

@@ -0,0 +1,244 @@
/*
* 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 termonate 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 */
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;
size_t size_128K = 128 * 1024;
size_t size_256K = 256 * 1024;
int main(argc, argv)
int argc;
char **argv;
{
int n, nw, inp, outp;
struct mtop op;
size_t buf_size = size_256K;
int EOFcnt = 0; /* count the number of EOFs in a row. */
if (argc <= 1 || argc > 3)
{
(void)fprintf(stderr, "Usage: tape2disk src [dest]\n");
return (1);
}
inf = argv[1];
if (argc == 3)
{
outf = argv[2];
copy = 1;
}
if ((inp = open(inf, O_RDONLY, 0666)) < 0)
{
(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)
{
(void)fprintf(stderr, "Can't open %s\n", outf);
return (3);
}
}
/* get a 128k buffer */
if ((buff = malloc(buf_size)) == NULL)
{
(void)fprintf(stderr, "Can't allocate memory for tapecopy\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)
{
if (errno == ENOMEM)
{
if (buf_size < size_256K)
buf_size = size_256K;
else
buf_size *= 2;
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;
}
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)
{
int n1, n2;
/* we have data to write */
int hc = (n + 1) & ~1; /* make byte count even */
/* write actual byte count to 32 bit word as header */
n1 = write(outp, (char *)(&hc), (size_t)sizeof(hc));
/* write the data mod 2 */
nw = write(outp, buff, (size_t)hc);
/* write the byte count in 32 bit word as footer */
n2 = write(outp, (char *)(&hc), (size_t)sizeof(hc));
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
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), (size_t)sizeof(hc));
if (n1 != sizeof(hc))
{
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 */
int 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), (size_t)sizeof(hc));
if (n1 != sizeof(hc))
{
perror("Write EOM");
return (6);
}
(void)close(outp);
}
/* print out total tape size in bytes */
(void)printf("total length: %ld bytes\n", tsize);
return (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);
}

155
SEL32/taptools/tapscan.c Normal file
View File

@@ -0,0 +1,155 @@
/*
* tapscan.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 <errno.h>
int filen = 1;
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;
#endif
/* get a line of input. */
int getloi(char *s, int lim)
{
int c, i;
int32_t n1, n2, hc, tc, n;
errno = 0;
/* read the byte count in 32 bit word as header */
n1 = read(inp, (char *)(&hc), (size_t)sizeof(hc));
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 */
{
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
fprintf(stderr, "file %d: eof after %d records: %d bytes\n", filen, count, size);
filen++; /* set next file number */
}
else
{
fprintf(stderr, "second eof after %d files: %d bytes\n", filen-1, size);
}
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)
{
/* we have EOM */
fprintf(stderr, "mpx eot\n");
/* print out total tape size in bytes */
fprintf(stderr, "total length: %ld bytes\n", tsize);
return -1; /* at EOM on disk file */
}
/* read the data */
n = read(inp, s, (size_t)hc);
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)sizeof(tc));
count++; /* bump record count */
size += n; /* update bytes read */
EOFcnt = 0; /* not an EOF */
if (n != ln)
{
if (ln > 0)
{
if (count - lcount > 1)
fprintf(stderr, "file %d: records %d to %d: size %d\n", filen, lcount, count - 1, ln);
else
fprintf(stderr, "file %d: record %d: size %d\n", filen, lcount, ln);
}
ln = n;
lcount = count;
}
/* return bytes in buffer */
return n;
}
int main (int argc, char *argv[])
{
// char in[BUFSIZ], out[BUFSIZ];
char *buf;
size_t size_512K = 512 * 1024;
size_t buf_size = 512 * 1024;
char *cp, *np;
int ll, gotboth = 0;
if (argc != 2)
{
fprintf(stderr, "usage: %s infile\n", argv[0]);
exit(1);
} /* end of if */
#ifdef USE_READ
/* open input file */
infp = fopen(argv[1],"r");
if (infp == NULL) {
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
exit(1);
} /* end of if */
#else
if ((inp = open(argv[1], O_RDONLY, 0666)) < 0)
{
fprintf(stderr,"%s: fopen: unable to open input file %s\n", argv[0], argv[1]);
return (1);
}
#endif
/* get a 512k buffer */
if ((buf = malloc(buf_size)) == NULL)
{
fprintf(stderr, "Can't allocate memory for %s\n", argv[0]);
return (4);
}
/* init counts */
ln = -2; /* look for 2 eof */
count = 0;
size = 0;
tsize = 0;
lcount = 0;
/* get lines until eof */
while (((ll=getloi(buf, buf_size)) != EOF))
{
}
close(inp);
free(buf);
exit(0);
}

261
SEL32/taptools/volmcopy.c Normal file
View File

@@ -0,0 +1,261 @@
/*
* volmcopy.c
*
* This program scans a metatape file and prints file count and sizes.
* It is only for volmgr save images. Save images have the following format:
* One or more 6144 byte records containing a list of files saved 16 char file
* name followed my 16 char directory name followed by 16 char volume name.
* A 1536 byte file definition entry will be followed by 1 to 8 768 byte
* file data records followed by an EOF for each file. If the file size is
* greater than 6144 bytes, 1 or more 6144 byte records are output followed
* by last record modulo 768 bytes. Two EOFs in a row define the EOT.
* 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 filen = 1;
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)sizeof(hc));
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 */
{
filen++; /* set next file number */
}
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)
return -1; /* at EOM on disk file */
/* read the data */
n = read(inp, s, (size_t)hc);
/* read the byte count in 32 bit word as trailer */
n2 = read(inp, (char *)(&tc), (size_t)sizeof(tc));
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;
int lfilen = filen;
char path[64], command[128];
if (argc != 2)
{
fprintf(stderr, "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]);
return (1);
}
outp = -1;
/* get a 512k buffer */
if ((buf = malloc(buf_size)) == NULL)
{
fprintf(stderr, "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 = filen;
printf("\nfile %d:\n", filen);
/* get lines until eof */
while ((ll=getloi(buf, buf_size)) != EOF)
{
if (ll == 0)
{
/* eof found, process new file */
printf("\nfile %d:\n", filen);
}
else
{
int cc = 0;
unsigned int curchar;
/* dump first 2 words */
int w1, w2, i, j;
w1 = (buf[0] & 0xff) << 24 | buf[1] << 16 | buf[2] << 8 | (buf[3] & 0xff);
w2 = (buf[4] & 0xff) << 24 | buf[5] << 16 | buf[6] << 8 | (buf[7] & 0xff);
// printf("w1 = %x, w2 = %d count = %d\n", w1, w2, count);
if (count == 1 && w1 == 1)
{
char file[20], dir[20], vol[20];
int off = 8;
int l = 0;
/* we have directory entries */
for (j=0; j<w2; j++)
{
int k = l++ * 48;
if (k > (6144-48-off))
{
ll=getloi(buf, buf_size);
off = 0;
l = 0;
k = 0;
printf("reread: got ll= %d\n", ll);
}
for (i=0; i<16; i++)
{
file[i] = tolower(buf[k+off+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[16] = '\0';
for (i=0; i<16; i++)
{
dir[i] = tolower(buf[k+off+16+i]);
if (dir[i] == ' ')
dir[i] = '\0';
}
dir[16] = '\0';
for (i=0; i<16; i++)
{
vol[i] = tolower(buf[k+off+32+i]);
if (vol[i] == ' ')
vol[i] = '\0';
}
vol[16] = '\0';
sprintf(path, "./%s/%s", vol, dir);
/* create the directory/file */
sprintf(command, "mkdir -p %s", path);
system(command);
sprintf(path, "./%s/%s/%s", vol, dir, file);
sprintf(command, "touch %s", path);
system(command);
}
} else
if (count == 1 && w1 == 2 && w2 == 0)
{
char file[20], dir[20], vol[20];
if (outp >= 0)
close(outp);
outp = -1;
/* process file definition */
/* we have a file definition entry */
for (i=0; i<16; i++)
{
file[i] = tolower(buf[8+i]);
if (file[i] == ' ')
file[i] = '\0';
}
file[16] = '\0';
for (i=0; i<16; i++)
{
dir[i] = tolower(buf[24+i]);
if (dir[i] == ' ')
dir[i] = '\0';
}
dir[16] = '\0';
for (i=0; i<16; i++)
{
vol[i] = tolower(buf[40+i]);
if (vol[i] == ' ')
vol[i] = '\0';
}
vol[16] = '\0';
sprintf(path, "./%s/%s/%s", vol, dir, file);
printf("path = %s\n", path);
/* open output file, create it if necessary */
if ((outp = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
{
(void)fprintf(stderr, "Can't open %s\n", path);
close(inp);
free(buf);
return (3);
}
/* process file data for file */
if (ll > 1536)
{
int no = write(outp, buf+1536, ll-1536);
if (no != ll)
fprintf(stderr, "write (%d) != read (%d) on file %s\n", no, ll, path);
}
} else
if (count > 1)
{
/* process file data for file */
int no = write(outp, buf, ll);
if (no != ll)
fprintf(stderr, "write (%d) != read (%d) on file %s\n", no, ll, path);
}
/* process the returned buffer */
// while (cc < ll)
// {
// curchar = (unsigned int)buf[cc++] & 0xff;
// } /* end of while */
}
}
close(inp);
free(buf);
if (outp >= 0)
close(outp);
exit(0);
}