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:
171
SEL32/taptools/README.md
Normal file
171
SEL32/taptools/README.md
Normal 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
213
SEL32/taptools/cutostap.c
Normal 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
220
SEL32/taptools/ddump.c
Normal 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
603
SEL32/taptools/deblk.c
Normal 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
357
SEL32/taptools/diskload.c
Normal 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
225
SEL32/taptools/eomtap.c
Normal 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
348
SEL32/taptools/filelist.c
Normal 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
288
SEL32/taptools/fmgrcopy.c
Normal 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
178
SEL32/taptools/makefile
Normal 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
389
SEL32/taptools/mkfmtape.c
Normal 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
174
SEL32/taptools/mpxblk.c
Normal 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
58
SEL32/taptools/renum.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
357
SEL32/taptools/sdtfmgrcopy.c
Normal file
357
SEL32/taptools/sdtfmgrcopy.c
Normal 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
63
SEL32/taptools/small.c
Normal 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
245
SEL32/taptools/tapdump.c
Normal 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
244
SEL32/taptools/tape2disk.c
Normal 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
155
SEL32/taptools/tapscan.c
Normal 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
261
SEL32/taptools/volmcopy.c
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user