mirror of
https://github.com/open-simh/simtools.git
synced 2026-04-16 16:31:38 +00:00
Various os/8 and rt11 fixes. Add support for Unix V7.
This commit is contained in:
committed by
Timothe Litt
parent
a6fb802807
commit
405010f948
@@ -33,3 +33,36 @@ Changes Since Alpha Release:
|
||||
|
||||
- Merged change from tvrusso to fix compilation on FreeBSD
|
||||
|
||||
20-Aug-20
|
||||
|
||||
- Fixed bug in OS/8 file deletion which incorrectly reduced the directory
|
||||
file count by 1
|
||||
|
||||
- Fix ASCII mode read in OS/8 where it would read an entire block into
|
||||
memory rather than a single line. When copying to local:, this would
|
||||
result in the destination file having unexpected <CR> characters.
|
||||
|
||||
15-Feb-21
|
||||
|
||||
- Added support Research Unix V7 file systems of RK05, RL01 and RL02 drives
|
||||
using file system type "unixv7"
|
||||
|
||||
3-Mar-23
|
||||
|
||||
- Added support for RK06 and RK07 Unix V7 drives
|
||||
- Added support for creating arbitrary sized Unix V7 file systems
|
||||
|
||||
26-Sep-24
|
||||
|
||||
- Fixed display of System ID during RT-11 mount if there is non-zero data
|
||||
following the System ID on the disk
|
||||
|
||||
13-Nov-24
|
||||
|
||||
- Fixed OS/8 ASCII file read/write to to handle ^Z marking the end of file
|
||||
|
||||
28-Nov-24
|
||||
|
||||
- Fixed RT11 scan to find the size of the partition. The old code would
|
||||
incorrectly terminate on an EMPTY marker rather than END-OF-SEGMENT.
|
||||
|
||||
|
||||
@@ -7,14 +7,15 @@ INSTALL=install
|
||||
CC=gcc
|
||||
|
||||
EXECUTABLE=fsio
|
||||
SOURCES=fsio.c declib.c tape.c dos11.c rt11.c dosmt.c local.c os8.c
|
||||
INCLUDES=fsio.h declib.h tape.h dos11.h rt11.h dosmt.h os8.h
|
||||
SOURCES=fsio.c declib.c tape.c dos11.c rt11.c dosmt.c local.c os8.c unixv7.c
|
||||
INCLUDES=fsio.h declib.h tape.h dos11.h rt11.h dosmt.h os8.h unixv7.h
|
||||
LIBS=-lreadline
|
||||
MANPAGE=fsio.1
|
||||
MANPAGE_DOS=fsio-dos11.1
|
||||
MANPAGE_RT=fsio-rt11.1
|
||||
MANPAGE_DOSMT=fsio-dosmt.1
|
||||
MANPAGE_OS8=fsio-os8.1
|
||||
MANPAGE_UNIXV7=fsio-unixv7.1
|
||||
ARCHIVE=fsio.tgz
|
||||
|
||||
RELEASEFILES=$(BIN)/$(EXECUTABLE)
|
||||
@@ -23,8 +24,16 @@ RELEASEFILES+=$(MAN)/$(MANPAGE_DOS)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_RT)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_DOSMT)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_OS8)
|
||||
RELEASEFILES+=$(MAN)/$(MANPAGE_UNIXV7)
|
||||
RELEASEFILES+=./fsio.txt ./fsioSimh.txt
|
||||
|
||||
MANPAGES=$(MANPAGE)
|
||||
MANPAGES+=$(MANPAGE_DOS)
|
||||
MANPAGES+=$(MANPAGE_RT)
|
||||
MANPAGES+=$(MANPAGE_DOSMT)
|
||||
MANPAGES+=$(MANPAGE_OS8)
|
||||
MANPAGES+=$(MANPAGE_UNIXV7)
|
||||
|
||||
$(EXECUTABLE): $(SOURCES) $(INCLUDES) Makefile
|
||||
$(CC) $(CFLAGS) $(DEFINES) -o $(EXECUTABLE) $(SOURCES) $(LIBS)
|
||||
|
||||
@@ -33,7 +42,7 @@ $(EXECUTABLE): $(SOURCES) $(INCLUDES) Makefile
|
||||
clean:
|
||||
rm -f $(EXECUTABLE)
|
||||
|
||||
install: $(EXECUTABLE) $(MANPAGE) $(MANPAGE_DOS) $(MANPAGE_RT)
|
||||
install: $(EXECUTABLE) $(MANPAGES)
|
||||
$(INSTALL) -p -m u=rx,g=rx,o=rx $(EXECUTABLE) $(BIN)
|
||||
mkdir -p $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE) $(MAN)
|
||||
@@ -41,6 +50,7 @@ install: $(EXECUTABLE) $(MANPAGE) $(MANPAGE_DOS) $(MANPAGE_RT)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_RT) $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_DOSMT) $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_OS8) $(MAN)
|
||||
$(INSTALL) -p -m u=r,g=r,o=r $(MANPAGE_UNIXV7) $(MAN)
|
||||
|
||||
uninstall:
|
||||
rm -f $(BIN)/$(EXECUTABLE)
|
||||
@@ -49,6 +59,7 @@ uninstall:
|
||||
rm -f $(MAN)/$(MANPAGE_RT)
|
||||
rm -f $(MAN)/$(MANPAGE_DOSMT)
|
||||
rm -f $(MAN)/$(MANPAGE_OS8)
|
||||
rm -f $(MAN)/$(MANPAGE_UNIXV7)
|
||||
|
||||
# This assumes that fsio has been "installed" on the current system
|
||||
archive: $(RELEASEFILES)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -2473,6 +2473,7 @@ struct FSdef dos11FS = {
|
||||
dos11Umount,
|
||||
dos11Size,
|
||||
dos11Newfs,
|
||||
NULL,
|
||||
dos11Set,
|
||||
dos11Info,
|
||||
dos11Dir,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -385,9 +385,21 @@ static int dosmtReadBytes(
|
||||
break;
|
||||
}
|
||||
}
|
||||
*buf++ = file->buf[file->nextb++];
|
||||
len--;
|
||||
count++;
|
||||
if (SWISSET('a')) {
|
||||
char ch = file->buf[file->nextb++] & 0177;
|
||||
|
||||
if ((ch != 0) && (ch != 0177)) {
|
||||
*buf++ = ch;
|
||||
count++;
|
||||
}
|
||||
len--;
|
||||
if (ch == '\n')
|
||||
break;
|
||||
} else {
|
||||
*buf++ = file->buf[file->nextb++];
|
||||
len--;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -982,6 +994,7 @@ static void *dosmtOpenFileW(
|
||||
file->nextb = 0;
|
||||
file->tm = 0;
|
||||
file->error = 0;
|
||||
memset(file->buf, 0, DOSMTRCLNT);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
@@ -1015,8 +1028,8 @@ static off_t dosmtFileSize(
|
||||
uint32_t length;
|
||||
|
||||
/*
|
||||
* Compute the length of this file. The estimate may larger than the
|
||||
* actual size of the file size don't know the actual EOF position
|
||||
* Compute the length of this file. The estimate may be larger than the
|
||||
* actual size of the file since we don't know the actual EOF position
|
||||
* within the last block of the file.
|
||||
*/
|
||||
do {
|
||||
@@ -1097,13 +1110,21 @@ static void dosmtCloseFile(
|
||||
|
||||
data->eot = tapeGetPosition(mount->container);
|
||||
|
||||
if (tapeWriteEOM(mount->container, 1) == 0)
|
||||
/*
|
||||
* Write 2 tape marks indicating the end of tape (DOS/BATCH requires
|
||||
* 3 TM in a row, 1 for the EOF and the last 2 to indicate EOT) and then
|
||||
* backup over the last 2 TMs.
|
||||
*/
|
||||
if ((tapeWriteTM(mount->container) == 0) ||
|
||||
(tapeWriteTM(mount->container) == 0))
|
||||
file->error = 1;
|
||||
|
||||
if (file->error != 0) {
|
||||
ERROR("Panic: Error writing on \"%s\"\n", mount->name);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
tapeSetPosition(mount->container, data->eot);
|
||||
}
|
||||
|
||||
free(file);
|
||||
@@ -1304,6 +1325,7 @@ struct FSdef dosmtFS = {
|
||||
dosmtUmount,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
dosmtSet,
|
||||
dosmtInfo,
|
||||
dosmtDir,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FSIO-DOS11 1 "Jun 21,2019" "FFS I/O - DOS-11"
|
||||
.TH FSIO-DOS11 1 "Feb 14,2021" "FFS I/O - DOS-11"
|
||||
.SH NAME
|
||||
fsio-dos11 \- Foreign File System I/O - DOS-11
|
||||
.br
|
||||
@@ -14,6 +14,9 @@ group number and user number. Wildcard characters are only valid with the
|
||||
.SH NEWFS OPERATION
|
||||
\fInewfs\fP creates a blank RK05 image (2.5MB, 4800 blocks) with no UFD
|
||||
entries.
|
||||
.SH COPY OPERATION
|
||||
In ASCII mode ('-a'), characters will be converted to 7-bits and NULL and
|
||||
delete characters will not be copied.
|
||||
.SH SET OPERATION
|
||||
The following \fIset\fP commands are supported:
|
||||
.br
|
||||
@@ -46,6 +49,7 @@ Creates an empty UFD and sets default UIC for file access.
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.BR fsio-unixv7 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FSIO-DOSMT 1 "Jun 25,2019" "FFS I/O - DOS-11 magtape"
|
||||
.TH FSIO-DOSMT 1 "Feb 14,2021" "FFS I/O - DOS-11 magtape"
|
||||
.SH NAME
|
||||
fsio-dosmt \- Foreign File System I/O - DOS-11 magtape
|
||||
.br
|
||||
@@ -31,6 +31,9 @@ command, fsio will make use of the extra 3 characters on file lookup,
|
||||
directory listing and file creation.
|
||||
.SH NEWFS OPERATION
|
||||
\fInewfs\fP creates an empty (zero length) file.
|
||||
.SH COPY OPERATION
|
||||
In ASCII mode ('-a'), characters will be converted to 7-bits and NULL and
|
||||
delete characters will not be copied.
|
||||
.SH SET OPERATION
|
||||
The following \fIset\fP commands are supported:
|
||||
.br
|
||||
@@ -106,6 +109,7 @@ determine the current tape position).
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-os8 (1)
|
||||
.BR fsio-unixv7 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FSIO-OS8 1 "Sep 218,2019" "FFS I/O - OS/8"
|
||||
.TH FSIO-OS8 1 "Feb 14,2021" "FFS I/O - OS/8"
|
||||
.SH NAME
|
||||
fsio-os8 \- Foreign File System I/O - OS/8
|
||||
.br
|
||||
@@ -15,16 +15,16 @@ place multiple file systems on each physical device.
|
||||
.br
|
||||
OS/8 does not write any type of signature on the device and each device type
|
||||
has it's own partitioning scheme so the \fImount\fP command must use the
|
||||
"\fI-f type\fP switch so that \fBfsio\fP can determine the file system
|
||||
"\fI-t type\fP switch so that \fBfsio\fP can determine the file system
|
||||
layout. \fBfsio\fP uses a set of heuristics to verify the integrity of
|
||||
the OS/8 file system(s) but it is quite possible for a random disk to pass
|
||||
these tests and later crash \fBfsio\fP.
|
||||
.SH MOUNT OPERATION
|
||||
\fImount\fP requires the "\fI-f type\fP" switch so that it can determine the
|
||||
\fImount\fP requires the "\fI-t type\fP" switch so that it can determine the
|
||||
type of the underlying disk (See NEWFS OPERATION below for details).
|
||||
.SH NEWFS OPERATION
|
||||
\fInewfs\fP creates an RK05 disk image with 2 file systems. If the
|
||||
"\fI-f type\fP" switch is present a different container file will be created
|
||||
"\fI-t type\fP" switch is present a different container file will be created
|
||||
depending on the type of the device specified:
|
||||
.br
|
||||
.RS
|
||||
@@ -75,6 +75,7 @@ the default state after mount.
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-unixv7 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FSIO-RT11 1 "Jun 25,2019" "FFS I/O - RT-11"
|
||||
.TH FSIO-RT11 1 "Feb 14,2021" "FFS I/O - RT-11"
|
||||
.SH NAME
|
||||
fsio-rt11 \- Foreign File System I/O - RT-11
|
||||
.br
|
||||
@@ -84,6 +84,7 @@ No \fIset\fP commands are currently supported.
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.BR fsio-unixv7 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
74
converters/fsio/fsio-unixv7.1
Normal file
74
converters/fsio/fsio-unixv7.1
Normal file
@@ -0,0 +1,74 @@
|
||||
.TH FSIO-UNIXV7 1 "Mar 2,2023" "FFS I/O - UNIX V7"
|
||||
.SH NAME
|
||||
fsio-unixv7 \- Foreign File System I/O - Unix V7
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
\fBfsio\fP allows access to Unix V7 file systems using the file system type
|
||||
"\fIunixv7\fP". Note that you must use "\fI/etc/rawfs\fP" on Ultrix-11 3.0/3.1
|
||||
to access files on disks created by \fBfsio\fP.
|
||||
.br
|
||||
.SH UNIX V7 PHYSICAL DISKS
|
||||
UNIX V7 uses a logical block size of 512 bytes. \fBfsio\fP supports access to
|
||||
disks which have their super block stored at block 2. Unix V7 does not write
|
||||
any type of signature on the device so the \fImount\fP command uses a set of
|
||||
heuristics to determine if the file system is valid.
|
||||
.SH MOUNT OPERATION
|
||||
\fImount\fP accepts the optional "\fI-t type\fP" switch to provide an additonal
|
||||
check on the integrity of the file system (e.g. check for blocks addresses
|
||||
larger than the specified disk) (See NEWFS OPERATION below for details).
|
||||
.br
|
||||
|
||||
\fImount\fP also accepts the optional "\fI-o nnn\fP" switch where nnn is the
|
||||
block offset of the start of the partition to be mounted. Since most, if not
|
||||
all, UNIX V7 implementations hard code the partition layout for a specific
|
||||
disk within the device driver, you will have to examine the device driver
|
||||
code to calculate this offset.
|
||||
.SH NEWFS OPERATION
|
||||
\fInewfs\fP requires either the "\fI-b blocks\fP" or the "\fI-t type\fP" switch
|
||||
to determine the size of the container file to be created:
|
||||
.br
|
||||
.RS
|
||||
.TP
|
||||
\fIrk05\fP \- RK05 image (2436 blocks, 776 inodes)
|
||||
.br
|
||||
.TP
|
||||
\fIrl01\fP \- RL01 image (10240 blocks, 3272 inodes)
|
||||
.br
|
||||
.TP
|
||||
\fIrl02\fP \- RL02 image (20480 blocks, 6552 inodes)
|
||||
.br
|
||||
.TP
|
||||
\fIrk06\fP \- RK06 image (27126 blocks, 8680 inodes)
|
||||
.br
|
||||
.TP
|
||||
\fIrk07\fP \- RK07 image (53790 blocks, 17208 inodes)
|
||||
.br
|
||||
.RE
|
||||
.br
|
||||
|
||||
If neither switch is present, an RK05-sized disk will be created.
|
||||
.br
|
||||
|
||||
By default, inodes occupy 4% of the disk space. This can be overridden by
|
||||
using the "\fI-i num\fP" switch, where \fInum\fP can be in the range 8 - 65500
|
||||
and the resulting inode space cannot occupy more than 50% of the disk space
|
||||
(8 inodes consume 1 disk block).
|
||||
.br
|
||||
.SH SET OPERATION
|
||||
The following \fIset\fP commands are supported:
|
||||
.br
|
||||
.TP
|
||||
.B "\fIuid\fP n"
|
||||
Sets the default UID for created files and directories (was 0 after mount).
|
||||
.TP
|
||||
.B "\fIgid\fP n"
|
||||
Sets the default GID for created files and directories (was 0 after mount).
|
||||
.SH SEE ALSO
|
||||
.BR fsio (1)
|
||||
.BR fsio-dos11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.BR fsio-rt11 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH FSIO 1 "Sep 17,2019" "Foreign File System I/O"
|
||||
.TH FSIO 1 "Mar 2,2023" "Foreign File System I/O"
|
||||
.SH NAME
|
||||
fsio \- Foreign File System I/O
|
||||
.SH SYNOPSIS
|
||||
@@ -34,54 +34,56 @@ verb [switches] args ...
|
||||
The following verbs are supported:
|
||||
|
||||
.br
|
||||
.B "\fImount\fP \- make a container file available to fsio"
|
||||
.B "\fImount\fP \- Make a container file available to fsio"
|
||||
.br
|
||||
.B "\fIumount\fP \- remove knowledge of a container file from fsio"
|
||||
.B "\fIumount\fP \- Remove knowledge of a container file from fsio"
|
||||
.br
|
||||
.B "\fInewfs\fP \- create and new container and empty file system"
|
||||
.B "\fInewfs\fP \- Create a new container and empty file system"
|
||||
.br
|
||||
.B "\fIset\fP \- set parameters on a mounted file system"
|
||||
.B "\fImkdir\fP \- Create a new empty directory on a mounted file system"
|
||||
.br
|
||||
.B "\fIinfo\fP \- display information about the container file system"
|
||||
.B "\fIset\fP \- Set parameters on a mounted file system"
|
||||
.br
|
||||
.B "\fIdir\fP \- list a directory"
|
||||
.B "\fIinfo\fP \- Display information about the container file system"
|
||||
.br
|
||||
.B "\fIdump\fP \- dump a file in hex or octal"
|
||||
.B "\fIdir\fP \- List a directory"
|
||||
.br
|
||||
.B "\fIcopy\fP \- copy a single file"
|
||||
.B "\fIdump\fP \- Dump a file in hex or octal"
|
||||
.br
|
||||
.B "\fItype\fP \- type a file on the terminal"
|
||||
.B "\fIcopy\fP \- Copy a single file"
|
||||
.br
|
||||
.B "\fIdelete\fP \- delete a file"
|
||||
.B "\fItype\fP \- Type a file on the terminal"
|
||||
.br
|
||||
.B "\fIstatus\fP \- display currently mounted file systems"
|
||||
.B "\fIdelete\fP \- Delete a file"
|
||||
.br
|
||||
.B "\fIdo\fP \- echo and execute commands from a file"
|
||||
.B "\fIstatus\fP \- Display currently mounted file systems"
|
||||
.br
|
||||
.B "\fIhelp\fP \- display help on using fsio"
|
||||
.B "\fIdo\fP \- Echo and execute commands from a file"
|
||||
.br
|
||||
.B "\fIexit\fP \- terminate fsio (quit is an alias for exit)"
|
||||
.B "\fIhelp\fP \- Display help on using fsio"
|
||||
.br
|
||||
.B "\fIexit\fP \- Terminate fsio (quit is an alias for exit)"
|
||||
.br
|
||||
.TP
|
||||
The following commands are only accepted by file systems which are on magtape devices:
|
||||
|
||||
.br
|
||||
.B "\fIrewind\fP \- position the tape to the start of the data stream"
|
||||
.B "\fIrewind\fP \- Position the tape to the start of the data stream"
|
||||
.br
|
||||
.B "\fIeom\fP \- position the tape to the end of the data stream"
|
||||
.B "\fIeom\fP \- Position the tape to the end of the data stream"
|
||||
.br
|
||||
.B "\fIskipf\fP \- position the tape by skipping forward over files"
|
||||
.B "\fIskipf\fP \- Position the tape by skipping forward over files"
|
||||
.br
|
||||
.B "\fIskipr\fP \- position the tape by skipping backward over files"
|
||||
.B "\fIskipr\fP \- Position the tape by skipping backward over files"
|
||||
.br
|
||||
.SH COMMANDS
|
||||
.TP
|
||||
.B "\fImount\fP [-dfrx] [-t type] dev[:] file type"
|
||||
Make the container file available to fsio.
|
||||
.B "\fImount\fP [-dfrx] [-t type] [-o nnn] dev[:] file type"
|
||||
Make the container file available to \fBfsio\fP.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-d\fP \- generate debug output on stdout"
|
||||
.B "\fI\-d\fP \- Generate debug output on stdout"
|
||||
.br
|
||||
.B " Use environment variable \fIFSioDebugLog\fP to"
|
||||
.br
|
||||
@@ -89,44 +91,62 @@ Make the container file available to fsio.
|
||||
.br
|
||||
.B " Only available if built with DEBUG enabled"
|
||||
.br
|
||||
.B "\fI\-f\fP \- bypass home block validation (RT-11 only)"
|
||||
.B "\fI\-f\fP \- Bypass home block validation (RT-11 only)"
|
||||
.br
|
||||
.B "\fI\-r\fP \- mount file system read-only"
|
||||
.B "\fI\-o nnn\fP \- Specify partition block offset (unixv7 only)"
|
||||
.br
|
||||
.B "\fI\-t type\fP \- specify optional disk type"
|
||||
.B "\fI\-r\fP \- Mount file system read-only"
|
||||
.br
|
||||
.B "\fI\-t type\fP \- Specify optional disk type"
|
||||
.br
|
||||
.B "\fI\-x\fP \- dosmt will use extended filenames when writing"
|
||||
.br
|
||||
.B "\fIdev[:]\fP \- user supplied name for the mount"
|
||||
.B "\fIdev[:]\fP \- User supplied name for the mount"
|
||||
.br
|
||||
.B "\fIfile\fP \- name of the container file"
|
||||
.B "\fIfile\fP \- Name of the container file"
|
||||
.br
|
||||
.B "\fItype\fP \- type of container file system"
|
||||
.B "\fItype\fP \- Type of container file system"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
.B "\fIumount\fP dev[:]"
|
||||
Remove knowledge of the container file from fsio.
|
||||
Remove knowledge of the container file from \fBfsio\fP.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev[:]\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev[:]\fP \- Name supplied on a previous mount"
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
.B "\fInewfs\fP [-t type] [-e count] file type"
|
||||
.B "\fInewfs\fP [-b blks] [-t type] [-e n] [-i n] file type"
|
||||
Create an new container with an empty file system.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-t type\fP \- use alternate, file-system dependent size"
|
||||
.B "\fI\-b blks\fP \- Specify file system size (unixv7)"
|
||||
.br
|
||||
.B "\fI\-e n\fP \- Specify extra space for directory entries (RT11, OS/8)"
|
||||
.B "\fI\-t type\fP \- Use alternate, device-dependent size"
|
||||
.br
|
||||
.B "\fIfile\fP \- name of the container file"
|
||||
.B "\fI\-e n\fP \- Specify extra space for directory entries"
|
||||
.br
|
||||
.B "\fItype\fP \- type of container file system"
|
||||
.B " (RT11, OS/8)"
|
||||
.br
|
||||
.B "\fI\-i n\fP \- Specify inode count (8 to 65500) (UnixV7)"
|
||||
.br
|
||||
.B "\fIfile\fP \- Name of the container file"
|
||||
.br
|
||||
.B "\fItype\fP \- Type of container file system"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
.B "\fImkdir\fP [-p] dev:dirspec"
|
||||
Create a new empty directory on a mounted file system.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-p\fP \- Create any missing intermediate directories"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -136,9 +156,9 @@ Set parameters on a mounted file system.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIargs ...\fP\- arguments are passed on to the file system"
|
||||
.B "\fIargs ...\fP\- Arguments are passed on to the file system"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -148,7 +168,7 @@ Display information about the file system(s) within the container file.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
@@ -157,13 +177,13 @@ List the contents of a specific directory.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-f\fP \- display a full (vs. brief) directory"
|
||||
.B "\fI\-f\fP \- Display a full (vs. brief) directory"
|
||||
.br
|
||||
.B "\fI\-n\fP \- don't rewind tape before listing directory"
|
||||
.B "\fI\-n\fP \- Don't rewind tape before listing directory"
|
||||
.br
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIdirspec\fP \- filespec to display, may include wildcards"
|
||||
.B "\fIdirspec\fP \- Filespec to display, may include wildcards"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -173,45 +193,45 @@ Dump the contents of the file in octal, hex or characters.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-b\fP \- dump byte (8-bits) at a time"
|
||||
.B "\fI\-b\fP \- Dump byte (8-bits) at a time"
|
||||
.br
|
||||
.B "\fI\-c\fP \- dump in character format"
|
||||
.B "\fI\-c\fP \- Dump in character format"
|
||||
.br
|
||||
.B "\fI\-d\fP \- dump double-word (32-bits) at a time"
|
||||
.B "\fI\-d\fP \- Dump double-word (32-bits) at a time"
|
||||
.br
|
||||
.B "\fI\-w\fP \- dump word (16-bits) at a time"
|
||||
.B "\fI\-w\fP \- Dump word (16-bits) at a time"
|
||||
.br
|
||||
.B "\fI\-x\fP \- dump in hex format (default is octal)"
|
||||
.B "\fI\-x\fP \- Dump in hex format (default is octal)"
|
||||
.br
|
||||
.B "\fI\-n\fP \- don't rewind magtape before looking for file"
|
||||
.B "\fI\-n\fP \- Don't rewind magtape before looking for file"
|
||||
.br
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIdirspec\fP \- filespec to dump"
|
||||
.B "\fIdirspec\fP \- Filespec to dump"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
.B "\fIcopy\fP [-anpc blks] dev1:srcfile dev2:dstfile"
|
||||
.B "\fIcopy\fP [-anp] [-c blks] dev1:srcfile dev2:dstfile"
|
||||
Copy a file.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-a\fP \- copy in ASCII mode (translates line endings)"
|
||||
.B "\fI\-a\fP \- Copy in ASCII mode (translates line endings)"
|
||||
.br
|
||||
.B "\fI\-p\fP \- pad the file with NULLs"
|
||||
.B "\fI\-p\fP \- Pad the file with NULLs"
|
||||
.br
|
||||
.B "\fI\-n\fP \- don't rewind magtape before looking for input file"
|
||||
.B "\fI\-n\fP \- Don't rewind magtape before looking for input file"
|
||||
.br
|
||||
.B "\fI\-c blks\fP \- make contiguous file of specified size"
|
||||
.B "\fI\-c blks\fP \- Make contiguous file of specified size"
|
||||
.br
|
||||
.B "\fIdev1:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev1:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIsrcfile\fP \- source file to copy"
|
||||
.B "\fIsrcfile\fP \- Source file to copy"
|
||||
.br
|
||||
.B "\fIdev2:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev2:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIdstfile\fP \- destination file to copy"
|
||||
.B "\fIdstfile\fP \- Destination file to copy"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -221,11 +241,11 @@ Types the contents of the file on stdout.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-n\fP \- don't rewind magtape before looking for file"
|
||||
.B "\fI\-n\fP \- Don't rewind magtape before looking for file"
|
||||
.br
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIfilespec\fP\- filespec to type"
|
||||
.B "\fIfilespec\fP\- Filespec to type"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -235,9 +255,9 @@ Deletes the specified file.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIfilespec\fP\- filespec to delete"
|
||||
.B "\fIfilespec\fP\- Filespec to delete"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -251,9 +271,9 @@ Echo and execute commands from a file.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fI\-q\fP \- don't echo commands as they are read"
|
||||
.B "\fI\-q\fP \- Don't echo commands as they are read"
|
||||
.br
|
||||
.B "\fIcmdFile\fP \- file containing fsio commands"
|
||||
.B "\fIcmdFile\fP \- File containing \fBfsio\fP commands"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -263,7 +283,7 @@ Displays help text on stdout.
|
||||
.br
|
||||
.TP
|
||||
.B "\fIexit\fP"
|
||||
Causes fsio to exit (the quit command has the same effect).
|
||||
Causes \fBfsio\fP to exit (the quit command has the same effect).
|
||||
.br
|
||||
.TP
|
||||
.B "\fIrewind\fP dev:"
|
||||
@@ -271,7 +291,7 @@ Positions the device to the start of the tape.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -281,7 +301,7 @@ Positions the device to the end of the tape.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.RE
|
||||
.RE
|
||||
@@ -291,7 +311,7 @@ Positions the device by skipping forward over files.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIn\fP \- # of files to skip (must be > 0)"
|
||||
.br
|
||||
@@ -303,7 +323,7 @@ Positions the device by skipping backward over files.
|
||||
.br
|
||||
.RS
|
||||
.RS
|
||||
.B "\fIdev:\fP \- name supplied on a previous mount"
|
||||
.B "\fIdev:\fP \- Name supplied on a previous mount"
|
||||
.br
|
||||
.B "\fIn\fP \- # of files to skip (must be > 0)"
|
||||
.br
|
||||
@@ -331,13 +351,16 @@ This function depends on the value of blks:
|
||||
.br
|
||||
.B "\fIdosmt\fP \- container file in DOS-11 magtape format"
|
||||
.br
|
||||
.B "\fIos8\fP \- OS/8 on RX01, RX01 or RK05"
|
||||
.B "\fIos8\fP \- OS/8 on RX01, RX02 or RK05"
|
||||
.br
|
||||
.B "\fIunixv7\fP \- Unix V7"
|
||||
.br
|
||||
.SH SEE ALSO
|
||||
.BR fsio-dos11 (1),
|
||||
.BR fsio-rt11 (1)
|
||||
.BR fsio-dosmt (1)
|
||||
.BR fsio-os8 (1)
|
||||
.BR fsio-unixv7 (1)
|
||||
.SH AUTHOR
|
||||
John Forecast, <john@forecast.name>
|
||||
.br
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -85,7 +85,7 @@
|
||||
* file is open, and this routine should verify that it contains a valid
|
||||
* file system. This routine may print out information about the file
|
||||
* system. Return 1 if the file system is valid, 0 if the file system is
|
||||
* invalid and -1 if the file system is invalid and an erroir message
|
||||
* invalid and -1 if the file system is invalid and an error message
|
||||
* has already been printed.
|
||||
*
|
||||
* void (*umount)(struct mountedFS *mount);
|
||||
@@ -97,8 +97,10 @@
|
||||
*
|
||||
* size_t (*size)(void)
|
||||
*
|
||||
* Return the number of byte used for the container file. The command
|
||||
* line switch (-t type) may be used to override the default size.
|
||||
* Return the number of bytes used for the container file. The command
|
||||
* line switch (-t type) may be used to override the default size. If
|
||||
* there is a problem computing the size of a container file (e.g. -t
|
||||
* switch missing), print an error message and return (size_t)-1.
|
||||
*
|
||||
* int (*newfs)(struct mountedFS *mount, size_t size);
|
||||
*
|
||||
@@ -108,6 +110,15 @@
|
||||
* by this command. This routine returns 1 if the file system was
|
||||
* successfully created, 0 otherwise.
|
||||
*
|
||||
* int (*mkdir)(struct mountedFS *mount, uint8_t unit, char *fname);
|
||||
*
|
||||
* Create a new empty directory on the mounted file system. This routine
|
||||
* returns 1 if the directory was successfully created, 0 otherwise. If
|
||||
* the "-p" switch is present (SWISSET('p')), any missing intermediate
|
||||
* directories will be created. If the "-p" switch is present and 0 is
|
||||
* returned, an unknown number of intermediate directories may have
|
||||
* been created.
|
||||
*
|
||||
* void (*set)(struct mountedFS *mount, uint8_t unit, uint8_t present);
|
||||
*
|
||||
* This routine is called when processing a "set" command. The arguments
|
||||
@@ -123,7 +134,7 @@
|
||||
* FS_UNITVALID set (see above), "present" is non-zero if a unit number
|
||||
* was included on the command line. For example, RT-11 uses "present"
|
||||
* to decide whether to display information about a single file system
|
||||
* ("present" 0) or all file systems in the containder ("present" 1).
|
||||
* ("present" 0) or all file systems in the container ("present" 1).
|
||||
*
|
||||
* void (*dir)(struct mountedFS *mount, uint8_t unit, char *fname);
|
||||
*
|
||||
@@ -284,6 +295,7 @@ int verbose = 0, quiet = 0;
|
||||
static void doMount(void);
|
||||
static void doUmount(void);
|
||||
static void doNewfs(void);
|
||||
static void doMkdir(void);
|
||||
static void doSet(void);
|
||||
static void doInfo(void);
|
||||
static void doDir(void);
|
||||
@@ -311,12 +323,13 @@ struct command {
|
||||
cmd_t func; /* Command execution function */
|
||||
} cmdTable[] = {
|
||||
#ifdef DEBUG
|
||||
{ "mount", OPTIONS("dfrt:x"), 3, 3, 0, doMount },
|
||||
{ "mount", OPTIONS("dfo:rt:x"), 3, 3, 0, doMount },
|
||||
#else
|
||||
{ "mount", OPTIONS("frt:x"), 3, 3, 0, doMount },
|
||||
{ "mount", OPTIONS("fo:rt:x"), 3, 3, 0, doMount },
|
||||
#endif
|
||||
{ "umount", NULL, 1, 1, 0, doUmount },
|
||||
{ "newfs", OPTIONS("e:t:"), 2, 2, 0, doNewfs },
|
||||
{ "newfs", OPTIONS("b:e:i:t:"), 2, 2, 0, doNewfs },
|
||||
{ "mkdir", OPTIONS("p"), 1, 1, 0, doMkdir },
|
||||
{ "set", NULL, 2, MAX_CMDLEN, 0, doSet },
|
||||
{ "info", NULL, 1, 1, 0, doInfo },
|
||||
{ "dir", OPTIONS("fn"), 1, 1, 0, doDir },
|
||||
@@ -336,6 +349,8 @@ struct command {
|
||||
{ NULL, NULL, 0, 0, 0, doExit }
|
||||
};
|
||||
|
||||
char *command = NULL; /* Current command being executed */
|
||||
|
||||
/*
|
||||
* Switches and values
|
||||
*/
|
||||
@@ -406,6 +421,7 @@ extern struct FSdef dos11FS;
|
||||
extern struct FSdef rt11FS;
|
||||
extern struct FSdef dosmtFS;
|
||||
extern struct FSdef os8FS;
|
||||
extern struct FSdef unixv7FS;
|
||||
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
@@ -463,6 +479,9 @@ static void FSioInit(void)
|
||||
|
||||
os8FS.next = fileSystems;
|
||||
fileSystems = &os8FS;
|
||||
|
||||
unixv7FS.next = fileSystems;
|
||||
fileSystems = &unixv7FS;
|
||||
}
|
||||
|
||||
/*++
|
||||
@@ -609,7 +628,6 @@ static int checkDev(
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* cmd - current command name
|
||||
* dev - pointer to device name + file specification
|
||||
* unit - return optional unit number here
|
||||
* present - return unit present indicator here (0 or 1)
|
||||
@@ -626,7 +644,6 @@ static int checkDev(
|
||||
*
|
||||
--*/
|
||||
static struct mountedFS *findMount(
|
||||
char *cmd,
|
||||
char *dev,
|
||||
uint8_t *unit,
|
||||
uint8_t *present,
|
||||
@@ -655,13 +672,15 @@ static struct mountedFS *findMount(
|
||||
unitno = strtoul(&dev[i], &endptr, 8);
|
||||
if (*endptr != '\0') {
|
||||
fprintf(stderr,
|
||||
"%s: Device \"%s\" unit number invalid\n", cmd, origdev);
|
||||
"%s: Device \"%s\" unit number invalid\n",
|
||||
command, origdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (unitno > 0377) {
|
||||
fprintf(stderr,
|
||||
"%s: Device \"%s\" unit number too large\n", cmd, origdev);
|
||||
"%s: Device \"%s\" unit number too large\n",
|
||||
command, origdev);
|
||||
return NULL;
|
||||
}
|
||||
dev[i] ='\0';
|
||||
@@ -670,7 +689,7 @@ static struct mountedFS *findMount(
|
||||
}
|
||||
fprintf(stderr,
|
||||
"%s: Device \"%s\" contains non-alpha character\n",
|
||||
cmd, origdev);
|
||||
command, origdev);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -683,12 +702,13 @@ static struct mountedFS *findMount(
|
||||
((fs->filesys->flags & FS_UNITVALID) != 0))
|
||||
break;
|
||||
fprintf(stderr,
|
||||
"%s: \"%s\" does not support unit numbers\n", cmd, fs->name);
|
||||
"%s: \"%s\" does not support unit numbers\n",
|
||||
command, fs->name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fs == NULL)
|
||||
fprintf(stderr, "%s: Device \"%s\" not mounted\n", cmd, origdev);
|
||||
fprintf(stderr, "%s: Device \"%s\" not mounted\n", command, origdev);
|
||||
} else {
|
||||
if (getenv("FSioForceLocal") != NULL) {
|
||||
fprintf(stderr, "Local file system access requires use of \"local:\"\n");
|
||||
@@ -938,11 +958,14 @@ static void doNewfs(void)
|
||||
/*
|
||||
* Get the required container file size.
|
||||
*/
|
||||
if (filesys->size != NULL)
|
||||
if (filesys->size != NULL) {
|
||||
size = (*filesys->size)();
|
||||
if (size == (size_t)-1)
|
||||
return;
|
||||
}
|
||||
|
||||
if ((mount.container = fopen(words[0], "w+")) != NULL) {
|
||||
off_t offset = size - 1;
|
||||
off_t offset = size ? size - 1 : 0;
|
||||
|
||||
mount.skip = 0;
|
||||
|
||||
@@ -971,6 +994,39 @@ static void doNewfs(void)
|
||||
} else fprintf(stderr, "newfs: \"%s\" is not a supported file system type\n", words[1]);
|
||||
}
|
||||
|
||||
/*++
|
||||
* d o M k d i r
|
||||
*
|
||||
* Create a new empty directory on a mounted file system. This command is
|
||||
* only available if the file system supports multiple directories.
|
||||
*
|
||||
* Inputs:
|
||||
*
|
||||
* None
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* None
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* None
|
||||
*
|
||||
--*/
|
||||
static void doMkdir(void)
|
||||
{
|
||||
struct mountedFS *mount;
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if (mount->filesys->mkdir != NULL)
|
||||
(*mount->filesys->mkdir)(mount, unit, fname);
|
||||
else fprintf(stderr, "mkdir: \"%s\" does not support \"mkdir\" command\n",
|
||||
mount->filesys->fstype);
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* d o S e t
|
||||
*
|
||||
@@ -995,7 +1051,7 @@ static void doSet(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("set", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if (*fname == '\0') {
|
||||
if (mount->filesys->set != NULL)
|
||||
(*mount->filesys->set)(mount, unit, present);
|
||||
@@ -1029,7 +1085,7 @@ static void doInfo(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("info", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if (*fname == '\0')
|
||||
(*mount->filesys->info)(mount, unit, present);
|
||||
else fprintf(stderr, "info: Does not expect a file name\n");
|
||||
@@ -1060,7 +1116,7 @@ static void doDir(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("dir", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
(*mount->filesys->dir)(mount, unit, fname);
|
||||
return;
|
||||
}
|
||||
@@ -1091,7 +1147,7 @@ static void doDump(void)
|
||||
void *file;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("dump", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((file = (*mount->filesys->openFileR)(mount, unit, fname)) != NULL) {
|
||||
unsigned int offset = 0, datasz = 2;
|
||||
uint8_t data1;
|
||||
@@ -1210,8 +1266,8 @@ static void doCopy(void)
|
||||
void *fileSrc, *fileDest;
|
||||
char *endptr;
|
||||
|
||||
mountSrc = findMount("copy", words[0], &unitSrc, &presentSrc, &fnameSrc);
|
||||
mountDest = findMount("copy", words[1], &unitDest, &presentDest, &fnameDest);
|
||||
mountSrc = findMount(words[0], &unitSrc, &presentSrc, &fnameSrc);
|
||||
mountDest = findMount(words[1], &unitDest, &presentDest, &fnameDest);
|
||||
|
||||
if ((mountSrc != NULL) && (mountDest != NULL)) {
|
||||
fsSrc = mountSrc->filesys;
|
||||
@@ -1300,7 +1356,7 @@ static void doType(void)
|
||||
*/
|
||||
SWSET('a');
|
||||
|
||||
if ((mount = findMount("type", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((file = (*mount->filesys->openFileR)(mount, unit, fname)) != NULL) {
|
||||
char buf[BFRSIZ];
|
||||
size_t len, i;
|
||||
@@ -1344,7 +1400,7 @@ static void doDelete(void)
|
||||
void *file;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("delete", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if (mount->filesys->deleteFile != NULL) {
|
||||
if ((mount->flags & FS_READONLY) == 0) {
|
||||
if ((file = (*mount->filesys->openFileR)(mount, unit, fname)) != NULL)
|
||||
@@ -1479,6 +1535,9 @@ static void doHelp(void)
|
||||
"Create a new container file with an empty file system. The \"-t type\"\n"
|
||||
"switch may be used to control the size of the container file, this\n"
|
||||
"switch is file-system dependent.\n\n"
|
||||
" mkdir [-p] dev:dirspec\n\n"
|
||||
"Create a new empty directory on a mounted file system. The \"-p\"\n"
|
||||
"switch may be used to create any missing intermediate directories.\n\n"
|
||||
" set dev: args ...\n\n"
|
||||
"Set parameter(s) on a mounted file system.\n\n"
|
||||
" info dev:\n\n"
|
||||
@@ -1597,7 +1656,7 @@ static void doRewind(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("rewind", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount->filesys->flags & FS_TAPE) == 0) {
|
||||
fprintf(stderr, "rewind: Command only valid on magtapes\n");
|
||||
return;
|
||||
@@ -1633,7 +1692,7 @@ static void doEOM(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("eom", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount->filesys->flags & FS_TAPE) == 0) {
|
||||
fprintf(stderr, "eom: Command only valid on magtapes\n");
|
||||
return;
|
||||
@@ -1670,7 +1729,7 @@ static void doSkipForw(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("skipf", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount->filesys->flags & FS_TAPE) == 0) {
|
||||
fprintf(stderr, "skipf: Command only valid on magtapes\n");
|
||||
return;
|
||||
@@ -1716,7 +1775,7 @@ static void doSkipRev(void)
|
||||
char *fname;
|
||||
uint8_t unit, present;
|
||||
|
||||
if ((mount = findMount("skipf", words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount = findMount(words[0], &unit, &present, &fname)) != NULL) {
|
||||
if ((mount->filesys->flags & FS_TAPE) == 0) {
|
||||
fprintf(stderr, "skipr: Command only valid on magtapes\n");
|
||||
return;
|
||||
@@ -1869,6 +1928,7 @@ static void FSioExecute(
|
||||
/*
|
||||
* Execute the command.
|
||||
*/
|
||||
command = cmdTable[idx].name;
|
||||
(*cmdTable[idx].func)();
|
||||
} else fprintf(stderr, "Unknown command \"%s\"\n", words[0]);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -35,12 +35,13 @@
|
||||
/*
|
||||
* Mode for open files
|
||||
*/
|
||||
enum openMode { M_RD, M_WR };
|
||||
enum openMode { M_RD, M_WR, M_UNKNOWN };
|
||||
|
||||
#include "dos11.h"
|
||||
#include "rt11.h"
|
||||
#include "dosmt.h"
|
||||
#include "os8.h"
|
||||
#include "unixv7.h"
|
||||
|
||||
/*
|
||||
* All of the supported file systems are natively little endian so we only
|
||||
@@ -81,7 +82,7 @@ enum openMode { M_RD, M_WR };
|
||||
#endif
|
||||
|
||||
extern uint32_t swPresent;
|
||||
extern char *swValue[];
|
||||
extern char *command, *swValue[];
|
||||
|
||||
#define SWISSET(c) ((swPresent & (1 << (c - 'a'))) != 0)
|
||||
#define SWSET(c) swPresent |= (1 << (c - 'a'))
|
||||
@@ -114,6 +115,7 @@ struct FSdef {
|
||||
void (*umount)(struct mountedFS *);
|
||||
size_t (*size)(void);
|
||||
int (*newfs)(struct mountedFS *, size_t);
|
||||
int (*mkdir)(struct mountedFS *, uint8_t, char *);
|
||||
void (*set)(struct mountedFS *, uint8_t, uint8_t);
|
||||
void (*info)(struct mountedFS *, uint8_t, uint8_t);
|
||||
void (*dir)(struct mountedFS *, uint8_t, char *);
|
||||
@@ -157,11 +159,13 @@ struct mountedFS {
|
||||
struct RT11data _rt11;
|
||||
struct DOSMTdata _dosmt;
|
||||
struct OS8data _os8;
|
||||
struct UNIXV7data _unixv7;
|
||||
} FSdata;
|
||||
#define dos11data FSdata._dos11
|
||||
#define rt11data FSdata._rt11
|
||||
#define dosmtdata FSdata._dosmt
|
||||
#define os8data FSdata._os8
|
||||
#define unixv7data FSdata._unixv7
|
||||
};
|
||||
|
||||
extern int FSioReadBlob(struct mountedFS *, off_t, unsigned int, void *);
|
||||
|
||||
@@ -26,6 +26,8 @@ umount - removes knowledge of a container file from fsio
|
||||
|
||||
newfs - create a new container with an empty file system
|
||||
|
||||
mkdir - create a new directory
|
||||
|
||||
set - set file system parameters
|
||||
|
||||
info - display information about the file system
|
||||
@@ -87,19 +89,27 @@ Full command syntax:
|
||||
|
||||
1. mount
|
||||
|
||||
mount [-dfr] [-t type] dev[:] container type
|
||||
mount [-dfr] [-o nnn] [-t type] dev[:] container type
|
||||
|
||||
Make the specified container file available to fsio for I/O.
|
||||
|
||||
-d Generate debug output if fsio is built with the DEBUG symbol
|
||||
defined
|
||||
|
||||
-f Force the mount to happen even if we are unable to completely
|
||||
validate the container file format
|
||||
|
||||
-r If present, the file system is only available for read access
|
||||
|
||||
-o nnn This is only valid for Unix V7 file systems for specifying
|
||||
the starting offset of a partition within the container
|
||||
file.
|
||||
|
||||
-t type Specify the type of the container file. This is only required
|
||||
for OS/8 file systems where type should be one of "rx01",
|
||||
"rx02" or "rk05".
|
||||
"rx02" or "rk05". It is not required for Unix V7 file systems
|
||||
but, if supplied, allows for an additional integrity check
|
||||
before mounting the file system.
|
||||
|
||||
dev[:] User supplied name to be used for accessing files within the
|
||||
container file. Files within the container are named by using
|
||||
@@ -126,7 +136,7 @@ Full command syntax:
|
||||
|
||||
3. newfs
|
||||
|
||||
newfs [-t type] container type
|
||||
newfs [-b size] [-t type] container type
|
||||
|
||||
Create a new container file with an empty file system. The container
|
||||
will be a fixed size (depending on file system type) and may not exist
|
||||
@@ -137,7 +147,10 @@ Full command syntax:
|
||||
dos11 RK05 image (2.5MB, 4800 blocks)
|
||||
rt11 MSCP image (32MB, 65535 blocks)
|
||||
dosmt An empty file suitable for use with any magtape controller
|
||||
os8 An OS/8 file system
|
||||
os8 RK05 image (2.5MB, 3248 blocks)
|
||||
unixv7 RK05 image (2.5MB, 4872 blocks)
|
||||
|
||||
-b size Specify # of blocks for the container (only valid for unixv7)
|
||||
|
||||
-t type Use a different size for the container file. The size used
|
||||
will be file system dependent.
|
||||
@@ -153,11 +166,30 @@ Full command syntax:
|
||||
rx01 RX01 image (2002 sectors of 128 bytes each)
|
||||
rx02 RX02 imgae (2002 sectors of 256 bytes each)
|
||||
|
||||
For unixv7, the following disk types are valid:
|
||||
|
||||
rk05 RK05 image (4871 blocks)
|
||||
rl01 RL01 image (5MB, 10240 blocks)
|
||||
rl02 RL02 image (10MB, 20480 blocks)
|
||||
rk06 RK06 image (13MB, 27126 blocks)
|
||||
rk07 RK07 image (26MB, 53790 blocks)
|
||||
|
||||
container The name of the file to create
|
||||
|
||||
type The type of the file system to create in the container
|
||||
|
||||
4. set
|
||||
4. mkdir
|
||||
|
||||
mkdir [-p] dev:dirspec
|
||||
|
||||
Creates a new empty directory on a mounted file system.
|
||||
|
||||
-p If present, create any missing intermediate directories.
|
||||
|
||||
dev: The name of a previosly mounted file system
|
||||
dirspec Specification of the directory to create using the dev: syntax.
|
||||
|
||||
5. set
|
||||
|
||||
set dev: args ...
|
||||
|
||||
@@ -166,7 +198,7 @@ Full command syntax:
|
||||
|
||||
dev: The name of a previously mounted file system
|
||||
|
||||
5. info
|
||||
6. info
|
||||
|
||||
info dev:
|
||||
|
||||
@@ -175,7 +207,7 @@ Full command syntax:
|
||||
|
||||
dev: The name of a previously mounted file system
|
||||
|
||||
6. dir
|
||||
7. dir
|
||||
|
||||
dir [-fn] dev:dirspec
|
||||
|
||||
@@ -188,7 +220,7 @@ Full command syntax:
|
||||
dev: The name of a previosly mounted file system
|
||||
dirspec Specification of the directory to list using the dev: syntax.
|
||||
|
||||
7. dump
|
||||
8. dump
|
||||
|
||||
dump [-bcdnwx] dev:src
|
||||
|
||||
@@ -209,7 +241,7 @@ Full command syntax:
|
||||
dev: The name of a previosly mounted file system
|
||||
src The name of the source file (e.g. dp:input.dat)
|
||||
|
||||
8. copy
|
||||
9. copy
|
||||
|
||||
copy [-anpc blocks] dev1:src dev2:dest
|
||||
|
||||
@@ -244,7 +276,7 @@ Full command syntax:
|
||||
Note that wildcard naming is not supported and the source and destination
|
||||
file names must be fully specified.
|
||||
|
||||
9. type
|
||||
10. type
|
||||
|
||||
type [-n] dev:src
|
||||
|
||||
@@ -257,7 +289,7 @@ Full command syntax:
|
||||
dev: The name of a previously mounted file system
|
||||
src The name of the source file (e.g. dp:input.txt)
|
||||
|
||||
10. delete
|
||||
11. delete
|
||||
|
||||
delete dev:file
|
||||
|
||||
@@ -266,13 +298,13 @@ Full command syntax:
|
||||
dev: The name of a previously mounted file system
|
||||
file The name of the file to be deleted
|
||||
|
||||
11. status
|
||||
12. status
|
||||
|
||||
status
|
||||
|
||||
Displays the currently mounted file systems.
|
||||
|
||||
12. do
|
||||
13. do
|
||||
|
||||
do [-q] cmdFile
|
||||
|
||||
@@ -280,19 +312,19 @@ Full command syntax:
|
||||
|
||||
-q By default, command lines are echoed. Use -q to not echo.
|
||||
|
||||
13. help
|
||||
14. help
|
||||
|
||||
help
|
||||
|
||||
Display help text on the terminal.
|
||||
|
||||
14. exit
|
||||
15. exit
|
||||
|
||||
exit
|
||||
|
||||
Terminates the fsio application.
|
||||
|
||||
15. rewind
|
||||
16. rewind
|
||||
|
||||
rewind dev:
|
||||
|
||||
@@ -300,7 +332,7 @@ Full command syntax:
|
||||
|
||||
dev: The name of a previously mounted file system
|
||||
|
||||
16. eom
|
||||
17. eom
|
||||
|
||||
eom dev:
|
||||
|
||||
@@ -309,7 +341,7 @@ Full command syntax:
|
||||
|
||||
dev: The name of a previously mounted file system
|
||||
|
||||
17. skipf
|
||||
18. skipf
|
||||
|
||||
skipf dev: n
|
||||
|
||||
@@ -320,7 +352,7 @@ Full command syntax:
|
||||
dev: The name of a previously mounted file system
|
||||
n Number of files to skip (must be > 0)
|
||||
|
||||
18. skipr
|
||||
19. skipr
|
||||
|
||||
skipr dev: n
|
||||
|
||||
|
||||
@@ -83,6 +83,36 @@ pair <cr><lf> which RT-11 requires. In addition, unless the file ends
|
||||
exactly on a block (512 bytes) boundary, a ^Z (octal 32) will be appended
|
||||
to the file indicating end-of-file.
|
||||
|
||||
Research Unix V7
|
||||
----------------
|
||||
|
||||
For Unix V7, fsio understands the native disk format so we can transfer
|
||||
directly into the bootable SIMH disk ("unix_v7_rl.dsk" in the examples). Note
|
||||
that Unix disks may contain multiple partitions but the partition layout was
|
||||
not typically recorded on the disk, it was hard coded into the device driver.
|
||||
fsio does support the "-o nnn" switch to mount to specify the block offset of
|
||||
the partition to be mounted if it is not the first on the disk. The example
|
||||
below will copy an ASCII file into the root directory of the partition (if
|
||||
fsio is running on a Unix-like system, the "-a" switch is not needed):
|
||||
|
||||
pi@host:~ $ fsio
|
||||
fsio> mount dl unix_v7_rl.dsk unixv7
|
||||
Pack name: , File system name: , Total blocks: 18000
|
||||
fsio> copy -a file.txt dl:file.txt
|
||||
fsio> quit
|
||||
pi@host:~ $
|
||||
|
||||
By default, new files will be created with UID 0, GID 0. To override this use:
|
||||
|
||||
fsio> set dl: uid 1
|
||||
fsio> set dl: gid 100
|
||||
fsio> copy -a file.txt dl:file.txt
|
||||
|
||||
Research Unix V7 was distributed by DEC as v7m and later as Ultrix-11.
|
||||
Ultrix-11 V3.0/V3.1 used a modified disk layout with a 1K byte block size
|
||||
which is incompatible with fsio but it did come with /etc/rawfs which allows
|
||||
access to disks using a 512 byte block size.
|
||||
|
||||
|
||||
Foreign File System Support
|
||||
---------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -356,6 +356,7 @@ struct FSdef localFS = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
localInfo,
|
||||
localDir,
|
||||
localOpenFileR,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2019 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -2384,7 +2384,7 @@ static void os8Umount(
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* Size of the container file in block of default file system size
|
||||
* Size of the container file in blocks of default file system size
|
||||
*
|
||||
--*/
|
||||
static size_t os8Size(void)
|
||||
@@ -2410,7 +2410,7 @@ static size_t os8Size(void)
|
||||
* Inputs:
|
||||
*
|
||||
* mount - pointer to a mounted file system descriptor
|
||||
* (nit in the mounted file system list)
|
||||
* (not in the mounted file system list)
|
||||
* size - the sized (in blocks) of the filesystem
|
||||
*
|
||||
* Outputs:
|
||||
@@ -2440,7 +2440,8 @@ static int os8Newfs(
|
||||
|
||||
dev++;
|
||||
}
|
||||
dev = OS8Devices;
|
||||
fprintf(stderr, "newfs: Unknown device type \"%s\"\n", SWGETVAL('t'));
|
||||
return 0;
|
||||
}
|
||||
found:
|
||||
mount->skip = dev->skip;
|
||||
@@ -2862,8 +2863,6 @@ static void os8DeleteFile(
|
||||
data->buf[file->offset + OS8_DI_FNAME1] = 0;
|
||||
data->buf[file->offset + OS8_ED_LENGTH] =
|
||||
data->buf[file->offset + file->extra + OS8_DI_LENGTH];
|
||||
data->buf[OS8_DH_ENTRIES] =
|
||||
htole16(os8Value(-(os8Neg(le16toh(data->buf[OS8_DH_ENTRIES])) - 1)));
|
||||
|
||||
os8SlideUp(mount, file->offset + OS8_ED_SIZE,
|
||||
file->offset + file->entrysz, file->entrysz, file->remain);
|
||||
@@ -2905,6 +2904,12 @@ static void os8CloseFile(
|
||||
struct os8OpenFile *file = filep;
|
||||
|
||||
if (file->mode == M_WR) {
|
||||
if (SWISSET('a')) {
|
||||
char ch ='\032';
|
||||
|
||||
os8WriteBytes(file, &ch, 1);
|
||||
}
|
||||
|
||||
if (file->current != 0)
|
||||
/*
|
||||
* Flush the current buffer.
|
||||
@@ -2946,7 +2951,41 @@ static size_t os8ReadFile(
|
||||
)
|
||||
{
|
||||
struct os8OpenFile *file = filep;
|
||||
char *bufr = buf;
|
||||
|
||||
if (SWISSET('a')) {
|
||||
char ch;
|
||||
size_t count = 0;
|
||||
|
||||
if (file->eof != 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Read a full or partial line from the open file.
|
||||
*/
|
||||
while ((buflen != 0) && (os8ReadBytes(file, &ch, 1) == 1)) {
|
||||
if (ch == '\032') {
|
||||
/*
|
||||
* ^Z indicating EOF
|
||||
*/
|
||||
file->eof = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ignore NULL bytes in ASCII mode
|
||||
*/
|
||||
if (ch != '\0') {
|
||||
ch &= 0177;
|
||||
bufr[count++] = ch;
|
||||
buflen--;
|
||||
if (ch == '\n')
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
return os8ReadBytes(file, buf, buflen);
|
||||
}
|
||||
|
||||
@@ -2997,6 +3036,7 @@ struct FSdef os8FS = {
|
||||
os8Umount,
|
||||
os8Size,
|
||||
os8Newfs,
|
||||
NULL,
|
||||
os8Set,
|
||||
os8Info,
|
||||
os8Dir,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2019 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -217,6 +217,7 @@ struct os8OpenFile {
|
||||
uint16_t wordpos; /* Current word offset */
|
||||
uint8_t bytepos; /* Current byte position */
|
||||
off_t written; /* # of bytes written to the file */
|
||||
uint8_t eof; /* EOF seen on last read */
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -1565,7 +1565,7 @@ static int validate(
|
||||
|
||||
position += le16toh(data->buf[off + RT11_DI_LENGTH]);
|
||||
|
||||
if ((status & RT11_E_MPTY) != 0)
|
||||
if ((status & RT11_E_EOS) != 0)
|
||||
break;
|
||||
|
||||
/*
|
||||
@@ -1656,8 +1656,8 @@ int rt11ReadBytes(
|
||||
* Inputs:
|
||||
*
|
||||
* file - pointer to an open file descriptor
|
||||
* buf - pointer to a buffer to receive the data
|
||||
* len - # of bytes of data to read
|
||||
* buf - pointer to a buffer with the data to be written
|
||||
* len - # of bytes of data to write
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
@@ -1881,9 +1881,15 @@ static int rt11Mount(
|
||||
}
|
||||
|
||||
printf("%s%o:\n", mount->name, i);
|
||||
if (version != NULL)
|
||||
printf(" Version: %s, System ID: %12s\n",
|
||||
version, (char *)&data->buf[RT11_HB_SYSID]);
|
||||
if (version != NULL) {
|
||||
char sysid[16];
|
||||
|
||||
memset(sysid, 0, sizeof(sysid));
|
||||
strncpy(sysid, (char *)&data->buf[RT11_HB_SYSID],
|
||||
strlen(RT11_SYSID));
|
||||
|
||||
printf(" Version: %s, System ID: %s\n", version, sysid);
|
||||
}
|
||||
printf(" Total blocks: %5d, Free blocks: %5d\n"
|
||||
" Directory segments: %2d (Highest in use: %d)\n"
|
||||
" Extra bytes/directory entry: %d\n",
|
||||
@@ -1958,7 +1964,8 @@ static size_t rt11Size(void)
|
||||
}
|
||||
if (size == ((RT11_MAXPARTSZ - 1) * RT11_BLOCKSIZE))
|
||||
fprintf(stderr,
|
||||
"newfs: Invalid device type \"%s\", using default\n", type);
|
||||
"%s: Invalid device type \"%s\", using default\n",
|
||||
command, type);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@@ -2027,7 +2034,6 @@ static int rt11Newfs(
|
||||
* Remove possible first track
|
||||
*/
|
||||
size = (size - mount->skip) / RT11_BLOCKSIZE;
|
||||
// size = ((size * RT11_BLOCKSIZE) - mount->skip) / RT11_BLOCKSIZE;
|
||||
|
||||
/*
|
||||
* Mark partition 0 as valid
|
||||
@@ -2570,6 +2576,7 @@ struct FSdef rt11FS = {
|
||||
rt11Size,
|
||||
rt11Newfs,
|
||||
NULL,
|
||||
NULL,
|
||||
rt11Info,
|
||||
rt11Dir,
|
||||
rt11OpenFileR,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018 John Forecast. All Rights Reserved.
|
||||
* Copyright (C) 2018 - 2025 John Forecast. All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
@@ -568,7 +568,7 @@ int tapeWriteEOM(
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* 1 if EOM record successfully written, 0 otherwise
|
||||
* 1 if TM record successfully written, 0 otherwise
|
||||
*
|
||||
--*/
|
||||
int tapeWriteTM(
|
||||
|
||||
3080
converters/fsio/unixv7.c
Normal file
3080
converters/fsio/unixv7.c
Normal file
File diff suppressed because it is too large
Load Diff
258
converters/fsio/unixv7.h
Normal file
258
converters/fsio/unixv7.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2025, John Forecast
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
JOHN FORECAST BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of John Forecast shall not
|
||||
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from John Forecast.
|
||||
|
||||
*/
|
||||
#ifndef __UNIXV7_H__
|
||||
#define __UNIXV7_H__
|
||||
|
||||
/*
|
||||
* General disk layout:
|
||||
*
|
||||
* Block
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 0 | Reserved |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 1 | Super Block |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* 2 | I nodes |
|
||||
* | ... |
|
||||
* | ... |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | Data Blocks |
|
||||
* | ... |
|
||||
* | ... |
|
||||
* | ... |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* End of Volume
|
||||
*/
|
||||
|
||||
/*
|
||||
* Common data types
|
||||
*/
|
||||
typedef int16_t v7_short;
|
||||
typedef uint16_t v7_ushort;
|
||||
typedef int16_t v7_int;
|
||||
typedef uint16_t v7_uint;
|
||||
typedef int32_t v7_long;
|
||||
typedef uint32_t v7_ulong;
|
||||
|
||||
typedef int32_t v7_daddr_t;
|
||||
typedef uint16_t v7_ino_t;
|
||||
typedef int32_t v7_time_t;
|
||||
typedef int32_t v7_off_t;
|
||||
|
||||
/*
|
||||
* 32-bit longword values are stored with the high 16-bit word first
|
||||
*/
|
||||
#define V7_LONG(v) \
|
||||
((v7_long)((((v) & 0xFFFF) << 16) | (((v) & 0xFFFF0000) >> 16)))
|
||||
#define V7_ULONG(v) \
|
||||
((v7_ulong)((((v) & 0xFFFF) << 16) | (((v) & 0xFFFF0000) >> 16)))
|
||||
|
||||
#define V7_BLOCKSIZE 512
|
||||
#define V7_BSHIFT 9 /* Log2(V7_BLOCKSIZE) */
|
||||
#define V7_BMASK 0777 /* V7_BLOCKSIZE - 1 */
|
||||
#define V7_NINDIR ((int)(V7_BLOCKSIZE / sizeof(v7_daddr_t)))
|
||||
#define V7_NSHIFT 7 /* Log2(NINDIR) */
|
||||
#define V7_NMASK 0177 /* NINDIR - 1 */
|
||||
|
||||
#define V7_ROOTINO ((v7_ino_t)2) /* i number of all roots */
|
||||
#define V7_SUPERBLK 1 /* Super block address */
|
||||
#define V7_DIRSIZ 14 /* Max characters per directory */
|
||||
#define V7_NICFREE 50 /* Number of superblock free blocks */
|
||||
#define V7_NICINOD 100 /* Number of superblock inodes */
|
||||
|
||||
#define V7_STEPSIZE 9 /* Default step for freelist spacing */
|
||||
#define V7_CYLSIZE 400 /* Default cylinder size for spacing */
|
||||
|
||||
/*
|
||||
* Super-block
|
||||
*/
|
||||
#pragma pack(push, 1)
|
||||
struct v7_filsys {
|
||||
v7_ushort s_isize; /* Size in blocks of i-list */
|
||||
v7_daddr_t s_fsize; /* Size in blocks of entire volume */
|
||||
v7_short s_nfree; /* Number of addresses in s_free */
|
||||
v7_daddr_t s_free[V7_NICFREE];/* Free block list */
|
||||
v7_short s_ninode; /* Number of i-nodes in s_free */
|
||||
v7_ino_t s_inode[V7_NICINOD];/* Free i-node list */
|
||||
char s_flock; /* Lock during free list manip. */
|
||||
char s_ilock; /* Lock during i-list manip. */
|
||||
char s_fmod; /* Super-block modified flag */
|
||||
char s_ronly; /* Mounted read-only flag */
|
||||
v7_time_t s_time; /* Last super-block update */
|
||||
/*
|
||||
* Remainder not maintained by this version of the system
|
||||
*/
|
||||
v7_daddr_t s_tfree; /* Total free blocks */
|
||||
v7_ino_t s_tinode; /* Total free inodes */
|
||||
v7_short s_m; /* Interleave factor */
|
||||
v7_short s_n; /* " " */
|
||||
char s_fname[6]; /* File system name */
|
||||
char s_fpack[6]; /* File system pack name */
|
||||
};
|
||||
|
||||
/*
|
||||
* On-disk free space list at the head of each free block.
|
||||
*/
|
||||
struct v7_fblk {
|
||||
v7_int df_nfree; /* Number of addresses in df_free */
|
||||
v7_daddr_t df_free[V7_NICFREE];
|
||||
};
|
||||
|
||||
/*
|
||||
* On-disk inode structure
|
||||
*/
|
||||
struct v7_dinode {
|
||||
v7_ushort di_mode; /* Mode and type of file */
|
||||
v7_short di_nlink; /* Number of links to file */
|
||||
v7_short di_uid; /* Owner's user ID */
|
||||
v7_short di_gid; /* Owner's group ID */
|
||||
v7_off_t di_size; /* Number of bytes in file */
|
||||
char di_addr[40]; /* Disk block addresses */
|
||||
v7_time_t di_atime; /* Time last accessed */
|
||||
v7_time_t di_mtime; /* Time last modified */
|
||||
v7_time_t di_ctime; /* Time created */
|
||||
};
|
||||
#define V7_INOPB 8 /* 8 inodes per block */
|
||||
#define itod(x) ((v7_daddr_t)((x + 15) >> 3))
|
||||
#define itoo(x) ((v7_uint)((x + 15) & 07))
|
||||
#define itoff(x) ((v7_uint)(x + 15))
|
||||
|
||||
/*
|
||||
* The 40 address bytes:
|
||||
*
|
||||
* 39 used; 13 addresses of 3 bytes each
|
||||
*/
|
||||
#define NADDR 13
|
||||
|
||||
/*
|
||||
* Mode bits
|
||||
*/
|
||||
#define V7_IFMT 0170000 /* Type of file */
|
||||
#define V7_IFCHR 0020000 /* Character special */
|
||||
#define V7_IFBLK 0060000 /* Block special */
|
||||
#define V7_IFMPC 0030000 /* Multiplex character special */
|
||||
#define V7_IFMPB 0070000 /* Multiplex block special */
|
||||
#define V7_IFDIR 0040000 /* Directory */
|
||||
#define V7_IFLNK 0120000 /* Symbolic link */
|
||||
#define V7_IFREG 0100000 /* Regular */
|
||||
#define V7_ISUID 0004000 /* Set user ID on execution */
|
||||
#define V7_ISGID 0002000 /* Set group ID on execution */
|
||||
#define V7_ISVTX 0001000 /* Save swapped text even after use */
|
||||
#define V7_IREAD 0000400 /* Read permission, owner */
|
||||
#define V7_IWRITE 0000200 /* Write permission, owner */
|
||||
#define V7_IEXEC 0000100 /* Execute/Search permission, owner */
|
||||
|
||||
struct v7_direct {
|
||||
v7_ino_t d_ino; /* Inode number */
|
||||
char d_name[V7_DIRSIZ]; /* File name */
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/*
|
||||
* Disk block addresses are stored on disk in 2 formats:
|
||||
*
|
||||
* 1 - In the inode addr array, 3 bytes each which limits disk size to 16GB
|
||||
* 2 - In the free block list, 4 byte v7_long values
|
||||
*/
|
||||
#define V7_GET3ADDR(p, v) \
|
||||
{ uint8_t *tmp = (uint8_t *)p; \
|
||||
v = *tmp++ << 16; v |= *tmp++; v |= *tmp++ << 8; \
|
||||
}
|
||||
#define V7_PUT3ADDR(p, v) \
|
||||
{ uint8_t *tmp = (uint8_t *)p; \
|
||||
*tmp++ = (v >> 16) & 0xFF; *tmp++ = v & 0xFF; *tmp++ = (v >> 8) & 0xFF; \
|
||||
}
|
||||
#define V7_GET4ADDR(p, v) \
|
||||
{ uint16_t *tmp = (uint16_t *)p; \
|
||||
v = le16toh(*tmp++) << 16; v |= le16toh(*tmp); \
|
||||
}
|
||||
#define V7_PUT4ADDR(p, v) \
|
||||
{ uint16_t *tmp = (uint16_t *)p; \
|
||||
*tmp++ = htole16(v) >> 16; *tmp = htole16(v & 0xFFFF); \
|
||||
}
|
||||
|
||||
#define V7_READ 0 /* Read operation */
|
||||
#define V7_WRITE 1 /* Write operation */
|
||||
|
||||
/*
|
||||
* Structure to describe a file/directory name. * and % may be used as wild
|
||||
* card characters within each component of a name.
|
||||
*/
|
||||
#define UNIXV7_COMP 100 /* Maximum name depth */
|
||||
|
||||
struct unixv7FileSpec {
|
||||
int depth; /* Actual depth of this name */
|
||||
char wildcard; /* Wildcard options */
|
||||
char access; /* Access mode (existing/new file) */
|
||||
char *comp[UNIXV7_COMP];
|
||||
};
|
||||
#define UNIXV7_M_NONE 0000 /* Wild cards not allowed */
|
||||
#define UNIXV7_M_ALLOW 0001 /* Wild cards allowed */
|
||||
|
||||
#define UNIXV7_A_EXIST 0000 /* Access an existing file */
|
||||
#define UNIXV7_A_NEW 0001 /* Create a new file */
|
||||
|
||||
/*
|
||||
* Device descriptor
|
||||
*/
|
||||
struct UNIXV7device {
|
||||
char *name; /* Device name */
|
||||
size_t diskSize; /* # of blocks on device */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to define an open file.
|
||||
*/
|
||||
struct unixv7OpenFile {
|
||||
char name[V7_DIRSIZ + 1]; /* file name */
|
||||
v7_ino_t parent; /* inode number of parent directory */
|
||||
v7_ino_t ino; /* inode number of file */
|
||||
struct v7_dinode inode; /* on-disk inode copy */
|
||||
enum openMode mode; /* Open mode (read/write) */
|
||||
struct mountedFS *mount; /* Mounted file system descriptor */
|
||||
off_t offset; /* Current read/write point */
|
||||
uint32_t block; /* Current block in buffer */
|
||||
char *buffer; /* Private buffer for file I/O */
|
||||
};
|
||||
|
||||
/*
|
||||
* Unix V7 specific data area.
|
||||
*/
|
||||
struct UNIXV7data {
|
||||
unsigned int blocks; /* # of blocks in the file system */
|
||||
unsigned int offset; /* Block offset to partition start */
|
||||
uint16_t user; /* Default user ID */
|
||||
uint16_t group; /* Default group ID */
|
||||
union {
|
||||
struct v7_filsys sb;
|
||||
uint8_t super;
|
||||
} superblk; /* Holds super block */
|
||||
uint8_t buf[512]; /* Disk buffer */
|
||||
uint8_t zero[512]; /* Always contains 0's */
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user