From bf7c17ab4ab5bf37faecaeb1cc069e9948711abd Mon Sep 17 00:00:00 2001 From: Paul Koning Date: Wed, 27 Apr 2016 15:00:42 -0400 Subject: [PATCH] Add RSTSFLX V2.6. This is a file system access utility for RSTS file systems. It supports reading and writing as well as a number of other operations, such as octal dump, file system initialize, and file system check ("clean"). This was originally maintained as a Subversion repository at svn://akdesign.dyndns.org/flx/branches/V2.6. as suggested by Timothe Litt on the SIMH mailing list. --- .gitignore | 31 + extracters/Makefile | 4 + extracters/rstsflx/BUGS | 7 + extracters/rstsflx/HISTORY | 68 ++ extracters/rstsflx/LICENSE | 32 + extracters/rstsflx/Makefile | 86 ++ extracters/rstsflx/Makefile.dos | 133 +++ extracters/rstsflx/README | 25 + extracters/rstsflx/absio.h | 6 + extracters/rstsflx/borabsio.c | 42 + extracters/rstsflx/diskio.c | 262 +++++ extracters/rstsflx/diskio.h | 8 + extracters/rstsflx/djabsio.c | 304 ++++++ extracters/rstsflx/doalloc.c | 58 + extracters/rstsflx/doalloc.h | 1 + extracters/rstsflx/doclean.c | 1794 +++++++++++++++++++++++++++++++ extracters/rstsflx/doclean.h | 1 + extracters/rstsflx/docomp.c | 62 ++ extracters/rstsflx/docomp.h | 1 + extracters/rstsflx/dodelete.c | 28 + extracters/rstsflx/dodelete.h | 4 + extracters/rstsflx/dodir.c | 128 +++ extracters/rstsflx/dodir.h | 2 + extracters/rstsflx/dodump.c | 134 +++ extracters/rstsflx/dodump.h | 1 + extracters/rstsflx/doget.c | 193 ++++ extracters/rstsflx/doget.h | 1 + extracters/rstsflx/dohook.c | 350 ++++++ extracters/rstsflx/dohook.h | 13 + extracters/rstsflx/doident.c | 48 + extracters/rstsflx/doident.h | 1 + extracters/rstsflx/doinit.c | 387 +++++++ extracters/rstsflx/doinit.h | 2 + extracters/rstsflx/dolist.c | 218 ++++ extracters/rstsflx/dolist.h | 1 + extracters/rstsflx/doprot.c | 54 + extracters/rstsflx/doprot.h | 4 + extracters/rstsflx/doput.c | 301 ++++++ extracters/rstsflx/doput.h | 1 + extracters/rstsflx/dorename.c | 96 ++ extracters/rstsflx/dorename.h | 4 + extracters/rstsflx/dorts.c | 56 + extracters/rstsflx/dorts.h | 4 + extracters/rstsflx/dosabsio.c | 337 ++++++ extracters/rstsflx/dosabsio.h | 3 + extracters/rstsflx/dosrxio.c | 203 ++++ extracters/rstsflx/dotype.c | 28 + extracters/rstsflx/dotype.h | 4 + extracters/rstsflx/fdprm | 29 + extracters/rstsflx/fileio.c | 592 ++++++++++ extracters/rstsflx/fileio.h | 25 + extracters/rstsflx/filename.c | 309 ++++++ extracters/rstsflx/filename.h | 39 + extracters/rstsflx/fip.c | 1544 ++++++++++++++++++++++++++ extracters/rstsflx/fip.h | 87 ++ extracters/rstsflx/fldef.h | 299 ++++++ extracters/rstsflx/flx.dep | 45 + extracters/rstsflx/flx.doc | Bin 0 -> 123392 bytes extracters/rstsflx/flx.h | 227 ++++ extracters/rstsflx/flx.pdf | Bin 0 -> 348018 bytes extracters/rstsflx/linuxabsio.c | 233 ++++ extracters/rstsflx/platform.h | 65 ++ extracters/rstsflx/rstsflx.c | 166 +++ extracters/rstsflx/rstsflx.h | 3 + extracters/rstsflx/rtime.c | 76 ++ extracters/rstsflx/rtime.h | 12 + extracters/rstsflx/scancmd.c | 577 ++++++++++ extracters/rstsflx/scancmd.h | 11 + extracters/rstsflx/silfmt.h | 87 ++ extracters/rstsflx/unxabsio.c | 110 ++ extracters/rstsflx/version.h | 1 + 71 files changed, 10068 insertions(+) create mode 100644 extracters/rstsflx/BUGS create mode 100644 extracters/rstsflx/HISTORY create mode 100644 extracters/rstsflx/LICENSE create mode 100644 extracters/rstsflx/Makefile create mode 100644 extracters/rstsflx/Makefile.dos create mode 100644 extracters/rstsflx/README create mode 100644 extracters/rstsflx/absio.h create mode 100644 extracters/rstsflx/borabsio.c create mode 100644 extracters/rstsflx/diskio.c create mode 100644 extracters/rstsflx/diskio.h create mode 100644 extracters/rstsflx/djabsio.c create mode 100644 extracters/rstsflx/doalloc.c create mode 100644 extracters/rstsflx/doalloc.h create mode 100644 extracters/rstsflx/doclean.c create mode 100644 extracters/rstsflx/doclean.h create mode 100644 extracters/rstsflx/docomp.c create mode 100644 extracters/rstsflx/docomp.h create mode 100644 extracters/rstsflx/dodelete.c create mode 100644 extracters/rstsflx/dodelete.h create mode 100644 extracters/rstsflx/dodir.c create mode 100644 extracters/rstsflx/dodir.h create mode 100644 extracters/rstsflx/dodump.c create mode 100644 extracters/rstsflx/dodump.h create mode 100644 extracters/rstsflx/doget.c create mode 100644 extracters/rstsflx/doget.h create mode 100644 extracters/rstsflx/dohook.c create mode 100644 extracters/rstsflx/dohook.h create mode 100644 extracters/rstsflx/doident.c create mode 100644 extracters/rstsflx/doident.h create mode 100644 extracters/rstsflx/doinit.c create mode 100644 extracters/rstsflx/doinit.h create mode 100644 extracters/rstsflx/dolist.c create mode 100644 extracters/rstsflx/dolist.h create mode 100644 extracters/rstsflx/doprot.c create mode 100644 extracters/rstsflx/doprot.h create mode 100644 extracters/rstsflx/doput.c create mode 100644 extracters/rstsflx/doput.h create mode 100644 extracters/rstsflx/dorename.c create mode 100644 extracters/rstsflx/dorename.h create mode 100644 extracters/rstsflx/dorts.c create mode 100644 extracters/rstsflx/dorts.h create mode 100644 extracters/rstsflx/dosabsio.c create mode 100644 extracters/rstsflx/dosabsio.h create mode 100644 extracters/rstsflx/dosrxio.c create mode 100644 extracters/rstsflx/dotype.c create mode 100644 extracters/rstsflx/dotype.h create mode 100644 extracters/rstsflx/fdprm create mode 100644 extracters/rstsflx/fileio.c create mode 100644 extracters/rstsflx/fileio.h create mode 100644 extracters/rstsflx/filename.c create mode 100644 extracters/rstsflx/filename.h create mode 100644 extracters/rstsflx/fip.c create mode 100644 extracters/rstsflx/fip.h create mode 100644 extracters/rstsflx/fldef.h create mode 100644 extracters/rstsflx/flx.dep create mode 100644 extracters/rstsflx/flx.doc create mode 100644 extracters/rstsflx/flx.h create mode 100644 extracters/rstsflx/flx.pdf create mode 100644 extracters/rstsflx/linuxabsio.c create mode 100644 extracters/rstsflx/platform.h create mode 100644 extracters/rstsflx/rstsflx.c create mode 100644 extracters/rstsflx/rstsflx.h create mode 100644 extracters/rstsflx/rtime.c create mode 100644 extracters/rstsflx/rtime.h create mode 100644 extracters/rstsflx/scancmd.c create mode 100644 extracters/rstsflx/scancmd.h create mode 100644 extracters/rstsflx/silfmt.h create mode 100644 extracters/rstsflx/unxabsio.c create mode 100644 extracters/rstsflx/version.h diff --git a/.gitignore b/.gitignore index aff4fdb..d685c08 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,34 @@ *~ *.bak *.o +config11/config11 +converters/asc/asc +converters/decsys/decsys +converters/dtos8cvt/dtos8cvt +converters/gt7cvt/gt7cvt +converters/hpconvert/hpconvert +converters/indent/indent +converters/littcvt/littcvt +converters/m8376/m8376 +converters/mt2tpc/mt2tpc +converters/mtcvt23/mtcvtv23 +converters/mtcvtfix/mtcvtfix +converters/mtcvtodd/mtcvtodd +converters/noff/noff +converters/sfmtcvt/sfmtcvt +converters/strrem/strrem +converters/strsub/strsub +converters/tar2mt/tar2mt +converters/tp512cvt/tp512cvt +converters/tpc2mt/tpc2mt +crossassemblers/hpasm/hpasm +crossassemblers/macro1/macro1 +crossassemblers/macro7/macro7 +crossassemblers/macro8x/macro8x +extracters/ckabstape/ckabstape +extracters/mmdir/mmdir +extracters/mtdump/mtdump +extracters/rawcopy/RawCopy +extracters/rstsflx/flx +extracters/sdsdump/sdsdump +extracters/tpdump/tpdump diff --git a/extracters/Makefile b/extracters/Makefile index be52cc8..ec72b86 100644 --- a/extracters/Makefile +++ b/extracters/Makefile @@ -13,6 +13,7 @@ all: cd mmdir && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" cd mtdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" cd rawcopy && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" + cd rstsflx && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" cd sdsdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" cd tpdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" @@ -21,6 +22,7 @@ clean: cd mmdir && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" clean cd mtdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" clean cd rawcopy && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" clean + cd rstsflx && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" clean cd sdsdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" clean cd tpdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" clean @@ -29,6 +31,7 @@ install: cd mmdir && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" install cd mtdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" install cd rawcopy && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" install + cd rstsflx && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" install cd sdsdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" install cd tpdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" install @@ -37,5 +40,6 @@ uninstall: cd mmdir && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" uninstall cd mtdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" uninstall cd rawcopy && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" uninstall + cd rstsflx && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" uninstall cd sdsdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" uninstall cd tpdump && $(MAKE) CFLAGS="$(CFLAGS)" BIN="$(BIN)" INSTALL="$(INSTALL)" CC="$(CC)" uninstall diff --git a/extracters/rstsflx/BUGS b/extracters/rstsflx/BUGS new file mode 100644 index 0000000..98f905a --- /dev/null +++ b/extracters/rstsflx/BUGS @@ -0,0 +1,7 @@ +open bugs: +- delete does not honor priv (erase on delete) bit +- no readline support in dos +- filename completion does host file system completion, which is usually + the wrong thing +- "put" should pre-extend the output file if in binary copy mode. +- need error checking on I/O diff --git a/extracters/rstsflx/HISTORY b/extracters/rstsflx/HISTORY new file mode 100644 index 0000000..117d273 --- /dev/null +++ b/extracters/rstsflx/HISTORY @@ -0,0 +1,68 @@ +Changes for V2.6: +16.04.27 A couple of bugfixes. Changed license to BSD. + +Changes for V2.5: +00.08.24 Readline support for DOS now appears to be working, + thanks to a newer version of DJGPP. It needs to + be checked out a bit more, though, and there + still seem to be some oddities. + +Changes for V2.4: +00.01.16 Added upper limit check on INIT to hook command so + we don't try to hook an INIT that extends into the + space needed for the bootstrap. This duplicates + a check that exists in hook.sav. +00.01.18 Have "clean" display current dir and filename + even if not -verbose, but all on a single line. +00.01.23 Fix calculation of RE count in fileseek, which was + causing disk block out of range errors sometimes. + +Changes for V2.3: +00.01.02 Fixed eof calculation for RMS fixed files (-rf switch) + Added support for RX50 format 5.25 inch floppy access + in Linux. Added code to get size for raw disks + under Linux, so the -Size switch is no longer needed. + Changed date display format to use 4 digit years, and + fix some Y2K bugs. :-( +00.01.04 Fixed an elusive malloc bug. +00.01.08 Fixed RX50 I/O. + +Changes for V2.2: +99.12.02 Bugfix in RMS mode "get" for 32 bit int targets. + Use fgets instead of gets in scancmd. + +Changes for V2.0: + +- bugfix in protect command: allow file protection code changes even +if P bit is set (as RSTS does) + +- bugfix in rename: disallow rename/replace if new file name == old +name (previous code would delete the file and then crash) + +- bugfix in hook command for environments with 32-bit integers + +- fix platform.h so it may work better in Alphas (not tested for lack +of hardware) + +- change abort handler to use setjmp/longjmp so failure no longer +exits but goes back to command prompt if in prompting mode + +- added -noprotect as synonym for -unprotect + +- bugfix in list -summary: print correct ppns in per-directory summary +line. + +- added clean (rebuild) + +- added -odt and -offset to hook command. + +- bugfix in hook command to set clustersize (for disks whose +clustersize is not always the same) + +- bugfix in quota update if doing multiple directories since start of +program + +- allow [n,*] and [*,*] for gfd and mfd in get and dump commands + +- use GNU readline package, with command line recall including history +file. diff --git a/extracters/rstsflx/LICENSE b/extracters/rstsflx/LICENSE new file mode 100644 index 0000000..a6833ad --- /dev/null +++ b/extracters/rstsflx/LICENSE @@ -0,0 +1,32 @@ +License for RSTSFLX +-------------------- + +Copyright (c) 1994-2016, Paul Koning. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/extracters/rstsflx/Makefile b/extracters/rstsflx/Makefile new file mode 100644 index 0000000..2ea895d --- /dev/null +++ b/extracters/rstsflx/Makefile @@ -0,0 +1,86 @@ +# *** NOTE *** +# This makefile is set up for Linux. It will need some (small) changes to +# build under something else. See notes in comments below, marked with *** + +VERSION = 2.5 + +# objects +OBJS=\ + rstsflx.o \ + fip.o \ + rtime.o \ + filename.o \ + doget.o \ + dolist.o \ + doalloc.o \ + docomp.o \ + dotype.o \ + doput.o \ + dodump.o \ + dodelete.o \ + dorename.o \ + dorts.o \ + doprot.o \ + dodir.o \ + doident.o \ + doinit.o \ + dohook.o \ + scancmd.o \ + doclean.o \ + fileio.o \ + diskio.o \ + absio.o + +# Flags and the like + +# *** change the two lines below as needed for your C compiler. +CC ?= gcc +OPTIMIZE ?= -O2 -g2 +LDFLAGS ?= -g2 + +DEFINES = +CFLAGS = $(OPTIMIZE) $(DEFINES) $(EXTRAFLAGS) + +KITNAME = flx-$(VERSION) +DIR = flx + +# Rules + +S = $(OBJS:.o=.c) +SRCS = $(S:absio.c=unxabsio.c) + +# *** comment out or delete this first rule if not building on DOS +#flx.exe: flx +# strip flx +# coff2exe -s /djgpp/bin/go32.exe flx + +flx: $(OBJS) + $(CC) $(LDFLAGS) -o flx $(OBJS) $(EXTRAOBJS) -lreadline -lncurses $(EXTRAFLAGS) + +# *** the rule below builds absio.o. You need to use as source file +# *** an appropriate file; in Unix that's probably unxabsio.c but check +# *** the source file to be sure. + +absio.o: unxabsio.c + $(CC) -c -o absio.o $(CFLAGS) $< + +# general build rule for all other object files: +.c.o: + $(CC) -c $(CFLAGS) $< + +kit: + rm -f *~ + cd ..; tar cvzf $(KITNAME).tar.gz \ + $(DIR)/README $(DIR)/COPYING $(DIR)/BUGS $(DIR)/HISTORY \ + $(DIR)/Makefile* $(DIR)/*.c $(DIR)/*.h \ + $(DIR)/*.doc $(DIR)/*.pdf $(DIR)/fdprm + +clean: + rm -f *.o flx flx.exe flx.dep + + +flx.dep: + gcc -MM $(SRCS) > flx.dep + +# the one below is created by make depend +include flx.dep diff --git a/extracters/rstsflx/Makefile.dos b/extracters/rstsflx/Makefile.dos new file mode 100644 index 0000000..ecdd2da --- /dev/null +++ b/extracters/rstsflx/Makefile.dos @@ -0,0 +1,133 @@ +# *** NOTE *** +# This makefile is set up for DOS (DJGPP). It will need some (small) +# changes to build under Unix. See notes in comments below, marked with *** + +# sources +# *** note the first one, that's the absolute I/O source module. Change +# *** this to the one appropriate for your OS, for example unxabsio.c +# *** in the case of Unix. + +SRCS=\ + djabsio.c \ + rstsflx.c \ + fip.c \ + rtime.c \ + filename.c \ + doget.c \ + dolist.c \ + doalloc.c \ + docomp.c \ + dotype.c \ + doput.c \ + dodump.c \ + dodelete.c \ + dorename.c \ + dorts.c \ + doprot.c \ + dodir.c \ + doident.c \ + doinit.c \ + dohook.c \ + scancmd.c \ + fileio.c \ + diskio.c + +# prototype header files (none for rstsflx.c and scancmd.c) +PROTOS=\ + rstsflx.h \ + platform.h \ + fip.h \ + rtime.h \ + filename.h \ + doget.h \ + dolist.h \ + doalloc.h \ + docomp.h \ + dotype.h \ + doput.h \ + dodump.h \ + dodelete.h \ + dorename.h \ + dorts.h \ + doprot.h \ + dodir.h \ + doident.h \ + doinit.h \ + doinit.h \ + scancmd.h \ + fileio.h \ + diskio.h + +# objects +OBJS=\ + rstsflx.o \ + fip.o \ + rtime.o \ + filename.o \ + doget.o \ + dolist.o \ + doalloc.o \ + docomp.o \ + dotype.o \ + doput.o \ + dodump.o \ + dodelete.o \ + dorename.o \ + dorts.o \ + doprot.o \ + dodir.o \ + doident.o \ + doinit.o \ + dohook.o \ + scancmd.o \ + doclean.o \ + fileio.o \ + diskio.o \ + absio.o + +# Flags and the like + +# *** change the three lines below as needed for your C compiler. +CC= gcc +CFLAGS= -O3 -Wall +LFLAGS= + +# Rules + +# *** comment out or delete this first rule if not building on DOS +#flx.exe: flx +# strip flx +# coff2exe flx + +flx.exe: $(OBJS) + $(CC) -o flx.exe $(OBJS) -lreadline $(LFLAGS) + +# *** the rule below builds absio.o. You need to use as source file +# *** an appropriate file; in Unix that's probably unxabsio.c but check +# *** the source file to be sure. + +absio.o: djabsio.c + $(CC) -c -o absio.o $(CFLAGS) $< + +# general build rule for all other object files: +.c.o: + $(CC) -c $(CFLAGS) $< + +kit: + tar cvzf ../flx.tar.gz flx.exe \ + Makefile* *.c *.h *.doc *.ps *.txt *.html \ + README COPYING BUGS HISTORY + zip ../flx.zip flx.exe \ + Makefile* *.c *.h *.doc *.ps *.txt *.html \ + README COPYING BUGS HISTORY + +clean: + del *.o + del flx + del flx.exe + +depend: + gcc -MM *.c > flx.dep + +# the one below is created by make depend +include flx.dep diff --git a/extracters/rstsflx/README b/extracters/rstsflx/README new file mode 100644 index 0000000..72008a3 --- /dev/null +++ b/extracters/rstsflx/README @@ -0,0 +1,25 @@ +README file for FLX 1/11/2000 + +What you have here is the set of sources needed to build FLX, a +Makefile to do it, and documentation (in PostScript and the source in +MS Word format). + +Note on the Makefile: it has been used both with Mips Ultrix "cc" and +with gcc (with DOS and with Linux), but "make proto" only works with +cc since gcc doesn't support the -protoi switch. Don't worry about +that unless you change the sources in a way that affects the procedure +prototype declarations. (If you do, edit the .h file of the same name +as the .c file to reflect the changed prototypes.) + +As far as I know, everything that's described in flx.ps should work. +Let me know if you find problems. (I'll admit that I haven't tested +all the cases. For example, RDS0.0 support has had limited testing. +And I don't have a "large" disk to test large DCS support!) + +I've had very little feedback on this program. If you use it, even +if you have no comments on it, I'd appreciate a short note. And of +course if you do have comments, bug reports, or suggestions, then +definitely let me know! + + paul koning + ni1d@arrl.net diff --git a/extracters/rstsflx/absio.h b/extracters/rstsflx/absio.h new file mode 100644 index 0000000..de5f9ca --- /dev/null +++ b/extracters/rstsflx/absio.h @@ -0,0 +1,6 @@ +extern void absname (const char *rname); +extern int absopen (const char *rname, const char *mode); +extern void absseek (long block); +extern long absread (long sec, long count, void *buffer); +extern long abswrite (long sec, long count, void *buffer); +extern void absclose (void); diff --git a/extracters/rstsflx/borabsio.c b/extracters/rstsflx/borabsio.c new file mode 100644 index 0000000..73050db --- /dev/null +++ b/extracters/rstsflx/borabsio.c @@ -0,0 +1,42 @@ +/* absread and abswrite services for use with Borland C implementation + * + * Paul Koning 95.01.17 Dummy module (no absio in TC++ for Windows) + */ + +#include +#include + +#include "flx.h" +#include "absio.h" + +/* this routine is called to scan a supplied container file/device + * name. If the name refers to a real disk, then absflag is set + * and rsize is set to the device size. Otherwise, no action is taken. + */ + +void absname (const char *rname) +{ + if (rname[strlen(rname) - 1] == ':') { /* device name alone */ + printf ("Absolute I/O not supported\n"); + } +} + +int absopen (const char *rname, const char *mode) +{ + return (1); /* should never get here... */ +} + +void absseek (long block) { } /* nothing to do */ + +void absclose () { } /* nothing to do */ + +long absread (long sec, long count, void *buffer) +{ + return (0); /* should never get here... */ +} + +long abswrite (long sec, long count, void *buffer) +{ + return (0); /* should never get here... */ +} + diff --git a/extracters/rstsflx/diskio.c b/extracters/rstsflx/diskio.c new file mode 100644 index 0000000..fb6b4c4 --- /dev/null +++ b/extracters/rstsflx/diskio.c @@ -0,0 +1,262 @@ +/* subroutines to do rsts disk (logical block) I/O */ + +#include +#include +#include +#include +#include +#include + +#include "flx.h" +#include "diskio.h" +#include "absio.h" + +#define DEFDEVICE "rsts.dsk" + +#define NOLAST 0 +#define LASTREAD 1 +#define LASTWRITE 2 + +#ifndef S_ISCHR +#define S_ISCHR(x) (((x) & S_IFMT) == S_IFCHR) +#endif + +typedef struct { + const char *name; /* Name of the disk */ + long tsize; /* Total container size */ + long rsize; /* Size RSTS uses */ + int dec166; /* TRUE if disk has factor bad block table */ +} diskent; + +int dcs; /* device clustersize */ +long diskblocks; /* device block count */ +const char *rname; /* file name of disk/container */ +const char *rssize; /* and associated size */ +long rsize; /* explicitly supplied size (for real disks) */ +int absflag; /* doing absolute I/O to real disk if non-zero */ +FILE *rstsfile; /* rsts disk or container file */ + +int lastio; /* what type of I/O, if any, was last done */ +long nextblk; /* next block after end of last I/O */ + +const diskent sizetbl[] = { + { "rx50", 800, 800, FALSE }, + { "rf11", 1024, 1024, FALSE }, + { "rs03", 1024, 1024, FALSE }, + { "rs04", 2048, 2048, FALSE }, + { "rk05", 4800, 4800, FALSE }, + { "rl01", 10240, 10220, TRUE }, + { "rl02", 20480, 20460, TRUE }, + { "rk06", 27126, 27104, TRUE }, + { "rk07", 53790, 53768, TRUE }, + { "rp04", 171798, 171796, FALSE }, + { "rp05", 171798, 171796, FALSE }, + { "rp06", 340670, 340664, FALSE }, + { "rp07", 1008000, 1007950, TRUE }, + { "rm02", 131680, 131648, TRUE }, + { "rm03", 131680, 131648, TRUE }, + { "rm05", 500384, 500352, TRUE }, + { "rm80", 251328, 242575, TRUE }, + { NULL, 0, 0, 0 }}; + +/* getsize takes as input a container file size specifier, which is either + * a decimal string or a disk type name, and returns the corresponding + * size. In the case of disk names, it returns both the size as RSTS + * knows it, and the full hardware-defined size. In addition, it returns + * a flag indicating whether that type has a bad block table. + * In the case of a numeric size, it looks for a match in the table + * (against either RSTS size or "full" size) and returns what the + * table entry specifies. If no match is found, it returns the + * specified value for both and the dec166 flag is false. + * If the size specifier is invalid, the RSTS size is returned as zero + * and the other two return values are undefined. + */ + +void getsize (const char *name, long *tsize, long *rsize, int *dec166) +{ + const diskent *d; + char *n, *n2, *pp; + + if (isdigit (*name)) /* numeric size given */ + { + *rsize = strtoul (name, &pp, 10); /* scan size */ + if (*pp != '\0') *rsize = 0; + *tsize = *rsize; + *dec166 = FALSE; + for (d = sizetbl; d->name != NULL; d++) + if (d->rsize == *rsize || d->tsize == *rsize) + { + *tsize = d->tsize; + *rsize = d->rsize; + *dec166 = d->dec166; + break; + } + } + else + { + if ((n = (char *) malloc (strlen (name) + 1)) == NULL) rabort(NOMEM); + strcpy (n, name); + for (n2 = n; *n2; n2++) *n2 = tolower (*n2); + for (d = sizetbl; d->name != NULL; d++) + if (strcmp (d->name, n) == 0) break; + free (n); + *tsize = d->tsize; + *rsize = d->rsize; + *dec166 = d->dec166; + } +} + +/* adjsize takes as input a container file size. it returns the + * corresponding RSTS size, based on a match against a table of + * known disk sizes. if it finds a match, it returns the RSTS + * size given in the table; otherwise it returns the value that + * was passed. + */ + +long adjsize (long tsize) +{ + const diskent *d; + + for (d = sizetbl; d->name != NULL; d++) + if (d->tsize == tsize) + return d->rsize; + return tsize; +} + +void setrname () +{ + long t1; + int t2; + + if ((rname = sw.rstsdevice) == NULL) + if ((rname = defdevice) == NULL) + if ((rname = getenv ("RSTSDISK")) == NULL) + rname = DEFDEVICE; + if ((rssize = sw.disksize) == NULL) + if ((rssize = defsize) == NULL) + if ((rssize = getenv ("RSTSDISKSIZE")) == NULL) + rssize = NULL; + rsize = 0; + absflag = FALSE; + if (rssize != NULL) { + getsize (rssize, &t1, &rsize, &t2); /* scan size */ + if (rsize == 0) { + printf ("Invalid device size %s\n", rssize); + return; /* and quit */ + } + } + absname (rname); /* see if name is special */ + if (absflag && rsize == 0) { + printf ("Disk size must be specified explicitly for disk %s\n", + rname); + return; + } +} + +void ropen (const char *mode) +{ + long d; + struct stat sbuf; + + fiblk = -1; /* indicate no valid FIBUF */ + lastio = NOLAST; /* and no previous I/O */ + womsat = FALSE; /* SATT is clean */ + setrname (); + if (absflag) { /* open real disk */ + if (absopen (rname, mode)) { + printf ("Error opening RSTS device %s\n", rname); + perror (progname); /* report any details */ + rabort (NOMSG); + } + diskblocks = rsize; /* set block count */ + } else { /* not absolute disk */ + if ((rstsfile = fopen (rname, mode)) == NULL) { + printf ("Error opening RSTS device %s\n", rname); + perror (progname); /* report any details */ + rabort (NOMSG); + } + if (fstat (fileno(rstsfile), &sbuf)) { /* get info about disk/file */ + printf ("Can't stat RSTS device %s", rname); + perror (progname); + fclose (rstsfile); /* close it */ + rabort (NOMSG); + } + diskblocks = UP(sbuf.st_size,BLKSIZE) / BLKSIZE; + if (diskblocks == 0) { + if (!S_ISCHR(sbuf.st_mode) && + !S_ISBLK(sbuf.st_mode)) + { + printf ("Null RSTS container file %s\n", rname); + fclose (rstsfile); + rabort (NOMSG); + } + if (rsize == 0) { + printf ("Size not specified for RSTS disk %s\n", rname); + fclose (rstsfile); + rabort (NOMSG); + } + diskblocks = rsize; + } + } + diskblocks = adjsize (diskblocks); /* adjust for bad block tbl */ + d = (diskblocks - 1) >> 16; /* high order bits of last LBN */ + dcs = 1; /* compute DCS */ + while (d) { + d >>= 1; + dcs <<= 1; + } + if (dcs > 64) rabort(BADDCS); /* Sorry, disk too big! */ +} + +void rseek (long block) +{ + if (block >= diskblocks) rabort(BADBLK); + if (absflag) absseek (block); + else fseek (rstsfile, block * BLKSIZE, SEEK_SET); + if (sw.debug != NULL) + printf ("seek to: %ld\n", block); +} + +void rread (long block, long size, void *buffer) +{ + long iosize; + + if (lastio != LASTREAD || nextblk != block) { + rseek (block); + lastio = LASTREAD; + } + if (absflag) { + if (absread (block, size, buffer)) + iosize = 0; + else iosize = size; + } + else iosize = fread (buffer, 1, size, rstsfile); + if (sw.debug != NULL) + printf ("size requested: %ld, read: %ld\n", size, iosize); + if (iosize != size) rabort(DISKIO); + nextblk = block + size / BLKSIZE; +} + +void rwrite (long block, long size, void *buffer) +{ + long iosize; + + if (lastio != LASTWRITE || nextblk != block) { + rseek (block); + lastio = LASTWRITE; + } + if (absflag) { + if (abswrite (block, size, buffer)) + iosize = 0; + else iosize = size; + } + else iosize = fwrite (buffer, 1, size, rstsfile); + if (iosize != size) rabort(DISKIO); + nextblk = block + size / BLKSIZE; +} + +void rclose () +{ + if (absflag) absclose (); + else fclose (rstsfile); +} diff --git a/extracters/rstsflx/diskio.h b/extracters/rstsflx/diskio.h new file mode 100644 index 0000000..1e0d424 --- /dev/null +++ b/extracters/rstsflx/diskio.h @@ -0,0 +1,8 @@ +extern void getsize (const char *name, long *tsize, long *rsize, int *dec166); +extern long adjsize (long size); +extern void setrname(void); +extern void ropen(const char * mode); +extern void rseek(long block); +extern void rread(long block , long size , void * buffer); +extern void rwrite(long block , long size , void * buffer); +extern void rclose(void); diff --git a/extracters/rstsflx/djabsio.c b/extracters/rstsflx/djabsio.c new file mode 100644 index 0000000..18dc96b --- /dev/null +++ b/extracters/rstsflx/djabsio.c @@ -0,0 +1,304 @@ +/* absread and abswrite services for use with DJGPP GNU C implementation + * + * Paul Koning 94.10.16 + * 94.11.18 added bios i/o + * 94.11.21 dos i/o for hard disk, bios i/o for floppy + * 94.12.19 add retry for bios I/O + * 95.01.05 update for generalized abs i/o in flx + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "flx.h" +#include "absio.h" + +#define tb _go32_info_block.linear_address_of_transfer_buffer + +#define BIOSBUF (_go32_info_block.size_of_transfer_buffer) + /* size of djgpp bios disk I/O buffer */ +#define BIOSMAX (18 * BLKSIZE) /* max size in biosdisk() call */ +#define BIOSRESET 0 /* error reset */ +#define BIOSREAD 2 /* bios disk read function code */ +#define BIOSWRITE 3 /* bios disk write function code */ +#define BIOSTRIES 4 /* retry count */ +#define ABSREAD 0x25 /* abs read int code */ +#define ABSWRITE 0x26 /* abs write int code */ +#define BIOS_DATA_SEG 0x0040 /* BIOS data segment number */ +#define BIOS_DSK_STATE 0x0090 /* offset to drive 0 media state */ +#define DISK_STATE(d) ((BIOS_DATA_SEG << 4) + BIOS_DSK_STATE + ((d) - 1)) + +#define BIOS_DSK_360K 0x74 /* 360kb media established */ +#define BIOS_DSK_RX50 0x54 /* RX50 media established in drive */ + /* (same as 360kb except single steps */ + /* for 96 tpi media) */ + +static int secsize = 0; +static int param_segment = 0; +static unsigned short int dosparam[5]; +static int rxflag = 0; /* set if accessing 5.25 inch floppy */ +static int gdrive = -1; /* drive to which geometry data applies */ +static int drive; /* disk unit number currently open */ +static int sectors, heads, cylinders, drives; +static _go32_dpmi_seginfo param_info; + +/* The param_buffer is used to hold the dos abs disk I/O parameter block + */ + +static void free_param_buffer() +{ + _go32_dpmi_free_dos_memory(¶m_info); + param_segment = 0; +} + +static void alloc_param_buffer() +{ + if (param_segment) return; + param_info.size = UP(sizeof(param_info),16) / 16; + if (_go32_dpmi_allocate_dos_memory(¶m_info)) { + param_segment = 0; + return; + } + param_segment = param_info.rm_segment; + atexit(free_param_buffer); +} + +/* convert dos style drive number to bios style number */ + +static int biosdrive (int drive) +{ + if (drive < 3) return (drive - 1); + else return ((drive - 3) + 0x80); /* need to do partitions */ +} + +/* do bios I/O with retries */ + +static int biosdiskr (int func, int drive, int track, int cyl, + int sec, int count, void *buffer, int dparam) +{ + int tries, status; + + for (tries = 0; tries < BIOSTRIES; tries++) { + if (dparam) dosmemput (&dparam, 1, DISK_STATE(drive)); + status = biosdisk (func, biosdrive (drive), track, cyl, + sec, count, buffer); + if (status == 0) break; + + /* strictly speaking one should do error classification + * at this point... + */ + biosdisk (BIOSRESET, biosdrive (drive), 0, 0, 0, 0, NULL); + } + return (status); +} + +static void getgeom (int drive) +{ + _go32_dpmi_registers r; + + gdrive = drive; + memset(&r, 0, sizeof(r)); + r.h.ah = 8; + r.h.dl = biosdrive (drive); + _go32_dpmi_simulate_int(0x13, &r); + heads = r.h.dh + 1; + drives = r.h.dl; + cylinders = r.h.ch + ((r.h.cl >> 6) << 8) + 1; + sectors = r.h.cl & 0x3f; + if (drive < 3 && (r.h.bl & 0x0f) == 2) /* floppy && drive = 1.2MB */ + rxflag = 1; + else rxflag = 0; +} + +/* Convert block number to cylinder, head, sector for RT11-RX50. + * This is different for RT11 than for Rainbow DOS: + * For DOS, for cylinders 2 through 79, the sectors are interleaved 2:1. + * (DOS capability is not supported in this RT11 version). + * For RT11, all sectors are interleaved 2:1, and each subsequent + * track has the first logical block offset by 2 more sectors. + */ + +static void makechs_rx50 (int block, int *trk, int *sec) +{ + int t, s; + + t = block / 10; + s = block % 10 + 1; + if (s < 6) s = (s - 1) * 2 + 1; + else s = (s - 5) * 2; + s += t * 2; + while (s > 10) s -= 10; + t++; + if (t == 80) t = 0; /* wrap around last 10 blocks */ + *trk = t; + *sec = s; +} + +/* do single block disk I/O to DEC RX50 floppy */ +static int rx50io (int func, int drive, int dsksec, void *buffer) +{ + byte oldstate; + int cyl, sec; + int status; + + alloc_param_buffer(); + + /* save old state and set up for RX50 I/O */ + dosmemget (DISK_STATE(drive), 1, &oldstate); + makechs_rx50 (dsksec, &cyl, &sec); + status = biosdiskr (func, drive, 0, cyl, sec, 1, buffer, BIOS_DSK_RX50); + + /* restore BIOS state as it was on entry */ + dosmemput (&oldstate, 1, DISK_STATE(drive)); + return (status); +} + +/* do bios disk I/O call + * if this is a 5.25" floppy, we do the required magic to read it as + * a DEC RX50 format floppy. + */ + +static long biosio (int func, int drive, long dsksec, long count, void *buffer) +{ + long track, sec, cyl; + long tcount, status; + + if (drive != gdrive) getgeom (drive); + while (count) { + if (rxflag) { + tcount = BLKSIZE; + status = rx50io (func, drive, dsksec, buffer); + } else { + tcount = count; + if (tcount > BIOSMAX) tcount = BIOSMAX; + sec = dsksec % sectors; + if ((sectors - sec) * BLKSIZE < tcount) + tcount = (sectors - sec) * BLKSIZE; + sec++; /* weird 1-based numbering */ + track = (dsksec / sectors) % heads; + cyl = dsksec / (sectors * heads); + status = biosdiskr (func, drive, track, cyl, + sec, tcount / BLKSIZE, buffer, 0); + } + if (status) return (status); + count -= tcount; + buffer += tcount; + dsksec += (tcount / BLKSIZE); + } + return (0); +} + +/* do absolute dos disk read/write + * arguments: + * function code (0x25 = read, 0x26 = write) + * drive number (1 = a:, etc) + * starting sector number + * byte count (must be multiple of sector size) + * buffer pointer + */ + +static long dosio (int func, int drive, int sec, long count, void *buffer) +{ + long tcount; + _go32_dpmi_registers r; + + while (count) { + tcount = count; + if (tcount > BIOSBUF) tcount = BIOSBUF; + alloc_param_buffer(); + dosparam[0] = sec & 0xffff; + dosparam[1] = sec >> 16; + dosparam[2] = (tcount / secsize) & 0xffff; + dosparam[3] = (unsigned int) tb & 15; + dosparam[4] = (unsigned int) tb >> 4; + dosmemput(dosparam, sizeof(dosparam), param_segment << 4); + if (func == ABSWRITE) + dosmemput(buffer, tcount, tb); + memset(&r, 0, sizeof(r)); + r.h.al = drive - 1; /* 0-based numbering here */ + r.x.ds = param_segment; + r.x.bx = 0; + r.x.cx = -1; + _go32_dpmi_simulate_int(func, &r); + if (func == ABSREAD) + dosmemget(tb, tcount, buffer); + if (r.x.flags & 1) + return (r.h.al); + count -= tcount; + buffer += tcount; + sec += (tcount / secsize); + } + return (0); +} + +/* return size of specified disk, in blocks. Saves sector size in a local + * static variable as a side effect. A flag is set if the disk is a + * 5.25 inch floppy. + * Note: this must be called before any abs I/O is done. + */ + +static int disksize (int drive) +{ + _go32_dpmi_registers r; + + if (drive >= 3) { /* hard disk */ + memset(&r, 0, sizeof(r)); + r.h.ah = 0x1c; + r.h.dl = drive; + _go32_dpmi_simulate_int(0x21, &r); + secsize = r.x.cx; + return (r.h.al * r.x.dx * secsize / BLKSIZE); + } else { + getgeom (drive); + secsize = 512; + return (cylinders * heads * sectors); + } +} + +/* this routine is called to scan a supplied container file/device + * name. If the name refers to a real disk, then absflag is set + * and rsize is set to the device size. Otherwise, no action is taken. + */ + +void absname (const char *rname) +{ + if (rname[strlen(rname) - 1] == ':') { /* device name alone */ + absflag = TRUE; + drive = tolower (rname[0]) - 'a' + 1; /* set drive number */ + rsize = disksize (drive); + if (sw.debug != NULL) + printf ("disk size for drive %d is %ld\n", drive, rsize); + } +} + +int absopen (const char *rname, const char *mode) +{ + return (0); /* always ok, nothing to do */ +} + +void absseek (long block) { } /* nothing to do */ + +void absclose () { } /* nothing to do */ + +long absread (long sec, long count, void *buffer) +{ + if (drive >= 3) /* hard disk */ + return (dosio (ABSREAD, drive, sec, count, buffer)); + else + return (biosio (BIOSREAD, drive, sec, count, buffer)); +} + +long abswrite (long sec, long count, void *buffer) +{ + if (drive >= 3) /* hard disk */ + return (dosio (ABSWRITE, drive, sec, count, buffer)); + else + return (biosio (BIOSWRITE, drive, sec, count, buffer)); +} + diff --git a/extracters/rstsflx/doalloc.c b/extracters/rstsflx/doalloc.c new file mode 100644 index 0000000..eabbe78 --- /dev/null +++ b/extracters/rstsflx/doalloc.c @@ -0,0 +1,58 @@ +/* handler for the "allocation" command */ + +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "doalloc.h" +#include "fip.h" + +void doalloc (int argc, char **argv) /* show allocated clusters */ +{ + byte *s; + int bit, szb; + long first, used, unused, biggest, size; + long n; + + rmount (); /* mount the disk R/O */ + findsat (); /* look up satt.sys */ + s = sattbufp; + szb = (diskblocks - dcs) / pcs; /* satt bits actually used */ + bit = 1; + n = 0; /* start looking at PCN = 0 */ + used = unused = biggest = 0; /* nothing used, nor unused */ + if (sw.bswitch == NULL) printf ("\nFree pack cluster number ranges:\n"); + for (;;) { + for ( ; n < szb; n++) { + if (bit > 0x80) { + bit = 1; + s++; + } + if ((*s & bit) == 0) break; + used++; /* count allocated clusters */ + bit <<= 1; + } + if (n == szb) break; + first = n; + for ( ; n < szb; n++) { + if (bit > 0x80) { + bit = 1; + s++; + } + if (*s & bit) break; + unused++; /* count free clusters */ + bit <<= 1; + } + size = (n - first) * pcs; + if (size > biggest) biggest = size; + if (sw.bswitch == NULL) { + printf ("%6ld - %-6ld (%ld blocks)\n", first, n - 1, size); + } + } + printf ("Blocks used: %ld, free: %ld, max contiguous free: %ld\n", + used * pcs, unused * pcs, biggest); + free (sattbufp); /* release the satt memory copy */ + rumount (); /* done with the disk */ +} + diff --git a/extracters/rstsflx/doalloc.h b/extracters/rstsflx/doalloc.h new file mode 100644 index 0000000..de3eb64 --- /dev/null +++ b/extracters/rstsflx/doalloc.h @@ -0,0 +1 @@ +extern void doalloc(int argc , char ** argv); diff --git a/extracters/rstsflx/doclean.c b/extracters/rstsflx/doclean.c new file mode 100644 index 0000000..8f57916 --- /dev/null +++ b/extracters/rstsflx/doclean.c @@ -0,0 +1,1794 @@ +/* handler for the "clean" (or "rebuild") command */ + +/* this code is inspired by the INICLN module of RSTS INIT, with some + * significant changes: + * 1. support for "read-only" clean, i.e., look, do not touch. + * 2. directories are read in entirely and manipulated in memory. + * this speeds things up a lot and eliminates the need for the + * disk cache that ONLCLN maintains. + * 3. blockette use status is kept in a separate bitmap rather than + * in the link words on disk. this avoids two write passes and + * allows a totally read-only clean to be done. + * 4. if a double allocation is found, the offending file is truncated + * (if it's a directory, it is zeroed). you don't get the option + * to delete the file it conflicts with. that saves a *lot* of code. + */ +#include +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "diskio.h" +#include "filename.h" +#include "doclean.h" +#include "fip.h" +#include "rtime.h" + +#define dirbufsize (7 * 16 * BLKSIZE) +#define dirmapsize (7 * 16 * BLKSIZE / sizeof (gfdne) / 8) +#define PPN11 0401 + +/* pointers to buffers used by clean. to speed things up, we use + * lots of memory and read whole file system structures into memory. + * specifically we use: + * sattbf2 - storage allocation table (same form as sattbuf) + * badbmap - map of bad blocks (same form as sattbuf) + * mfdbuf - the entire MFD + * mfdmap - bitmap of allocated MFD blockettes + * gfdbuf - the entire current GFD + * gfdmap - bitmap of allocated GFD blockettes + * ufdbuf - the entire current UFD + * ufdmap - bitmap of allocated UFD blockettes + * + * note: the blockette maps don't explicitly represent the label or + * fdcm spots, since those are in use by definition. however, the + * label position (LSB of first byte) is used as a "dirty buffer" + * marker for the corresponding directory buffer. + */ + +#define MARK(map) *(map) |= 1 + +typedef enum +{ + ok, badblock, dup, badlink, nullink, other, + range, align, delete +} retcode; + +byte *sattbf2 = NULL; +byte *badbmap = NULL; +byte *mfdbuf = NULL; +byte *mfdmap = NULL; +byte *gfdbuf = NULL; +byte *gfdmap = NULL; +byte *ufdbuf = NULL; +byte *ufdmap = NULL; + +byte curproj, curprog; +char curdir[10]; +char curfile[22]; +long filesize; +long e; +long gfds, ufds, files, clusters; +long dirfiles, dirtsize; +int badb, satt, init; /* flags for special files */ + +/* get a yes or no answer; return true if yes, false if no. + * loop until a valid answer is received. the default is "no". + * if -protect switch (read-only clean) was present, supply + * a "yes" answer automatically (note that this won't actually + * cause any changes, but it will allow the process to continue). + */ +static retcode yesno (void) +{ + char c; + char answer[LSIZE]; + int cmdlen; + + if (sw.prot != NULL) + { + printf ("Yes (read-only)\n"); + return other; + } + for (;;) + { + if (fgets (answer, LSIZE, stdin) == NULL) return FALSE; + cmdlen = strlen (answer); + if (answer[cmdlen - 1] == '\n') + answer[--cmdlen] = '\0'; + else + { + printf ("Reply too long\nYes or No? "); + continue; + } + c = toupper (answer[0]); + if (c == 'Y') return ok; + else if (c == 'N' || c == '\0') return other; + printf ("Invalid answer\nYes or No? "); + } +} + +/* similarly but a "no" answer aborts the clean */ +static void yes (void) +{ + printf ("\nProceed (Yes or No)? "); + if (yesno () == ok) return; + printf ("Clean aborted\n"); + rabort (NOMSG); +} + +/* this function reads an entire directory into the designated buffer. + * it assumes the supplied dcn is valid. it uses the first fdcm to + * find all the other clusters, but does not do full validation on + * the fdcm -- only enough to avoid making a mess of the reads. + * it's the caller's job to do more detailed checks. + * + * on the assumption that a directory often has a clustersize of 16, + * and in any case may be more or less contiguous, we start with a + * read of 16 blocks. + */ +static void readdir (word dcn, byte *buf) +{ + int i, clu; + long j, start, blks; + fdcm *m; + byte *p; + + if (sw.debug != NULL) + printf ("\nreaddir(%d,%p)", dcn, buf); + start = dcntolbn (dcn); + if ((diskblocks - start) < 16) + blks = diskblocks - start; + else blks = 16; + if (blks < 1) rabort (INTERNAL); + rread (start, BLKSIZE * blks, buf); + m = (fdcm *) (buf + 0760); + clu = m->uclus; + if (dcn != m->uent[0] || /* some simple sanity checks... */ + clu > blks || + (pcs <= 16 && clu < pcs) || + (clu & (-clu)) != clu) + return; + p = buf + (BLKSIZE * clu); /* point to second cluster's data */ + i = 1; /* and next r.e. index to use */ + if (clu != blks) /* read more than a cluster? */ + { + j = clu / dcs; /* dcn increment if contiguous */ + for (;;) + { + if (i == 7 || i * clu >= blks) return; + if (m->uent[i] == 0) return; + if (m->uent[i] != m->uent[i - 1] + j) break; + if (sw.debug != NULL) + printf (" entry %d, dcn %d is contiguous", + i, m->uent[i]); + i++; + p += BLKSIZE * clu; + } + } + for ( ; i < 7; i++) + { + if (m->uent[i] == 0) return; /* done */ + j = dcntolbn (m->uent[i]); + if (sw.debug != NULL) + printf (" read entry %d, dcn %ld, %d blocks", + i, j, clu); + if (j >= diskblocks) return; /* out of range, quit */ + rread (j, BLKSIZE * clu, p); + p += BLKSIZE * clu; + } +} + +/* this function writes back a directory. no validation is done, since + * that was all done before. + */ +static void writedir (byte *buf) +{ + int i, clu; + long j; + fdcm *m; + byte *p; + + if (sw.prot != NULL) return; /* read-only, don't write */ + m = (fdcm *) (buf + 0760); + clu = m->uclus; + for (i = 0 ; i < 7; i++) + { + if (m->uent[i] == 0) return; /* done */ + j = dcntolbn (m->uent[i]); + rwrite (j, BLKSIZE * clu, buf); + buf += BLKSIZE * clu; + } +} + +/* this function is like the standard function ulk (in fip.c) except + * that it operates on a previously read directory in its buffer. + * i and k are set as usual; in addition, e (for "entry") is set to + * be a byte offset to the entry. + */ + +retcode ulk2 (word link, byte *buf) +{ + int clu, blk; + fdcm *m; + + if (NULLINK (link)) return nullink; + m = (fdcm *) (buf + 0760); + k = (link & ul_eno); /* k = byte offset to entry */ + clu = (link & ul_clo) >> sl_clo; /* cluster number */ + blk = (link & ul_blo) >> sl_blo; /* block in cluster */ + if (sw.debug != NULL) + printf ("\nulk2(%o), k=%lo, clu=%d, blk=%d, clumap=%d", + link, k, clu, blk, m->uent[clu]); + if (blk >= m->uclus || + clu > 6 || + k == 0760 || + m->uent[clu] == 0) + return badlink; + i = blk + dcntolbn(m->uent[clu]); /* LBN of entry */ + e = k + (clu * m->uclus + blk) * BLKSIZE; + return ok; /* ok */ +} + +/* function to read an entry into fibuf given a link, with validity + * checking but no abort for bad links. + */ +retcode readlkchk (word link) +{ + if (NULLINK(link)) return nullink; /* indicate null link */ + if (ulk (link)) return badlink; /* unpack and check link */ + fbread (i); /* read the directory block */ + return ok; +} + +/* function to mark a directory entry as allocated. it takes a pointer + * to the entry map to update. the entry marked is the one most recently + * referenced in a call to ulk2. + */ +static retcode allocent (byte *map) +{ + int ent, bpos, m; + + if (e == 0 || k == 0760) rabort (INTERNAL); + ent = e / sizeof (gfdne); /* entry number */ + bpos = ent / 8; /* byte offset */ + m = 1 << (ent % 8); /* mask to touch */ + if (map[bpos] & m) return dup; /* error if already marked */ + map[bpos] |= m; + return ok; +} + +/* similarly, mark entry as deallocated */ +static void deallocent (byte *map) +{ + int ent, bpos, m; + + if (e == 0 || k == 0760) rabort (INTERNAL); + ent = e / sizeof (gfdne); /* entry number */ + bpos = ent / 8; /* byte offset */ + m = 1 << (ent % 8); /* mask to touch */ + if (((map[bpos] & m) == 0)) + rabort (INTERNAL); /* error if not marked */ + map[bpos] &= ~m; +} + +/* mark a chain of directory blockettes as allocated (but do no + * other processing on them). this is used for attribute chains + * and the like. the "use" argument is non-zero to force the link + * word of each entry to have the ul_use bit set. + * it returns 0 if all is ok, or the last good link (i.e., the link for + * the entry that contains the problem link) if there is a problem. + * a suitable message is printed to indicate the problem. if the + * first link is bad, the return value is 1. this allows the caller + * to truncate the chain. entries up to the problem spot are still + * marked as allocated. + */ +static word allocchain (word link, byte *buf, byte * map, int use) +{ + word prev = 1; + retcode st; + + for (;;) + { + st = ulk2 (link, buf); + if (st == nullink) return 0; /* end of chain, success */ + if (st == badlink) + { + printf ("invalid link "); + break; + } + /* ok, so the link is good. does it point to a real entry? */ + if (*(lword32 *) (buf + e) == 0) + { + printf ("entry is a hole "); + break; + } + st = allocent (map); + if (st != ok) + { + printf ("doubly allocated entry "); + break; + } + prev = link; + link = *(word16 *) (buf + e); /* follow link to next */ + if (use && (link & ul_use) == 0) + { + if (sw.debug != NULL) + printf ("\nfixed link word for entry at offset %06lo\n", + e); + *(word16 *) (buf + e) |= ul_use; + MARK (map); + } + } + return prev; /* we had a problem */ +} + +/* similarly, mark a chain as free. */ +static void deallocchain (word link, byte *buf, byte * map) +{ + retcode st; + + for (;;) + { + st = ulk2 (link, buf); + if (st == nullink) return; /* end of chain, done */ + if (st == badlink) rabort (INTERNAL); + deallocent (map); + link = *(word16 *) (buf + e); /* follow link to next */ + } +} + +/* function to mark a cluster as allocated. this operates on sattbf2 + * (not sattbuf) -- it looks a lot like retclu except for the sense of + * the change... + */ + +static retcode alloc (word pos, int clusiz) +{ + long m, n; + byte *s; + int bpos; + retcode ret = ok; + + if (sw.debug != NULL) + printf ("\nalloc(%d,%d)", pos, clusiz); + if (clusiz < dcs && dcs > 16) + clusiz = dcs; /* deal with directories on large disks */ + if ((pos - 1) % (clusiz / dcs)) + return align; + pos = dcntopcn(pos); /* convert to pcn */ + if (pos >= pcns) + return range; + clusiz /= pcs; /* fcs as count of clusters */ + if (clusiz <= 0) + rabort (INTERNAL); + bpos = pos / 8; /* byte offset to start of cluster */ + if (clusiz < 8) /* scanning bitwise */ + { + m = (1 << clusiz) - 1; /* mask to match on */ + m <<= (pos % 8); /* form starting bit field */ + if (badbmap[bpos] & m) + ret = badblock; /* bad block, remember it */ + if (sattbf2[bpos] & m) + return dup; /* double allocation */ + sattbf2[bpos] |= m; /* ok, allocate it */ + clusters += clusiz; /* update stats */ + } + else /* scanning whole bytes */ + { + clusiz /= 8; /* change to count of bytes to alloc */ + for (n = 0; n < clusiz; n++) + if (badbmap[bpos + n]) + ret = badblock; /* bad block, remember it */ + for (n = 0; n < clusiz; n++) + if (sattbf2[bpos + n]) + return dup; /* double allocation */ + for (n = 0; n < clusiz; n++) + sattbf2[bpos + n] = 0xff; /* ok, allocate it */ + clusters += clusiz * 8; /* update stats */ + } + + return ret; +} + +/* sometimes we have to deallocate something -- to clean up from + * allocating something that then messes up halfway. + * this code is straight from fip.c retclu except for the use of + * a different buffer. + */ +static void dealloc (word pos, int clusiz) +{ + long m, n; + byte *s; + + if (sw.debug != NULL) + printf ("\ndealloc(%o,%d)", pos, clusiz); + if (sattsize == 0) + rabort (INTERNAL); + pos = dcntopcn(pos); /* convert to pcn */ + clusiz /= pcs; /* fcs as count of clusters */ + if (clusiz == 0 && pcs > 16) + clusiz = 1; /* handle directories on large disks */ + if (clusiz <= 0) + rabort (INTERNAL); + s = sattbf2 + pos / 8; /* byte pointer to start of cluster */ + if (clusiz < 8) /* scanning bitwise */ + { + m = (1 << clusiz) - 1; /* mask to match on */ + m <<= (pos % 8); /* form starting bit field */ + *s &= ~m; /* free this cluster */ + } + else /* scanning whole bytes */ + { + clusiz /= 8; /* change to count of bytes to free */ + for (n = 0; n < clusiz; n++) + *s++ = 0; + } +} + +/* common directory cleanup + * this function reads a directory into the indicated buffer, clears + * out the blockette map, and validates all the fdcm's. if it's happy, + * it returns ok or badblock; if an uncorrectable problem is found it + * generates a suitable message, deallocates the directory clusters, + * and returns the corresponding error code. + * + * if the clustersize argument is non-zero, it is checked against the + * fdcm. otherwise, the clustersize found in the first fdcm is used. + * (the latter applies to gfd/mfd, for which the clustersize is stored + * nowhere else.) + */ +static retcode cleandir (word dcn, int clu, + byte *buf, byte *map, + byte proj, byte prog) +{ + fdcm *m; + fdcm *first; + int i, j, ent, dirblks; + retcode st, ret = ok; + mfdlabel *l; + word16 id; + + /* figure out what we're cleaning */ + if (prog == 255) + { + if (proj == 255) + { + id = MFD; + strcpy (curdir, "[*,*]"); + } + else + { + id = GFD; + sprintf (curdir, "[%d,*]", proj); + } + } + else + { + id = UFD; + sprintf (curdir, "[%d,%d]", proj, prog); + } + curproj = proj; + curprog = prog; + printf ("\rprocessing %s ", curdir); + fflush (stdout); + + if (dcntopcn (dcn) >= pcns) + { + printf ("\nstarting dcn %d for %s out of range\n", + dcn, curdir); + return range; + } + memset (map, 0, dirmapsize); + readdir (dcn, buf); + m = (fdcm *) (buf + 0760); + if (clu == 0) clu = m->uclus; + if (m->uclus != clu || + clu > 16 || + (clu < 4 && id != UFD) || + (pcs <= 16 && clu < pcs) || + (pcs > 16 && clu != 16) || + (clu & (-clu)) != clu) + { + printf ("\ninvalid clustersize %d for %s\n", clu, curdir); + return other; + } + if (m->uent[0] != dcn) + { + printf ("\nstarting dcn %d for %s doesn't match that in cluster map\n", + dcn, curdir); + return other; + } + + /* in old disk, [1,1] label is pack label, don't touch + * otherwise do some checks and fixups. + */ + if (plevel != RDS0 || proj != 1 || prog != 1) + { + l = (mfdlabel *) buf; + if (l->lppn[1] != proj || l->lppn[0] != prog) + { + l->lppn[1] = proj; + l->lppn[0] = prog; + MARK (map); + if (sw.verbose != NULL) + printf ("\nfixed ppn in directory label for %s\n", + curdir); + } + if (l->lid != id) + { + l->lid = id; + MARK (map); + if (sw.verbose != NULL) + printf ("\nfixed identifier field in directory label for %s\n", + curdir); + } + if (l->fill2 != -1 || (l->fill1 & ul_use) == 0) + { + l->fill1 |= ul_use; + l->fill2 = -1; + MARK (map); + if (sw.debug != NULL) + printf ("\nfixed reserved field in directory label for %s\n", + curdir); + } + } + + /* go check the fdcm's in detail */ + if (id == UFD) i = 0; + else i = fd_new; + if (m->uflag != i) + { + m->uflag = i; + MARK (map); + if (sw.verbose != NULL) + printf ("\nfixed directory type flag bit in cluster map for %s\n", + curdir); + } + ent = 0; + /* look for holes in cluster map */ + for (i = 6; i >= 0; i--) + { + if (m->uent[i] == 0) + { + if (ent != 0) + { + printf ("\nholes in cluster map for %s\n", + curdir); + return other; + } + } + else if (dcntopcn (m->uent[i]) >= pcns) + { + printf ("\ncluster %d out of range in cluster map for %s\n", + m->uent[i], curdir); + return range; + } + else + ent = i; + } + if (ent == 0 && m->uent[0] == 0) + { + printf ("\ndirectory %s is empty\n", curdir); + return other; + } + dirblks = ent * clu; /* count of used directory blocks */ + first = m; /* save copy to first fdcm */ + ent = -1; /* no map mismatches yet */ + for (i = 1; i < dirblks; i++) + { + m = (fdcm *) (buf + (i * BLKSIZE) + 0760); + if (memcmp (first, m, sizeof (fdcm)) == 0) continue; + if (first->uclus != m->uclus) + { + printf ("\ninconsistent cluster sizes in maps for %s\n", + curdir); + return other; + } + if (first->uflag != m->uflag) + { + m->uflag = first->uflag; /* fix this quietly */ + MARK (map); + } + for (j = 0; j < 7; j++) + { + if (first->uent[j] == m->uent[j]) continue; + if (first->uent[j] == 0 && + (ent == j || ent == -1)) + { + ent = j; + continue; + } + printf ("\ninconsistent cluster maps for %s\n", curdir); + return other; + } + } + + /* things look cool, go mark the directory as allocated */ + for (i = 0; i < 7; i++) + { + if (first->uent[i] == 0) break; + st = alloc (first->uent[i], clu); + switch (st) + { + case ok: + continue; + case badblock: + printf ("\nbad block"); + ret = badblock; + break; + case dup: + printf ("\ndoubly allocated block"); + break; + case align: + printf ("\nmisaligned cluster"); + break; + case range: + printf ("\ncluster number out of range"); + break; + default: rabort (INTERNAL); + } + printf (", dcn %d in directory %s\n", first->uent[i], curdir); + if (st != badblock) /* bad blk is warning, others quit */ + { + while (i > 0) dealloc (first->uent[--i], clu); + return st; + } + } + return ret; +} + +/* finish up cleaning a directory + * this wipes out any unallocated blockettes. + */ +static void finishdir (byte *buf, byte *map) +{ + lword32 *l; + lword32 or; + int clu, blk, off; + fdcm *m; + byte *p; + byte bit; + mfdlabel *lb; + int ufd; + + /* figure out what we're cleaning */ + lb = (mfdlabel *) buf; + if (lb->lppn[0] == 255) + { + ufd = 0; + if (lb->lppn[1] == 255) + strcpy (curdir, "[*,*]"); + else sprintf (curdir, "[%d,*]", lb->lppn[1]); + } + else + { + ufd = 1; + sprintf (curdir, "[%d,%d]", lb->lppn[1], lb->lppn[0]); + } + m = (fdcm *) (buf + 0760); + l = (lword32 *) buf; + p = map; + bit = 1; + for (clu = 0; clu < 7; clu++) + { + if (m->uent[clu] == 0) break; + for (blk = 0; blk < m->uclus; blk++) + for (off = 0; off < BLKSIZE; off += sizeof (gfdne)) + { + /* check if it's a special spot */ + if (off == 0760 || + (!ufd && (clu == 0 && + (blk == 1 || blk == 2))) || + (off == 0 && clu == 0 && blk == 0)) + { + l += 4; + } + else if ((*p & bit) != 0) /* in use */ + { + if (*(byte *) l & ul_cln) + { + *(byte *) l &= ~ul_cln; + MARK (map); + if (sw.debug != NULL) + printf ("\ncleared ul.cln bit in %s at %d, %d, %d\n", + curdir, clu, blk, off); + } + l += 4; + } + else + { + or = l[0] | l[1] | l[2] | l[3]; + if (or) + { + *l++ = 0; + *l++ = 0; + *l++ = 0; + *l++ = 0; + if (sw.debug != NULL) + printf ("\ncleaned up free entry in %s at %d, %d, %d\n", + curdir, clu, blk, off); + MARK (map); + } + else + { + l += 4; + } + } + if (bit == 0x80) + { + p++; + bit = 1; + } + else bit <<= 1; + continue; + } + } + /* if directory needs writing, write it */ + if (*map & 1) + { + printf ("\rwriting %s ", curdir); + fflush (stdout); + writedir (buf); + } +} + +/* deallocate a directory (used when we zero it) */ +static void deallocdir (byte *buf) +{ + int i; + fdcm *m; + + m = (fdcm *) (buf + 0760); + for (i = 0; i < 7; i++) + { + if (m->uent[i]) + dealloc (m->uent[i], m->uclus); + else break; + } +} + +/* process a file. + * + * returns "ok" if things worked, something else if not. an appropriate + * message is printed if necessary. if the status code is "delete", the + * caller should just delete the file; otherwise, ask first. + * + * note: UFD entries in [1,1] for old disks don't come here. also: the + * caller has to validate the n.e. link and allocate the n.e. + */ +static retcode cleanfile (ufdne *n, byte *buf, byte *map) +{ + retcode st, ret = ok; + ufdae *a; + ufdre *r; + ufdlabel *l; + int clu, i, clurat, sysfile; + int hole = 0, badflag = 0, contig = 1, prevdcn = 0; + word prev; + char name[11]; + long dfsize; /* file size currently in dir */ + + memset (name, 0, sizeof (name)); + init = satt = badb = 0; /* not one of the special files */ + filesize = 0; + r50filename (n->unam, name, 0); + sprintf (curfile, "%s%s", curdir, name); + if (curproj == 0 && curprog == 1) + { + badb = (strcmp (name, "badb.sys") == 0); + satt = (strcmp (name, "satt.sys") == 0); + init = (strcmp (name, "init.sys") == 0); + } + sysfile = badb || init || satt || (n->ustat & us_nok); + printf ("\rprocessing %s ", curfile); + if (n->ustat & us_del) /* marked for delete */ + { + if (sw.verbose != NULL) + printf ("\nfile %s is marked for delete\n", curfile); + return delete; + } + if (n->ustat & us_ufd) /* bogus ufd-like entry */ + { + printf ("\nentry for file %s looks like a ufd\n", curfile); + return other; + } + if (n->unam[2] == TMP) /* .rad50 "tmp" */ + { + if (sw.verbose != NULL) + printf ("\nfile %s deleted\n", curfile); + return delete; + } + st = ulk2 (n->uaa, buf); + if (st != ok) + { + printf ("\ninvalid account entry link for file %s\n", curfile); + return badlink; + } + a = (ufdae *) (buf + e); + clu = a->uclus; + if (clu > 256 || + clu < pcs || + (clu & (-clu)) != clu || + (clu != pcs && satt)) /* badb.sys we checked earlier */ + { + printf ("\nbad clustersize %d for file %s\n", clu, curfile); + return other; + } + clurat = clu / dcs; /* dcn delta if contiguous */ + st = allocent (map); + if (st != ok) + { + printf ("\naccount entry for file %s is doubly allocated\n", + curfile); + return st; + } + if ((a->ulnk & ul_use) == 0) + { + if (sw.debug != NULL) + printf ("\nfixed link from account entry of file %s\n", + curfile); + a->ulnk |= ul_use; + MARK (map); + } + prev = allocchain (a->ulnk, buf, map, ul_use); + if (prev != 0) + { + printf (" in attributes chain for file %s -- will be truncated", + curfile); + if (sysfile) rabort (BADPAK); + if (prev == 1) + a->ulnk = (a->ulnk & ~LINKBITS) | ul_use; + else + { + ulk2 (prev, buf); + *(word16 *) (buf + e) &= ~LINKBITS; + } + MARK (map); + } + prev = allocchain (n->uar, buf, map, 0); + if (prev != 0) + { + printf (" in retrieval entry chain for file %s\n", curfile); + if (sysfile) rabort (BADPAK); + printf ("file will be truncated"); + if (prev == 1) n->uar = 0; + else + { + ulk2 (prev, buf); + *(word16 *) (buf + e) = 0; + } + MARK (map); + } + /* we've allocated all the blockettes, now walk the r.e. chain + * again to allocate the clusters and accumulate the file size + */ + st = ulk2 (n->uar, buf); + while (st != nullink) + { + if (st != ok) rabort (INTERNAL); + r = (ufdre *) (buf + e); + if (prevdcn == 0) prevdcn = r->uent[0] - clurat; + for (i = 0; i < 7; i++) + { + if (r->uent[i] == 0) break; + if (contig) + { + contig = (prevdcn + clurat == r->uent[i]); + prevdcn = r->uent[i]; + } + if (badb || (n->ustat & us_out)) + st = ok; + else st = alloc (r->uent[i], clu); + switch (st) + { + case ok: + filesize += clu; + continue; + case badblock: + if (!badflag) + { + printf ("\nbad block in file %s, cluster %d (block %ld of the file)\n", + curfile, r->uent[i], + filesize + 1); + if (!sysfile) + { + printf ("do you want it truncated (if not, it will be flagged)? "); + if (yesno () == ok) break; + } + badflag = 1; + } + filesize += clu; + continue; + case dup: + printf ("\ndoubly allocated block"); + break; + case align: + printf ("\nmisaligned cluster"); + break; + case range: + printf ("\ncluster number out of range"); + break; + default: + rabort (INTERNAL); + } + printf (", dcn %d in file %s", r->uent[i], curfile); + if (sysfile) rabort (BADPAK); + printf (" -- file will be truncated\n"); + while (i < 7) r->uent[i++] = 0; + r->ulnk = 0; + break; + } + if (i < 7) /* if we stopped on eof */ + { + for ( ; i < 7; i++) + { + hole |= r->uent[i]; + r->uent[i] = 0; + } + hole |= (r->ulnk & LINKBITS); + if (hole != 0) + { + printf ("\nholes in retrieval entry for %s", + curfile); + if (sysfile) printf ("\n"); + else + { + printf (" fixed"); + r->ulnk = 0; + MARK (map); + } + } + } + st = ulk2 (r->ulnk, buf); + } + dfsize = a->usiz; /* pick up current size */ + if (a->urts[0] == 0) /* possible large file */ + dfsize += a->urts[1] << 16; + if (satt) /* satt.sys gets a few checks more */ + { + if (!contig) + { + printf ("\n[0,1]satt.sys is not contiguous\n"); + rabort (BADPAK); + } + if (filesize * BLKSIZE * 8 < pcns) + { + printf ("\n[0,1]satt.sys is too small\n"); + rabort (BADPAK); + } + } + if (!badb && ((n->ustat & us_out) == 0)) + { + if (filesize != ((dfsize + clu - 1) & (-clu))) + { + printf ("\nfile %s size %ld is incorrect (%ld) in ufd", + curfile, filesize, dfsize); + if (sysfile && !satt) printf ("\n"); + else + { + printf (" -- fixed"); + a->usiz = filesize; + if (filesize >> 16) + { + a->urts[0] = 0; + a->urts[1] = filesize >> 16; + } + else if (a->urts[0] == 0) a->urts[1] = 0; + MARK (map); + } + } + } + if (badflag) + { + if ((a->ulnk & ul_bad) == 0) + { + a->ulnk |= ul_bad; + MARK (map); + } + } + else if (a->ulnk & ul_bad) + { + a->ulnk &= ~ul_bad; + MARK (map); + } + if (!contig && (n->ustat & us_nox)) + { + printf ("\nfile %s is marked as contiguous but is not\n", + curfile); + n->ustat &= ~us_nox; + MARK (map); + } + if (n->ustat & (us_wrt | us_upd)) + { + if (sw.debug != NULL) + printf ("\ncleared write/update flags for file %s\n", + curfile); + n->ustat &= ~(us_wrt | us_upd); + MARK (map); + } + if ((filesize >> 16) != 0 && (n->uprot & up_run) != 0) + { + if (sw.debug != NULL) + printf ("\ncleared runnable bit for file %s\n", + curfile); + n->uprot &= ~up_run; + MARK (map); + } + if ((n->uaa & ~(LINKBITS | ul_che)) != 0 || + (n->uar & ~LINKBITS) != 0 || + (n->ulnk & ~(LINKBITS | ul_che)) != 0) + { + if (sw.debug != NULL) + printf ("\nfixed links in n.e. for file %s\n", + curfile); + n->uaa &= LINKBITS | ul_che; + n->uar &= LINKBITS; + n->ulnk &= LINKBITS | ul_che; + MARK (map); + } + return ok; +} + +/* process the content of a ufd. this is separate from cleanufd so + * we can call it for the MFD [1,1] of an RDS0 disk. + * the buf and map pointers point to where the data and blockette maps + * are, normally ufdbuf and ufdmap but mfdbuf and mfdmap for the + * special case. + */ +static void processufd (byte *buf, byte *map) +{ + word prev, link; + retcode st; + ufdlabel *l; + ufdne *n; + + l = (ufdlabel *) buf; + link = l->ulnk; + prev = 1; + for (;;) + { + st = ulk2 (link, buf); + if (st == nullink) break; /* all done */ + if (st == ok) + st = allocent (map); /* allocate n.e. */ + if (st != ok) /* link bad or duplicate */ + { + if (prev == 1) + { + printf ("\nbad link in label of %s", curdir); + printf (" -- UFD will be zeroed"); + yes (); /* ask for permission */ + l->ulnk = 0; + } + else + { + printf ("\nbad next file link in file %s" + " -- remaining files will be lost", + curfile); + yes (); /* ask for permission */ + ulk2 (prev, buf); + n = (ufdne *) (buf + e); + n->ulnk = 0; + } + MARK (map); + break; + } + n = (ufdne *) (buf + e); + st = cleanfile (n, buf, map); + if (st != ok) + { + if (st != delete) + { + if (satt || init || badb || + (n->ustat & us_nok)) + { + printf ("\nfile %s cannot be deleted\n", + curfile); + rabort (BADPAK); + } + yes (); /* ask for ok */ + } + link = n->ulnk; /* set next file */ + if (prev == 1) l->ulnk = link; + else + { + ulk2 (prev, buf); + n = (ufdne *) (buf + e); + n->ulnk = link; + } + } + else + { + files++; + dirfiles++; + dirtsize += filesize; + prev = link; + link = n->ulnk; + } + } +} + +/* go clean a ufd */ +static retcode cleanufd (word dcn, int proj, int prog) +{ + retcode st, ret = ok; + word prev; + + dirfiles = dirtsize = 0; + if (dcn == 0) return 0; /* nothing there... */ + st = cleandir (dcn, 0, ufdbuf, ufdmap, proj, prog); + if (st != ok) + { + if (st != badblock) return st; + if (proj == 0 && prog == 1) + { + printf ("\nclean will continue, but there may be problems\n"); + yes (); /* get approval */ + } + else + { + printf ("\ncontinue cleaning [%d,%d] anyway? ", + proj, prog); + if (yesno () != ok) + { + deallocdir (ufdbuf); + return other; + } + } + ret = st; + } + + /* go process the ufd contents */ + processufd (ufdbuf, ufdmap); + finishdir (ufdbuf, ufdmap); + ufds++; + return ret; /* success */ +} + +/* go clean a gfd */ +static int cleangfd (word dcn, retcode proj) +{ + int prog; + retcode st, ret = ok; + word prev; + word16 *dcnp, *unep; + gfdne *n; + gfdae *a; + uattr *at; + ua_quo *q; + + if (dcn == 0) return 0; /* nothing there... */ + st = cleandir (dcn, 0, gfdbuf, gfdmap, proj, 255); + if (st != ok) + { + if (st != badblock) return st; + if (proj == 0) + { + printf ("\nclean will continue, but there may be problems\n"); + yes (); /* get approval */ + } + else + { + printf ("\ncontinue cleaning [%d,*] anyway? ", proj); + if (yesno () != ok) + { + deallocdir (gfdbuf); + return other; + } + } + ret = st; + } + + /* check that there isn't an entry for user 255 */ + if (*(word16 *) (gfdbuf + 01776) != 0 || + *(word16 *) (gfdbuf + 02776) != 0) + { + printf ("\ninvalid user [%d,255] found in gfd -- deleted\n", + proj); + *(word16 *) (gfdbuf + 01776) = 0; + *(word16 *) (gfdbuf + 02776) = 0; + MARK (gfdmap); + } + + /* check that there isn't an entry for [0,0] either */ + if (proj == 0 && + (*(word16 *) (gfdbuf + 01000) != 0 || + *(word16 *) (gfdbuf + 02000) != 0)) + { + printf ("\ninvalid user [0,0] found in gfd [0,*] -- deleted\n"); + *(word16 *) (gfdbuf + 01000) = 0; + *(word16 *) (gfdbuf + 02000) = 0; + MARK (gfdmap); + } + + /* now process each user */ + for (prog = 0; prog < 255; prog++) + { + dcnp = (word16 *) (gfdbuf + 01000 + (2 * prog)); + unep = (word16 *) (gfdbuf + 02000 + (2 * prog)); + if (*unep & ~LINKBITS) + { + if (sw.debug != NULL) + printf ("\nname entry link for [%d,%d] fixed\n", + proj, prog); + *unep &= LINKBITS; + MARK (gfdmap); + } + st = ulk2 (*unep, gfdbuf); + if (st == nullink) /* no n.e. link */ + { + if (*dcnp != 0) + { + *dcnp = 0; + MARK (gfdmap); + printf ("\ndcn pointer for non-existent account [%d,%d zeroed\n", + proj, prog); + } + continue; + } + if (st) /* bad link! */ + { + printf ("\nname entry link for [%d,%d] is bad\n", + proj, prog); + if (proj == 0 && prog == 1) rabort (BADPAK); + printf ("account will be deleted\n"); + yes (); /* get approval */ + *unep = 0; + *dcnp = 0; + MARK (gfdmap); + continue; + } + n = (gfdne *) (gfdbuf + e); + if (n->ustat & us_del) /* account marked for delete */ + { + if (sw.verbose != NULL || + (proj == 0 & prog == 1)) + printf ("\naccount [%d,%d] marked for delete\n", + proj, prog); + if (proj == 0 && prog == 1) rabort (BADPAK); + *unep = 0; /* so delete it... */ + *dcnp = 0; + MARK (gfdmap); + continue; + } + if ((n->ustat & us_ufd) == 0) /* not marked as ufd! */ + { + printf ("\nname entry for [%d,%d] not marked as ufd\n", + proj, prog); + if (proj == 0 && prog == 1) rabort (BADPAK); + printf ("account will be deleted\n"); + yes (); /* get approval */ + *unep = 0; + *dcnp = 0; + MARK (gfdmap); + continue; + } + if (n->unam[0] != ((proj << 8) | prog)) + { + printf ("\nname entry for [%d,%d] has wrong ppn [%d,%d]\n", + proj, prog, + n->unam[0] >> 8, n->unam[0] & 0xff); + if (proj == 0 && prog == 1) rabort (BADPAK); + *unep = 0; /* so delete it... */ + *dcnp = 0; + MARK (gfdmap); + continue; + } + allocent (gfdmap); /* allocate name entry */ + st = ulk2 (n->uaa, gfdbuf); + if (st != ok) /* something wrong with a.e. */ + { + printf ("\naccount entry link for [%d,%d] is bad\n", + proj, prog); + if (proj == 0 && prog == 1) rabort (BADPAK); + printf ("account will be deleted\n"); + yes (); /* get approval */ + ulk2 (*unep, gfdbuf); /* mark n.e. free */ + deallocent (gfdmap); + *unep = 0; + *dcnp = 0; + MARK (gfdmap); + continue; + } + a = (gfdae *) (gfdbuf + e); + if (NULLINK (a->ulnk)) + { + if (a->ulnk != ul_use) + { + if (sw.debug != NULL) + printf ("\nlink from account entry for [%d,%d] fixed\n", + proj, prog); + a->ulnk = ul_use; + MARK (gfdmap); + } + } + else + { + printf ("\nlink from account entry for [%d,%d] cleared\n", + proj, prog); + a->ulnk = ul_use; + MARK (gfdmap); + } + allocent (gfdmap); /* allocate acct. entry */ + q = NULL; /* assume no quota block */ + if (plevel == RDS12 && (proj != 0 || prog != 1)) + { + st = ulk2 (n->ulnk, gfdbuf); /* get attributes */ + while (st == ok) + { + at = (uattr *) (gfdbuf + e); + if (at->uatyp == aa_quo) + { + q = (ua_quo *) at; + break; + } + st = ulk2 (at->ulnk, gfdbuf); + } + if (q == NULL) + { + printf ("\nquota block missing for [%d,%d]\n" + "account will be deleted\n", + proj, prog); + yes (); /* get approval */ + ulk2 (n->uaa, gfdbuf); /* mark a.e. free */ + deallocent (gfdmap); + ulk2 (*unep, gfdbuf); /* mark n.e. free */ + deallocent (gfdmap); + *unep = 0; + *dcnp = 0; + MARK (gfdmap); + continue; + } + } + prev = allocchain (n->ulnk, gfdbuf, gfdmap, 0); + if (prev) + { + /* note that the problem is after the quota block, + * for cases where we need one. that's because + * the quota block scan is before this point. + */ + printf (" in account [%d,%d] attribute chain -- will be truncated\n", + proj, prog); + yes (); /* get approval */ + if (prev == 1) n->ulnk = 0; + else + { + ulk2 (prev, gfdbuf); + *(word16 *) (gfdbuf + e) = ul_use; + } + MARK (gfdmap); + } + if (*dcnp != n->uar) /* inicln doesn't do this... */ + { + n->uar = *dcnp; + MARK (gfdmap); + if (sw.verbose != NULL) + printf ("\nfixed account [%d,%d] dcn in n.e.\n", + proj, prog); + } + st = cleanufd (*dcnp, proj, prog); + if (st == badblock) /* bad block but it worked */ + { + a->ulnk |= ul_bad; /* mark bad block in account */ + MARK (gfdmap); + } + else if (st != ok) + { + if (proj == 0 && prog == 1) rabort (BADPAK); + printf ("\naccount [%d,%d] will be zeroed\n", + proj, prog); + yes (); /* get approval */ + *dcnp = 0; + MARK (gfdmap); + } + if ((st == ok || st == badblock) && q != NULL) + { + if (((q->aq_crm << 16) | q->aq_crl) != dirtsize) + { + if (sw.debug != NULL) + printf ("\naccount [%d,%d] usage fixed, was %d now %ld\n", + proj, prog, + ((q->aq_crm << 16) | q->aq_crl), + dirtsize); + q->aq_crm = dirtsize >> 16; + q->aq_crl = dirtsize & 0xffff; + MARK (gfdmap); + } + } + if (sw.verbose != NULL) + printf ("\ntotal of %ld files, %ld blocks in [%d,%d]\n", + dirfiles, dirtsize, proj, prog); + } + finishdir (gfdbuf, gfdmap); + gfds++; + return ret; /* success */ +} + +/* go clean the mfd for a new format (RDS1.1 or above) disk */ +static void cleannewmfd (void) +{ + int proj; + retcode st; + word prev; + mfdlabel *l; + word16 *dcnp, *attrp; + + st = cleandir (mfddcn, 0, mfdbuf, mfdmap, 255, 255); + if (st != ok) + { + if (st != badblock) rabort (BADPAK); + printf ("\nclean will continue, but there may be problems\n"); + yes (); /* get approval */ + } + l = (mfdlabel *) mfdbuf; + + /* allocate any mfd attributes */ + prev = allocchain (l->malnk, mfdbuf, mfdmap, 0); + if (prev) + { + printf (" in mfd attribute chain -- will be truncated\n"); + yes (); /* get approval */ + if (prev == 1) l->malnk = 0; + else + { + ulk2 (prev, mfdbuf); + *(word16 *) (mfdbuf + e) = ul_use; + } + MARK (mfdmap); + } + + /* check that there isn't an entry for group 255 */ + if (*(word16 *) (mfdbuf + 01776) != 0 || + *(word16 *) (mfdbuf + 02776) != 0) + { + printf ("\ninvalid group [255,*] found in mfd -- deleted\n"); + *(word16 *) (mfdbuf + 01776) = 0; + *(word16 *) (mfdbuf + 02776) = 0; + MARK (mfdmap); + } + + /* now process each group */ + for (proj = 0; proj < 255; proj++) + { + dcnp = (word16 *) (mfdbuf + 01000 + (2 * proj)); + attrp = (word16 *) (mfdbuf + 02000 + (2 * proj)); + if (*attrp & ~LINKBITS) + { + if (sw.debug != NULL) + printf ("\nattribute link for group %d fixed\n", + proj); + *attrp &= LINKBITS; + MARK (mfdmap); + } + prev = allocchain (*attrp, mfdbuf, mfdmap, 0); + if (prev) + { + yes (); /* get approval */ + printf (" in group [%d,*] attribute chain -- will be truncated\n", + proj); + if (prev == 1) *attrp = 0; + else + { + ulk2 (prev, mfdbuf); + *(word16 *) (mfdbuf + e) = ul_use; + } + MARK (mfdmap); + } + st = cleangfd (*dcnp, proj); + if (st != ok && st != badblock) + { + if (proj == 0) rabort (BADPAK); + printf ("\ngfd [%d,*] will be zeroed\n", proj); + yes (); /* get approval */ + *dcnp = 0; + MARK (mfdmap); + } + } + finishdir (mfdbuf, mfdmap); +} + +/* go clean the mfd for an old format (RDS0) disk */ +static void cleanoldmfd (void) +{ + retcode ret; + + ret = cleandir (mfddcn, 0, mfdbuf, mfdmap, 1, 1); + if (sw.debug != NULL) + printf ("\ncleandir returned %d\n", ret); + finishdir (mfdbuf, mfdmap); +} + +/* set up the bitmap of bad clusters + * note that these are not marked (for the moment) in sattbf2 so they + * don't appear as double allocations if a file contains a bad block. + * instead, we check for the bad block map separately. + */ +static void allocbadb (void) +{ + firqb f; + ufdre *r; + ufdae *a; + int i, clurat, fsize = 0; + retcode st; + word link, dcn; + word16 *prevlink; + + memset (badbmap, 0, sattsize); /* initially no bad blocks */ + if (!findfile (&f, "[0,1]badb.sys")) + { + printf ("\n[0,1]badb.sys is missing!\n"); + rabort (BADPAK); + } + if (f.clusiz != pcs) + { + printf ("\n[0,1]badb.sys clustersize is invalid (%d should be %d)", + f.clusiz, pcs); + rabort (BADPAK); + } + clurat = pcs / dcs; + link = f.rlink; + readlk (f.nlink); + prevlink = &(use (ufdne, k)->uar); /* in case link is bad */ + for (;;) + { + st = readlkchk (link); + if (st == nullink) break; /* null link */ + else if (st != ok) + { + printf ("\nbad link in [0,1]badb.sys -- truncated\n"); + if (sw.prot == NULL) + { + *prevlink = 0; + fbwrite (); + } + break; + } + r = use (ufdre, k); + for (i = 0; i < 7; i++) + { + dcn = r->uent[i]; + if (dcn == 0) break; + fsize += pcs; /* accumulate badb.sys size */ + if (dcn % clurat) /* check for PCS boundary */ + { + printf ("\nwarning, [0,1]badb.sys dcn %d not on PCS boundary\n", dcn); + dcn = dcn / clurat * clurat; + } + st = alloc (dcn, pcs); + if (st == 3) + { + printf ("\nwarning, [0,1]badb.sys dcn %d is too large\n", dcn); + } + else if (st) + { + printf ("\nwarning, [0,1]badb.sys dcn %d doubly allocated\n", dcn); + } + } + prevlink = &(r->ulnk); + link = r->ulnk; + } + readlk (f.alink); + a = use (ufdae, k); + if (a->usiz != fsize) + { + if (sw.prot == NULL) + { + a->usiz = fsize; + fbwrite (); + if (sw.verbose != NULL) + printf ("\n[0,1]badb.sys filesize fixed\n"); + } + else printf ("\nnote: [0,1]badb.sys filesize doesn't match r.e. chain\n"); + } + memcpy (badbmap, sattbf2, sattsize); /* load the bad block map */ + memset (sattbf2, 0xff, sattsize); /* and make all free again */ + memset (sattbf2, 0, pcns / 8); + if (pcns & 7) sattbf2[pcns / 8] = 0xff << (pcns & 7); + if (sw.verbose != NULL) + printf ("total of %d bad blocks\n", fsize); +} + +/* validate the pack label, fix up any inconsistencies, and mark the + * pack as mounted in case we get a failure in mid-operation. + */ +static void cleanlabel (void) +{ + packlabel *p; + + readdcn (1); /* get pack label */ + p = use(packlabel,0); + if (p->fill1 != -1) + { + if (sw.debug != NULL) + printf ("pack label reserved field fixed\n"); + p->fill1 = -1; + } + if (pflags & uc_new) /* "new" flag set */ + { + if (alloc (1, pcs)) /* mark pack label allocated */ + rabort (INTERNAL); + if (plevel < RDS11) + { + p->plvl = plevel = RDS11; + if (sw.verbose != NULL) + printf ("pack rev level field fixed\n"); + } + else if (plevel > RDS12) + { + printf ("unsupported structure level %d.%d\n", + plevel >> 8, plevel & 0xff); + rabort (NOMSG); + } + } + else /* old pack */ + { + if (p->plvl) + { + p->plvl = 0; + if (sw.verbose != NULL) + printf ("pack label rev level field cleared\n"); + } + if (p->mdcn) + { + p->mdcn = 0; + if (sw.verbose != NULL) + printf ("pack label mfd cluster field cleared\n"); + } + } + /* while we're here, mark the pack as mounted in case of trouble + * (and, for that matter, so the rumountrw() call will work) + */ + if (sw.prot == NULL) + { + p->pstat |= uc_mnt; + fbwrite (); + } + else fiblk = -1; /* readonly clean, invalidate buffer */ +} + +/* switches recognized: + * -Debug lots of debug info + * -verbose print more info about what's happening + * -protect don't write anything, just inspect the disk + */ +void doclean (int argc, char **argv) +{ + int i, flag; + byte *o, *n; + byte m; + + if (sw.prot == NULL) + ropen (DWRITEMODE); /* open it first */ + else ropen (DREADMODE); + readlabel (); /* read and remember label data */ + if (pcs < dcs || pcs > 64 || (pcs > 16 && plevel < RDS12) || + (pcs & -pcs) != pcs) + { + printf ("invalid pack cluster size %d\n", pcs); + rabort (BADPAK); + } + if (sw.verbose != NULL) + { + if (pflags & uc_mnt) printf ("disk needs rebuilding.\n"); + else printf ("disk not marked as needing rebuilding.\n"); + } + if ((pflags & uc_ro) && + sw.overwrite == NULL && + sw.prot == NULL) + rabort (ROPACK); + sattsize = 0; /* SATT not looked up yet */ + womsat = FALSE; /* and SATT is clean */ + fiblkw = FALSE; /* FIBUF ditto */ + findsat (); /* make sure we know where satt is */ + + /* allocate some buffers we need */ + if (sattbf2 != NULL) free (sattbf2); + if ((sattbf2 = (byte *) malloc (sattsize)) == NULL) rabort (NOMEM); + if (badbmap != NULL) free (badbmap); + if ((badbmap = (byte *) malloc (sattsize)) == NULL) rabort (NOMEM); + if (mfdbuf != NULL) free (mfdbuf); + if ((mfdbuf = (byte *) malloc (dirbufsize)) == NULL) rabort (NOMEM); + if (mfdmap != NULL) free (mfdmap); + if ((mfdmap = (byte *) malloc (dirmapsize)) == NULL) rabort (NOMEM); + if (gfdbuf != NULL) free (gfdbuf); + if ((gfdbuf = (byte *) malloc (dirbufsize)) == NULL) rabort (NOMEM); + if (gfdmap != NULL) free (gfdmap); + if ((gfdmap = (byte *) malloc (dirmapsize)) == NULL) rabort (NOMEM); + if (ufdbuf != NULL) free (ufdbuf); + if ((ufdbuf = (byte *) malloc (dirbufsize)) == NULL) rabort (NOMEM); + if (ufdmap != NULL) free (ufdmap); + if ((ufdmap = (byte *) malloc (dirmapsize)) == NULL) rabort (NOMEM); + + /* init stats */ + gfds = ufds = files = clusters = 0; + + /* start out with nothing allocated */ + memset (sattbf2, 0xff, sattsize); + memset (sattbf2, 0, pcns / 8); + if (pcns & 7) sattbf2[pcns / 8] = 0xff << (pcns & 7); + + /* set up the bad block map */ + allocbadb (); + if (badbmap[0] & 1) + { + printf ("pack cluster 1 (pack label) is marked as bad\n"); + rabort (BADPAK); + } + + /* process the pack label */ + cleanlabel (); + + /* now do the rest of the file structure */ + if (plevel) cleannewmfd (); + else cleanoldmfd (); + + /* merge bad block map into satt */ + for (i = 0; i < sattsize; i++) sattbf2[i] |= badbmap[i]; + + /* all done. see if anything changed */ + if (memcmp (sattbufp, sattbf2, sattsize) != 0) + { + if (sw.verbose != NULL) + { + flag = 0; + m = 1; + o = sattbufp; + n = sattbf2; + for (i = 0; i < pcns; i++) + { + if ((*n & m) != 0 && (*o & m) == 0) + { + if (!flag) printf ("was free, now allocated: "); + flag = 1; + printf ("%d ", i); + } + if (m == 0x80) + { + m = 1; + o++; + n++; + } + else m <<= 1; + } + if (flag) printf ("\n"); + flag = 0; + m = 1; + o = sattbufp; + n = sattbf2; + for (i = 0; i < pcns; i++) + { + if ((*n & m) == 0 && (*o & m) != 0) + { + if (!flag) printf ("was allocated, now free: "); + flag = 1; + printf ("%d ", i); + } + if (m == 0x80) + { + m = 1; + o++; + n++; + } + else m <<= 1; + } + if (flag) printf ("\n"); + } + if (sw.prot == NULL) + { + memcpy (sattbufp, sattbf2, sattsize); + MARKS; /* indicate SATT needs writing */ + } + } + if (sw.verbose != NULL) + printf ("\n%ld gfds, %ld ufds, %ld files, %ld clusters processed\n", + gfds, ufds, files, clusters); + else + printf ("\n"); + + if (sw.prot == NULL) + rumountrw (); /* write satt, mark clean, and close */ + else rumount (); +} + diff --git a/extracters/rstsflx/doclean.h b/extracters/rstsflx/doclean.h new file mode 100644 index 0000000..d700748 --- /dev/null +++ b/extracters/rstsflx/doclean.h @@ -0,0 +1 @@ +extern void doclean (int argc , char ** argv); diff --git a/extracters/rstsflx/docomp.c b/extracters/rstsflx/docomp.c new file mode 100644 index 0000000..362c4f5 --- /dev/null +++ b/extracters/rstsflx/docomp.c @@ -0,0 +1,62 @@ +/* handler for the "compress" command */ + +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "docomp.h" +#include "diskio.h" +#include "fip.h" + +void docomp (int argc, char **argv) /* zero unused clusters */ +{ + byte *s; + int bit, szb; + long first, size, iosize; + long n; + + rmountrw (); /* mount the disk R/W */ + memset (iobuf, 0, iobufsize); /* clear out I/O buffer */ + s = sattbufp; + szb = (diskblocks - dcs) / pcs; /* satt bits actually used */ + bit = 1; + n = 0; /* start looking at PCN = 0 */ + for (;;) { + for ( ; n < szb; n++) { /* scan past allocated clusters */ + if (bit > 0x80) { + bit = 1; + s++; + } + if ((*s & bit) == 0) break; + bit <<= 1; + } + if (n == szb) break; + first = n; + for ( ; n < szb; n++) { /* find length of free area */ + if (bit > 0x80) { + bit = 1; + s++; + } + if (*s & bit) break; + bit <<= 1; + } + size = (n - first) * pcs; + first = pcntolbn(first); /* get starting lbn */ + if (sw.verbose != NULL) { + printf ("clearing %ld..%ld\015", first, first + size - 1); + fflush (stdout); + } + for (;;) { + iosize = size * BLKSIZE; + if (iosize > iobufsize) iosize = iobufsize; + rwrite (first, iosize, iobuf); + size -= iobufsize / BLKSIZE; + if (size <= 0) break; + first += iobufsize / BLKSIZE; + } + } + if (sw.verbose != NULL) printf ("\n"); + rumountrw (); /* done with the disk */ +} + diff --git a/extracters/rstsflx/docomp.h b/extracters/rstsflx/docomp.h new file mode 100644 index 0000000..e6990e2 --- /dev/null +++ b/extracters/rstsflx/docomp.h @@ -0,0 +1 @@ +extern void docomp(int argc , char ** argv); diff --git a/extracters/rstsflx/dodelete.c b/extracters/rstsflx/dodelete.c new file mode 100644 index 0000000..a60d1cb --- /dev/null +++ b/extracters/rstsflx/dodelete.c @@ -0,0 +1,28 @@ +/* handler for the "delete" command */ + +#include + +#include "flx.h" +#include "fldef.h" +#include "dodelete.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +void dodel2 (firqb *f) +{ + if (protfile (f)) return; /* quit if protected file */ + delfile (f); /* now really delete the file */ + if (sw.verbose != NULL) { + printcurname (f); + printf (" deleted\n"); + } +} + +void dodelete (int argc, char **argv) +{ + rmountrw (); /* mount r/w */ + dofiles (argc, argv, dodel2, NOTNULL); + rumountrw (); /* done with r/w */ +} diff --git a/extracters/rstsflx/dodelete.h b/extracters/rstsflx/dodelete.h new file mode 100644 index 0000000..3440508 --- /dev/null +++ b/extracters/rstsflx/dodelete.h @@ -0,0 +1,4 @@ +extern void dodel2(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void dodelete(int argc , char ** argv); diff --git a/extracters/rstsflx/dodir.c b/extracters/rstsflx/dodir.c new file mode 100644 index 0000000..32633ed --- /dev/null +++ b/extracters/rstsflx/dodir.c @@ -0,0 +1,128 @@ +/* handler for the mkdir" and "rmdir" commands */ + +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "dodir.h" +#include "fip.h" +#include "filename.h" + +void domkdir (int argc, char **argv) +{ + int n; + firqb f; + int newclu; + char *p; + word link, ulink, alink, qlink; + uattr *u; + ua_qt2 *q; + + if (argc == 0) { + printf ("Usage: %s mkdir dir...\n", progname); + return; + } + rmountrw (); + if (sw.clusiz == NULL) { + newclu = pcs; + if (newclu > 16) newclu = 16; + } else { + newclu = strtol (sw.clusiz, &p, 10); + if (newclu < 0) { + newclu = -newclu; + if (newclu < pcs) { + newclu = pcs; + if (newclu > 16) newclu = 16; + } + } + if (*p != '\0' || (newclu < pcs && newclu < 16) + || newclu > 16 || + (newclu & (-newclu)) != newclu) { + rumountrw (); /* dismount first */ + printf ("Invalid clustersize %s\n", sw.clusiz); + return; + } + } + for (n = 0; n < argc; n++) { + if (!parse (argv[n], &f) || f.flags != f_ppn) { + printf ("Invalid PPN %s\n", argv[n]); + continue; + } + if (initfilescan (&f, gfdatrtbl)) { + printf ("Directory [%d,%d] already exists\n", + f.cproj, f.cprog); + } else { + f.cproj = f.proj; /* set up for makedir */ + f.cprog = f.prog; + if (makedir (&f, newclu)) { + if (sw.user != NULL) { + fbread (curgfd + gfdatrtbl); + link = fibufw[f.cprog]; + readlktbl (link); + alink = use(gfdne,k)->ulnk; + if ((ulink = getent ()) == 0) + printf ("No room to mark account as user account\n"); + else { + readlk (ulink); + u = use(uattr,k); + u->ulnk = alink; + u->uatyp = aa_pas; + MARKF; + if ((qlink = getent ()) == 0) { + printf ("No room for second quota block\n"); + qlink = ulink; + } else { + readlk (qlink); + q = use(ua_qt2,k); + q->ulnk = ulink; + q->uatyp = aa_qt2; + q->a2_job = 255U; + q->a2_rib = 4; + q->a2_msg = 12; + MARKF; + } + readlk (link); + use(gfdne,k)->ulnk = qlink; + MARKF; + } + } + if (sw.verbose != NULL) + printf ("Account [%d,%d] created\n", + f.proj, f.prog); + } + } + } + rumountrw (); +} + +void dormdir (int argc, char **argv) +{ + int n; + firqb f; + word ne; + + if (argc == 0) { + printf ("Usage: %s rmdir dir...\n", progname); + return; + } + rmountrw (); + for (n = 0; n < argc; n++) { + if (!parse (argv[n], &f) || (f.flags & ~f_ppnw) != f_ppn) { + printf ("Invalid PPN %s\n", argv[n]); + continue; + } + if ((ne = initfilescan (&f, gfdatrtbl)) == 0) { + printf ("No PPNs matching "); + printfqbppn (&f); + continue; + } + do { + if (remdir (&f, ne) && sw.verbose != NULL) + printf ("Account [%d,%d] deleted\n", + f.cproj, f.cprog); + } while ((ne = nextppn (&f, gfdatrtbl)) != 0); + } + rumountrw (); +} diff --git a/extracters/rstsflx/dodir.h b/extracters/rstsflx/dodir.h new file mode 100644 index 0000000..5cd5993 --- /dev/null +++ b/extracters/rstsflx/dodir.h @@ -0,0 +1,2 @@ +extern void domkdir(int argc , char ** argv); +extern void dormdir(int argc , char ** argv); diff --git a/extracters/rstsflx/dodump.c b/extracters/rstsflx/dodump.c new file mode 100644 index 0000000..bb629c1 --- /dev/null +++ b/extracters/rstsflx/dodump.c @@ -0,0 +1,134 @@ +/* handler for the "dump" command */ + +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "dodump.h" +#include "fip.h" +#include "filename.h" +#include "diskio.h" +#include "fileio.h" +#include "scancmd.h" + +long startblk, endblk; + +static byte toprint (byte c) +{ + if (c > 31 && c < 127) return (c); + if (c > 159 ) return (c); + return ('.'); +} + +static void dumpbuf (firqb *f, word16 *buf, long count, long firstbyte) +{ + int b; + long off, block; + char r50[4]; + + for (off = 0; off < count; off += 16, buf += 8) { + if ((off & (BLKSIZE - 1)) == 0) { + block = (firstbyte + off) / BLKSIZE + startblk; + if (f != NULL) { + printf ("\nFile: "); + printcurname (f); + } else printf ("\nRSTS disk"); + printf (" block %ld\n", block); + } + if (sw.hex != NULL) { + printf ("%03lx/ ", off & (BLKSIZE - 1)); + for (b = 0; b < 8; b++) printf ("%04x ", buf[b]); + } else { + printf ("%03lo/ ", off & (BLKSIZE - 1)); + for (b = 0; b < 8; b++) printf ("%06o ", buf[b]); + } + for (b = 0; b < 8; b++) printf ("%c%c", toprint (buf[b] & 0xff), toprint (buf[b] >> 8)); + if (sw.wide != NULL) { + for (b = 0; b < 8; b++) { + r50toascii (buf[b], r50, TRUE); + printf (" %s", r50); + } + } + printf ("\n"); + } +} + +static void dumpfile (firqb *f) +{ + long iocount, totalbytes, end2; + + if (startblk >= f->size) return; /* nothing to do */ + end2 = endblk; + if (end2 > f->size) end2 = f->size; /* get end for this file */ + initrandom (f); /* set up for random read */ + fileseek (f, startblk); /* and seek to start vbn */ + totalbytes = 0; + while (TRUE) { + iocount = (end2 - startblk) * BLKSIZE - totalbytes; + if (iocount > iobufsize) iocount = iobufsize; + if (iocount <= 0) return; + iocount = seqio (f, iocount, rread, iobuf); + if (iocount == 0) return; /* exit if EOF */ + dumpbuf (f, (word16 *) iobuf, iocount, totalbytes); + totalbytes += iocount; + } +} + +static void dumpdisk (void) +{ + long lbn, iocount, totalbytes; + + if (endblk > diskblocks) endblk = diskblocks; + totalbytes = 0; + for (lbn = startblk; lbn < endblk; lbn += iobufsize / BLKSIZE) { + iocount = (endblk - lbn) * BLKSIZE; + if (iocount > iobufsize) iocount = iobufsize; + if (iocount <= 0) return; + rread (lbn, iocount, iobuf); + dumpbuf (NULL, (word16 *) iobuf, iocount, totalbytes); + totalbytes += iocount; + } +} + +/* "dump" will dump the disk NFS, or a directory (UFD), or a file. If no + * name is specified, you get NFS disk. In that case, there need not be + * any meaningful file structure on the disk. If a PPN is specified but no + * file name, you get the UFD; if a filename is given, you get that file. + */ + +void dodump (int argc, char **argv) +{ + char *p; + + if (sw.start == NULL) startblk = 0; /* start at the bottom */ + else { + if (*sw.start == '0') startblk = strtoul (sw.start, &p, 8); + else startblk = strtoul (sw.start, &p, 10); + if (*p != '\0') { + printf ("Invalid start block %s\n", sw.start); + return; + } + } + if (sw.end == NULL) endblk = 1L << 23; /* dump everything */ + else { + if (*sw.end == '0') endblk = strtoul (sw.end, &p, 8); + else endblk = strtoul (sw.end, &p, 10); + if (*p != '\0') { + printf ("Invalid end block %s\n", sw.end); + return; + } + } + endblk++; /* make end + 1 */ + if (argc == 0) { + ropen (DREADMODE); /* open the disk */ + dumpdisk (); /* do NFS dump */ + rclose (); /* now close it */ + } else { + rmount (); /* mount R/O */ + dofiles (argc, argv, dumpfile, NULLISNULL); + rumount (); /* done with the disk */ + } +} + diff --git a/extracters/rstsflx/dodump.h b/extracters/rstsflx/dodump.h new file mode 100644 index 0000000..fb8f1c0 --- /dev/null +++ b/extracters/rstsflx/dodump.h @@ -0,0 +1 @@ +extern void dodump(int argc , char ** argv); diff --git a/extracters/rstsflx/doget.c b/extracters/rstsflx/doget.c new file mode 100644 index 0000000..51cdd3c --- /dev/null +++ b/extracters/rstsflx/doget.c @@ -0,0 +1,193 @@ +/* handler for the "get" command */ + +#include +#include +#include +#include +#include +#if (defined(__MSDOS__) && !defined(__unix__)) +#include +#endif + +#include "flx.h" +#include "fldef.h" +#include "doget.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +#ifndef S_IRWXU +#define S_IRWXU (S_IREAD+S_IWRITE+S_IEXEC) +#endif +#ifndef S_IRWXG +#define S_IRWXG 0 +#endif +#ifndef S_IRWXO +#define S_IRWXO 0 +#endif +#ifndef S_ISDIR +#define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR) +#endif + +#define mkdirmode (S_IRWXU | S_IRWXG | S_IRWXO) /* mode for new directory */ + +static int concat; /* concatenating to one file */ +static struct stat sbuf; +static char *on, *on2; +static FILE *of; +static byte cproj, cprog; +static long matches, tmatches; +static int binmode; /* true if doing binary copy */ +static const char *openmode; +static long filebytes, tbytes; + +static void dogetfile (firqb *f) { + struct stat sbuf2; + char tmpname[FILENAME_MAX]; + char dirname[FILENAME_MAX]; + char rname[NAMELEN]; + + if (!concat) { + if (S_ISDIR(sbuf.st_mode)) { + if (f->stat & us_ufd) + sprintf (rname, "%03d%03d.dir", f->cproj, f->cprog); + else { + readlk (f->nlink); + r50filename (use(ufdne,k)->unam, + rname, FALSE); + } + if (sw.tree != NULL) { + if (cproj != f->cproj || cprog != f->cprog) { + cproj = f->cproj; + cprog = f->cprog; + sprintf (dirname, "%s/%03d%03d", on, cproj, cprog); + if (stat (dirname, &sbuf2)) { + if (errno != ENOENT) { + printf ("Can't stat %s\n", dirname); + perror (progname); + return; + } +#ifdef __unix__ + if (mkdir (dirname, mkdirmode)) { +#else + if (mkdir (dirname)) { +#endif + printf ("Can't mkdir %s\n", dirname); + perror (progname); + return; + } + } + } + sprintf (tmpname, "%s/%s", dirname, rname); + } else sprintf (tmpname, "%s/%s", on, rname); + on2 = tmpname; + } else on2 = on; + +/* open mode rule for copying to individual files: + * if -b is specified, use binary mode + * if -a is specified, use ascii mode + * else (no mode switch), the choice depends on the + * RMS file attributes, if any, of the input file: + * non-RMS files: + * if extension indicates text file, use ascii mode + * else use binary mode + * directory: use binary mode + * RMS sequential files: + * if fixed length records, recordsize a multiple of 512, use binary mode + * else use ascii mode + * Other RMS organizations, use binary mode + */ + + if (sw.bswitch != NULL) binmode = TRUE; + else if (sw.ascii != NULL) binmode = FALSE; + else { + if (f->stat & us_ufd) binmode = TRUE; + else if (NULLINK(f->rmslink)) + binmode = !textfile (f->cname); + else { + if ((f->recfmt & fa_org) == fo_seq) { + if ((f->recfmt & fa_rfm) == rf_fix + && (f->recsiz & 511) == 0) + binmode = TRUE; + else binmode = FALSE; + } else binmode = TRUE; + } + } + if (binmode) openmode = "wb"; + else openmode = "w"; + if (sw.debug != NULL) + printf ("get mode %s\n", openmode); + of = fopen (on2, openmode); + if (of == NULL) { + printf ("can't create %s\n", on2); + perror (progname); + return; + } + } + matches++; /* found another */ + tmatches++; + filebytes = getfile (of, f, binmode); + tbytes += filebytes; + if (!concat) fclose (of); + if (sw.verbose != NULL) { + printcurname (f); + if (concat && tmatches > 1) + printf (" =>> %s (%ld bytes) in ", on, filebytes); + else printf (" => %s (%ld bytes) in ", on2, filebytes); + if (binmode) printf ("block mode\n"); + else printf ("line mode\n"); + } +} + +void doget (int argc, char **argv) +{ + int s; + firqb f; + + if (argc < 2) { + printf ("Usage: %s get file... dest\n", progname); + return; + } + on = argv[--argc]; /* for convenience */ + cproj = cprog = 0; /* no current PPN yet */ + tmatches = 0; /* total matches */ + tbytes = 0; /* and total bytes */ + if (stat (on, &sbuf)) { /* stat the output spec */ + if (errno != ENOENT) { + printf ("can't stat %s\n", on); + perror (progname); /* report any details */ + return; /* and give up right now */ + } else sbuf.st_mode = 0; /* not found -> not a dir */ + } + s = strlen (on); + if (on[s - 1] == '/') on[s - 1] = '\0'; + on2 = on; + /* concatenating if output is a filespec (not a directory spec) + * and input spec is wildcard, or multiple input specs + */ + parse (argv[1], &f); /* parse first argument for wildcards */ + concat = (!S_ISDIR(sbuf.st_mode) && + (((f.flags & F_WILD) != 0) || argc >= 2)); + if (concat) { /* create now if concatenating */ + if (sw.bswitch == NULL) { + openmode = "w"; /* ascii mode */ + binmode = FALSE; + } else { + openmode = "wb"; /* binary mode */ + binmode = TRUE; + } + if ((of = fopen (on, openmode)) == NULL) { + printf ("can't create %s\n", on); + perror (progname); /* report any details */ + return; /* and give up right now */ + } + } + rmount (); /* mount the disk */ + dofiles (argc, argv, dogetfile, NULLISNULL); + if (concat) fclose (of); + if (sw.verbose != NULL && matches != 0) + printf ("Total files: %ld, total bytes: %ld\n", tmatches, tbytes); + rumount (); /* done with the disk */ +} + diff --git a/extracters/rstsflx/doget.h b/extracters/rstsflx/doget.h new file mode 100644 index 0000000..eaae1cc --- /dev/null +++ b/extracters/rstsflx/doget.h @@ -0,0 +1 @@ +extern void doget(int argc , char ** argv); diff --git a/extracters/rstsflx/dohook.c b/extracters/rstsflx/dohook.c new file mode 100644 index 0000000..2a248fe --- /dev/null +++ b/extracters/rstsflx/dohook.c @@ -0,0 +1,350 @@ +/* handler for the "hook" command */ + +#include +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "silfmt.h" +#include "dohook.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "diskio.h" + +typedef struct { /* boot data pointer in boot block */ + word16 lbn[2]; /* block number, LSW first */ + word16 wcnt; /* word count */ +} bdesc; + +typedef struct { /* header of boot block */ + word16 nop; /* nop required for boot */ + word16 setup_br; /* go do setup and relocation code */ + word16 trap4_vec[2]; /* if trap to 4, halt @ 6 w/ 10 in lights */ + word16 trap10_vec[2]; /* if trap to 10, halt @ 12 w/ 14 in lights */ + word16 clustr; /* 14 cluster size */ + word16 csr; /* 16 csr base */ + word16 devnam; /* 20 device name */ + word16 jmp; /* 22 jump to start address */ + word16 transfer; /* 24 transfer address (set by hook) */ + byte unit; /* 26 unit # in bits <2:0> (set by boot) */ + byte flags; /* 27 flags (definitions are in inidfn) */ + word16 unit_csr; /* 30 unit # in bits for csr (set by boot) */ + byte rc, wc; /* 32 read and write codes */ + word16 function; /* 34 function code: read */ + word16 blknum[2]; /* 36-40 block number to read, also spec func. */ + word16 memadr[2]; /* 42-44 memory address to read into */ + word16 wcnt; /* 46 word count, also spec function parameter */ + word16 reset; /* 50 do a device reset */ + word16 read; /* 52 do a single transfer */ + word16 spec; /* 54 do a magtape special function */ +} bhdr; + +int stbcnt, ovrcnt; /* SIL STB and OVR table entry count */ +stbent *stb = NULL; /* pointer to STB buffer */ +ovrent *ovr = NULL; /* pointer to OVR buffer */ + +/* note 0 rather than NULL because NULL is generally defined wrong + * (causing a warning that is a nuisance though it does no harm) + */ +const char disks[][3] = { "dv","df","ds","dk","dl","dm", + "dp","db","dr","dz","dw","du", + 0 }; + +long findsym (const char *sym) +{ + word16 r50[2]; + int n; + stbent *s; + ovrent *o; + + cvtnametor50 (sym, r50); /* convert symbol to rad50 */ + s = stb; /* point to start of stb */ + for (n = 0; n < stbcnt; n++, s++) + { + if (s->name[0] == r50[0] && s->name[1] == r50[1]) + { + if (s->ovnum >= ovrcnt) + { + printf ("Bad STB entry for %s\n", sym); + return (-1); + } + if (s->ovnum == 0) return (s->value); + o = &ovr[s->ovnum]; + return (s->value - o->base + + (o->offset[0] << 16) + o->offset[1]); + } + } + return (-1); +} + +void setptr (long blk, long size, void *buf) +{ + bdesc *b; + + b = (bdesc *) buf; /* point to where descriptor goes */ + b->wcnt = size / 2; /* set word count */ + b->lbn[0] = blk & 0xffff; /* low order LBN */ + b->lbn[1] = blk >> 16; /* and high order */ +} + +#define SIL 074064 /* rad50 "SIL" */ + +int silchk (firqb *f, savsilindex *x) +{ + word16 cs; + word16 *p; + + p = &(x->si_sil); + if (*p != SIL) /* verify SIL marker */ + { + printcurname (f); + printf (" is not a SIL\n"); + return (FALSE); + } + cs = 0; /* initialize checksum */ + do cs ^= *--p; /* XOR checksum of the rest */ + while (p != (word16 *)x); + if (cs != 0) + { + printf ("checksum error in SIL "); + printcurname (f); + printf ("\n"); + return (FALSE); + } + return (TRUE); /* it's ok */ +} + +/* read file data for some given byte address, and return a pointer to + * where it is. There's at least 512 valid bytes after that point. + */ + +/* this routine reads data from the file, doing the full count requested + * even if it requires multiple calls to seqio. (note that seqio only + * reads a single contiguous piece of file.) + */ + +void readfile (firqb *f, long count, void *buf) +{ + long rcnt; + byte *b; /* workaround cc bug */ + + b = (byte *) buf; + while (count) + { + rcnt = seqio (f, count, rread, b); + if (rcnt == 0) return; /* eof??? */ + b += rcnt; /* adjust by what we read */ + count -= rcnt; /* and count also */ + } +} + +void *getdata (firqb *f, long address) +{ + fileseek (f, address / BLKSIZE); /* seek to the right start block */ + readfile (f, BLKSIZE * 2, iobuf); + return (iobuf + (address % BLKSIZE)); +} + +void cleanup () +{ + rumountrw (); + if (ovr != NULL) free (ovr); + ovr = NULL; + if (stb != NULL) free (stb); + stb = NULL; + return; +} + +void dohook (int argc, char **argv) +{ + savsilindex idx; /* SIL index buffer */ + int n; + firqb hf; /* file to be hooked */ + firqb bf; /* file where bootstraps are */ + char *disk; /* bootstrap name */ + byte bbuf[BLKSIZE]; /* boot block buffer */ + bdesc *bd; /* pointer to current boot data desc */ + bhdr *bh; /* pointer to boot header */ + int dskio, dskioe, xxboot; /* symbols from SIL */ + int dskidx; /* disk index for boot disk name */ + void *btop; /* pointer to end of boot code */ + short int xxent; /* xxboot table entry */ + int pcoffset; /* offset to apply to entry point */ + char *p; + + if (argc == 0) disk = "dl"; + else + { + disk = argv[0]; /* disk is first argument */ + if (strlen (disk) != 2 ) { + printf ("Invalid disk name %s\n", disk); + return; + } + disk[0] = tolower (disk[0]); + if (disk[0] == 'r') disk[0] = 'd'; + disk[1] = tolower (disk[1]); + } + for (dskidx = 0; ; dskidx++) + { + if (disks[dskidx] == NULL) + { + printf ("Unknown disk name %s\n", disk); + return; + } + if (strcmp (disks[dskidx], disk) == 0) break; + } + if (sw.odt != NULL) pcoffset = 2; + else if (sw.offset == NULL) pcoffset = 0; + else + { + pcoffset = strtol (sw.offset, &p, 10); + if (*p != '\0' || (pcoffset & 1) != 0) + { + printf ("Invalid offset %s\n", sw.offset); + return; + } + } + dskidx *= 2; /* make even (byte offset) */ + rmountrw (); /* mount disk for read/write */ + if (argc < 2) parse ("[0,1]init.sys", &hf); + else + { + if (!parse (argv[1], &hf) || hf.flags & F_WILD) + { + cleanup (); + printf ("Invalid filespec %s\n", argv[1]); + return; + } + if ((hf.flags & f_ppn) == 0) + { + hf.proj = 0; + hf.prog = 1; + } + } + if (argc < 3) memcpy (&bf, &hf, sizeof (firqb)); + else { + if (!parse (argv[2], &bf) || bf.flags & F_WILD) + { + cleanup (); + printf ("Invalid filespec %s\n", argv[2]); + return; + } + if ((bf.flags & f_ppn) == 0) + { + bf.proj = 0; + bf.prog = 1; + } + } + if (initfilescan (&bf, gfddcntbl) == 0 || + nextfile (&bf) == 0) + { + printfqbname (&bf); + printf (" not found\n"); + cleanup (); + return; + } + initrandom (&bf); /* set up random access to bootfile */ + seqio (&bf, sizeof(idx), rread, &idx); /* read sil index */ + if (!silchk (&bf, &idx)) + { + cleanup (); + return; /* quit if bad sil index */ + } + stbcnt = idx.si_ent.se_stn; /* copy STB and OVR sizes */ + ovrcnt = idx.si_ent.se_ovn; + if ((stb = (stbent *) malloc (UP(stbcnt * sizeof (stbent),BLKSIZE))) == NULL) + { + cleanup (); + rabort(NOMEM); + } + if ((ovr = (ovrent *) malloc (UP(ovrcnt * sizeof (ovrent),BLKSIZE))) == NULL) + { + cleanup (); + rabort(NOMEM); + } + fileseek (&bf, idx.si_ent.se_stb); /* read symbol table */ + readfile (&bf, UP(stbcnt * sizeof (stbent),BLKSIZE), stb); + fileseek (&bf, idx.si_ent.se_ovb); /* read symbol table */ + readfile (&bf, UP(ovrcnt * sizeof (ovrent),BLKSIZE), ovr); + memset (bbuf, 0, BLKSIZE); /* zero out boot buffer */ + if ((xxboot = findsym ("xxboot")) < 0) + { + cleanup (); + printf ("Symbol XXBOOT not found\n"); + return; + } + if ((dskioe = findsym ("dskioe")) < 0) + { + cleanup (); + printf ("Symbol DSKIOE not found\n"); + return; + } + if ((dskio = findsym ("dskio")) < 0) dskio = dskioe - 72; + xxboot += dskidx; /* point to entry for selected disk */ + xxent = *(short int *)(getdata (&bf, xxboot)); + if (xxent == 0) + { + cleanup (); + printf ("No bootstrap for %s\n", disk); + return; + } + xxboot += xxent; /* point to bootstrap */ + bh = (bhdr *)(getdata (&bf, xxboot)); /* read it */ + n = bh->wcnt; /* get bootstrap size in bytes */ + memcpy (bbuf, bh, n); /* copy that into boot buffer */ + memcpy (bbuf + n, getdata (&bf, dskio), dskioe - dskio); + /* append boot mainline */ + btop = bbuf + n + (dskioe - dskio); + if (initfilescan (&hf, gfddcntbl) == 0 || + nextfile (&hf) == 0) + { + printcurname (&hf); + printf (" not found\n"); + } + openfile (&hf); /* set up to read file to hook */ + seqio (&bf, sizeof(idx), rread, &idx); /* read sil index */ + if (!silchk (&hf, &idx)) + { + cleanup (); + return; /* quit if bad sil index */ + } + openfile (&hf); /* reset to start over at VBN 0 */ + if (idx.usertop >= 0157000) + { + cleanup (); + printcurname (&hf); + printf (" high limit is too high (%06o)\n", idx.usertop); + return; + } + + n = UP(idx.usertop + 2,BLKSIZE); /* compute byte count to boot */ + ((bhdr *) bbuf)->transfer = idx.initpc + pcoffset; + /* set transfer address in bootstrap */ + ((bhdr *) bbuf)->clustr = dcs; /* set clustersize */ + bd = (bdesc *)(&bbuf[0772]); /* initialize boot desc pointer */ + while (n) + { + if (--bd < (bdesc *)btop) /* check for bootstrap full */ + { + cleanup (); + printcurname (&hf); + printf (" is too fragmented to hook\n"); + return; + } + n -= seqio (&hf, n, setptr, bd); + } + rwrite (0, BLKSIZE, bbuf); /* write boot block */ + if (sw.verbose != NULL) + { + printcurname (&hf); + if (sw.offset == NULL && sw.odt == NULL) + printf (" hooked, start PC = %06o\n", idx.initpc); + else printf (" hooked, start PC = %06o, offset %d\n", + idx.initpc + pcoffset, pcoffset); + } + cleanup (); /* clean up now */ + return; /* and we're done */ +} diff --git a/extracters/rstsflx/dohook.h b/extracters/rstsflx/dohook.h new file mode 100644 index 0000000..4e4faf5 --- /dev/null +++ b/extracters/rstsflx/dohook.h @@ -0,0 +1,13 @@ +extern long findsym(const char * sym); +extern void setptr(long blk , long size , void * buf); +extern int silchk(firqb * f , savsilindex * x); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void readfile(firqb * f , long count , void * buf); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void * getdata(firqb * f , long address); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void cleanup(void); +extern void dohook(int argc , char ** argv); diff --git a/extracters/rstsflx/doident.c b/extracters/rstsflx/doident.c new file mode 100644 index 0000000..2038425 --- /dev/null +++ b/extracters/rstsflx/doident.c @@ -0,0 +1,48 @@ +/* handler for the "identify" command */ + +#include + +#include "flx.h" +#include "fldef.h" +#include "doident.h" +#include "fip.h" +#include "rtime.h" + +void doident (int argc, char **argv) /* show pack id data */ +{ + packlabel *p; + char rdate[DATELEN]; + char rtime[RTIMELEN]; + + rmount (); /* mount the disk R/O */ + readdcn (1); /* get the pack label */ + p = use(packlabel,0); + if (p->fill1 == -1 + && (pcs >= dcs) + && ((pcs & (-pcs)) == pcs)) { + printf ("RSTS disk on %s -- \"%s\"\n", rname, pname); + printf (" Device clustersize: %d\n", dcs); + printf (" Pack clustersize: %d\n", pcs); + if (dcs > 1) + printf (" Device size: %ld (%ld DCNs)\n", + diskblocks, diskblocks / dcs); + else printf (" Device size: %ld\n", diskblocks); + printf (" Revision level: %d.%d\n", plevel >> 8, plevel & 0377); + if (plevel >= RDS12) { + cvtdate (p->mntdat, rdate); + cvttime (p->mnttim, rtime); + printf (" Last mount date: %s\n", rdate); + printf (" Last mount time: %s\n", rtime); + } + printf (" Pack flags: "); + if (p->pstat & uc_mnt) printf (" Dirty"); + if (p->pstat & uc_pri) printf (" Private/system"); + else printf (" Public"); + if (p->pstat & uc_ro) printf (" Read-only"); + if (p->pstat & uc_dlw) printf (" DLW"); + if (p->pstat & uc_top) printf (" NFF"); + printf ("\n"); + } else printf ("Disk on %s does not appear to be a RSTS format disk\n", rname); + rumount (); /* done with disk */ +} + diff --git a/extracters/rstsflx/doident.h b/extracters/rstsflx/doident.h new file mode 100644 index 0000000..3e52722 --- /dev/null +++ b/extracters/rstsflx/doident.h @@ -0,0 +1 @@ +extern void doident(int argc , char ** argv); diff --git a/extracters/rstsflx/doinit.c b/extracters/rstsflx/doinit.c new file mode 100644 index 0000000..e006b40 --- /dev/null +++ b/extracters/rstsflx/doinit.c @@ -0,0 +1,387 @@ +/* handler for the "initialize" command */ + +#include +#include +#include +#include +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "doinit.h" +#include "fip.h" +#include "diskio.h" +#include "filename.h" + +#define MFDCLU 16 +#define UFDCLU 16 +#define DEC166COUNT 10 /* number of bad block tables */ + +int getclusize () +{ + int newclu; + char *p; + + if (sw.clusiz == NULL) return (dcs); + else { + newclu = strtol (sw.clusiz, &p, 10); + if (newclu < 0) { + newclu = -newclu; + if (newclu < dcs) newclu = dcs; + } + if (*p != '\0' || newclu < dcs || newclu > 64 || + (newclu & (-newclu)) != newclu) { + printf ("Invalid clustersize %s\n", sw.clusiz); + return (0); + } + } + return (newclu); +} + +#define PSTAT (uc_dlw | uc_pri) /* pack flags to use */ +#define MRECNT 20 /* max RE's for merge.sys */ + +const ufdlabel newmlabel = { 0, 0177777, {0, 0, 0, 0}, {255, 255}, MFD}; +const word16 rstsrts[2] = { 001343, 077770 }; /* rad50 " RSTS " */ + +/* Dummy bootstrap */ + +const word16 dummyboot[] = { + 0000240, /* NOP ; */ + 0000005, /* RESET ;UGH */ + 0000402, /* BR 5$ ;Go to the real code */ + + 0000020,0153430,0000400,/* BOOTID 5$,<> ;Boot ID block, no controllers */ + + 0005067,0000002, /* 5$: CLR 20$ ;COUNT DOWN MEMORY TO DELAY */ + 0005327, /* 10$: DEC (PC)+ ;CHURN */ + 0000000, /* 20$: .WORD 0 ; */ + 0001375, /* BNE 10$ ; */ + 0010700, /* MOV PC,R0 ;GETTA POSITION INDEPENDENT MESSAGE */ + 0062700,0000026, /* ADD #40$-.,R0 ;ADDRESS INTO R0 */ + 0105737,0177564, /* 30$: TSTB @#177564 ;CONSOLE READY ? */ + 0100375, /* BPL 30$ ;PATIENCE */ + 0112037,0177566, /* MOVB (R0)+,@#177566 ;TALK TO ME */ + 0105710, /* TSTB (R0) ;ANY MORE ? */ + 0001371, /* BNE 30$ ;YUP */ + 0000000, /* HALT ;NOPE */ + 0000751 /* BR DUMBOT ;DO IT AGAIN IF HE CONTINUES */ + + /* 40$: ;String starts here */ + }; + +#define dummytext "\a\a\r\nPlease boot from the system disk\r\n" + +void doinit (int argc, char **argv) +{ + long n, count, sattblks; + firqb f, packid; + long newclu, newsize, newrsize; + int dec166; + long newlevel, mfdclu, ufdlbn; + char *p; + char answer[20]; + struct stat sbuf; + word dirne; + packlabel *l; + ufdae *a; + FILE *mf; + long mblocks, moblk, mbytes, mreoff; + word mprevre, mre; + + if (argc == 0) { + printf ("Usage: %s initialize packid [level]\n", progname); + return; + } + packid.flags = 0; + if (*parsename (argv[0], &packid) != '\0' || (packid.flags & F_WILD)) { + printf ("Invalid pack id %s\n", argv[0]); + return; + } + if (argc < 2) newlevel = RDS12; + else { + p = argv[1]; + if (tolower (*p) == 'r') { + p++; + if (tolower (*p++) != 'd' || tolower (*p++) != 's') { + printf ("Invalid revision level %s\n", argv[1]); + return; + } + } + while (*p == ' ') p++; + if (strcmp (p, "0") == 0) newlevel = RDS0; + else if (strcmp (p, "0.0") == 0) newlevel = RDS0; + else if (strcmp (p, "1.1") == 0) newlevel = RDS11; + else if (strcmp (p, "1.2") == 0) newlevel = RDS12; + else { + printf ("Invalid revision level %s\n", argv[1]); + return; + } + } + if (sw.merge != NULL) { /* merging another filesystem */ + if (newlevel == RDS0) { + printf ("-merge not allowed for RDS 0.0\n"); + return; + } + if ((mf = fopen (sw.merge, "rb")) == NULL) { + printf ("Can't open merge file %s\n", sw.merge); + perror (progname); + return; + } + if (fstat (fileno(mf), &sbuf)) { /* get info about input file */ + printf ("Can't stat merge file %s", sw.merge); + perror (progname); + fclose (mf); /* close input */ + return; + } + mblocks = UP(sbuf.st_size,BLKSIZE) / BLKSIZE; + } + if (sw.create != NULL) { + getsize (sw.create, &newsize, &newrsize, &dec166); + if (newsize == 0 || + newsize < 800 || + newsize >= (1 << 23)) { + printf ("Invalid container size %s\n", sw.create); + return; + } + diskblocks = newsize; /* allow writing it all */ + n = (newrsize - 1) >> 16; /* high order bits of last LBN */ + dcs = 1; /* compute DCS */ + while (n) { + n >>= 1; + dcs <<= 1; + } + if (dcs > 16 && newlevel != RDS12) + { + printf ("Large disk requires RDS 1.2\n"); + return; + } + newclu = getclusize (); + setrname (); /* set container name */ + if (stat (rname, &sbuf)) { + if (errno != ENOENT) { + printf ("Can't stat %s\n", rname); + return; + } + } else { + printf ("Container file %s already exists\n", rname); + return; + } + if ((rstsfile = fopen (rname, DCREATEMODE)) == NULL) { + printf ("Error opening container file %s\n", rname); + perror (progname); /* report any details */ + return; + } + memset (iobuf, 0, iobufsize); /* zero the entire buffer */ + for (n = 0; n < newsize; n += iobufsize / BLKSIZE) { + count = iobufsize / BLKSIZE; + if (newsize - n < count) count = newsize - n; + rwrite (n, count * BLKSIZE, iobuf); + } + if (dec166) { /* set up bad block table */ + word16 *w; + memset (iobuf, -1, BLKSIZE); /* set end marker */ + w = (word16 *)iobuf; + *w++ = 031416; /* random serial number */ + *w++ = 0; /* and high order */ + *w++ = 0; /* reserved word */ + *w = 0; /* mark as data pack */ + for (n = 0; n < DEC166COUNT; n++) + rwrite (newrsize + n, BLKSIZE, iobuf); + } + diskblocks = newrsize; + } else { + ropen (DWRITEMODE); + if (dcs > 16 && newlevel != RDS12) + { + printf ("Large disk requires RDS 1.2\n"); + return; + } + newclu = getclusize (); + readlabel (); + if (use(packlabel,0)->fill1 == -1 + && (pcs >= dcs) + && ((pcs & (-pcs)) == pcs)) { + printf ("Disk %s appears to be a RSTS format disk:\n", rname); + printf (" Clustersize: %d\n", pcs); + printf (" Revision: %d.%d\n", plevel >> 8, plevel & 0xff); + printf (" Pack label: %s\n", pname); + printf ("\nRe-initialize it (Y/N)? "); + } else printf ("Initialize %s (Y/N)? ", rname); + fgets (answer, sizeof (answer), stdin); + if (tolower(answer[0]) != 'y') return; + } + fiblk = dcntolbn(1); + memset (fibuf, 0, BLKSIZE); /* clear out fibuf to make an invalid pack */ + fbwrite (); /* write that out */ + pcs = newclu; /* set new PCS */ + f.clusiz = pcs; /* clustersize for files */ + plevel = newlevel; /* set up pack level being created */ + if (plevel == RDS0) pflags = PSTAT; + else pflags = PSTAT | uc_new; /* and flags also */ + pcns = (diskblocks - dcs) / pcs; /* compute PCN count */ + sattblks = UP(pcns,BLKSIZE*8) / (BLKSIZE * 8); /* SATT size in blocks */ + sattsize = sattblks * BLKSIZE; /* and in bytes */ + sattlbn = 1 << 23; /* set a fake SATT LBN */ + if ((sattbufp = (byte *) malloc (sattsize)) == NULL) rabort(NOMEM); + memset (sattbufp, 0xff, sattsize); /* first mark everything in use */ + memset (sattbufp, 0, pcns / 8); /* make all real clusters free */ + if (pcns & 7) sattbufp[pcns / 8] = 0xff << (pcns & 7); /* ditto any leftover bits */ + satptr = 0; /* MFD/label goes at the start */ + if (plevel == RDS0) { /* doing an old pack */ + if (!extdir2 (0, MFDCLU, 0, &newmlabel)) rabort(INTERNAL); + mfddcn = clumap->uent[0]; /* remember MFD start */ + if (sw.debug != NULL) printf ("mfd at %lo\n", mfddcn); + if (mfddcn != 1) rabort(INTERNAL); + curgfd = mfdlbn = dcntolbn(mfddcn); + f.cproj = f.cprog = 1; /* prepare to create [1,1] */ + prevppnlink = nextppnlink = 0; /* nothing in the MFD yet */ + if (!makedir (&f, MFDCLU)) rabort(INTERNAL); /* create MFD */ + readlk2 (0); /* re-read MFD label */ + dirne = use(packlabel,0)->ulnk; /* get [1,1] NE link */ + readlk (dirne); /* read that */ + use(gfdne,k)->uar = 1; /* fill in cluster pointer */ + MARKF; + satptr = pcns / 2; /* put the rest in the middle */ + } else { /* new (RDS1.1 or later) pack */ + if (sw.merge != 0) { /* do the merge */ + if (mblocks <= dcs) { /* merge fits in pack label */ + *sattbufp = 0x01; /* mark first cluster (pack label) allocated */ + } else { + if (getclu (pcs, UP(mblocks-dcs,pcs)) != 1) { + printf ("No room for merge data\n"); + rabort(INTERNAL); + } + } + moblk = 0; + while ((mbytes = fread (iobuf, 1, iobufsize, mf)) != 0) { + mbytes = UP(mbytes, BLKSIZE); + rwrite (moblk, mbytes, iobuf); + moblk += mbytes / BLKSIZE; + } + if (sw.verbose != NULL) + printf ("merged %s (%ld blocks)\n", + sw.merge, mblocks); + } else *sattbufp = 0x01; /* mark first cluster (pack label) allocated */ + satptr = pcns / 2; /* put the rest in the middle */ + mfdclu = MFDCLU; /* default MFD clustersize */ + if (pcs > mfdclu) mfdclu = pcs; + if (mfdclu > 16) mfdclu = 16; /* adjust it as needed */ + if (!extdir2 (0, mfdclu, fd_new, &newmlabel)) rabort(INTERNAL); + mfddcn = clumap->uent[0]; /* remember MFD start */ + if (sw.debug != NULL) printf ("mfd at %lo\n", mfddcn); + mfdlbn = dcntolbn(mfddcn); /* and LBN also */ + curgfd = 0; /* no [0,*] GFD yet */ + } + parse ("[0,1]badb.sys<63>", &f); /* set up firqb */ + f.cproj = f.proj; + f.cprog = f.prog; /* current also */ + memcpy (f.cname, f.name, NAMELEN); + if (!makedir (&f, UFDCLU)) rabort(INTERNAL); /* create [0,1] account */ + dirne = initfilescan (&f, gfdatrtbl); /* look up [0,1] NE pointer */ + if (sw.debug != NULL) printf ("[0,1] NE %o\n", dirne); + if ((ufdlbn = allocufd (dirne, &f)) == 0) rabort(INTERNAL); + /* allocate the UFD */ + fbread (ufdlbn); /* get it into fibuf */ + nextlink = prevlink = 0; + entptr = sizeof (ufdlabel); /* initialize pointers for crefile */ + f.stat = us_nok; /* we want P set for badb.sys */ + f.clusiz = pcs; /* default clustersize */ + if (!crefile (&f, rstsrts, NULL, NULL)) rabort(INTERNAL); + parse ("[0,1]satt.sys<63>", &f); /* set up firqb for the second file */ + f.cproj = f.proj; + f.cprog = f.prog; /* current also */ + memcpy (f.cname, f.name, NAMELEN); + f.stat = us_nok | us_nox; /* P set and contiguous */ + f.size = sattblks; /* we need this size */ + f.clusiz = pcs; /* default clustersize */ + if (!crefile (&f, rstsrts, NULL, NULL)) rabort(INTERNAL); + readlk (f.rlink); /* read first RE */ + sattlbn = dcntolbn(use(ufdre,k)->uent[0]); + if (sw.merge != NULL && (mblocks -= dcs + pcs) > 0) { + moblk = 1 + pcs / dcs; /* first DCN for merge.sys */ + parse ("[0,1]merge.sys<63>", &f); + f.cproj = f.proj; + f.cprog = f.prog; /* current also */ + memcpy (f.cname, f.name, NAMELEN); + f.stat = us_nok | us_nox; /* P set and contiguous */ + f.size = 0; /* don't allocate it now */ + f.clusiz = pcs; /* clustersize is PCS */ + if (!crefile (&f, rstsrts, NULL, NULL)) rabort(INTERNAL); + readlk (f.alink); + a = use(ufdae,k); + a->usiz = mblocks; + if (mblocks >> 16) { /* large file ! */ + a->urts[0] = 0; + a->urts[1] = mblocks >> 16; + } + MARKF; + mprevre = 0; + mreoff = 0; /* fill RE from top */ + while (mblocks > 0) { + if (mreoff == 0) { /* need a new RE */ + if ((mre = getent ()) == 0) { + printf ("No room in [0,1] for merge.sys\n"); + rabort(INTERNAL); + } + if (mprevre) { + readlk (mprevre); + use(ufdre,k)->ulnk = mre; + } else { + readlk (f.nlink); + use(ufdne,k)->uar = mre; + } + MARKF; + mprevre = mre; /* link to this next time */ + } + readlk (mre); + use(ufdre,k)->uent[mreoff] = moblk; + moblk += pcs / dcs; /* advance to next cluster */ + mblocks -= pcs; /* count down size to fill */ + mreoff++; + if (mreoff > 6) mreoff = 0; + } + } + rwrite (sattlbn, sattsize, sattbufp); /* now write the SATT data */ + womsat = FALSE; + free (sattbufp); /* deallocate SATT */ + checkwrite (); /* write FIBUF if needed */ + if (sw.merge != NULL) { /* see if overwriting merge data */ + fbread (0); /* read the boot block */ + for (n = 0; n < BLKSIZE; n++) { + if (fibuf[n] != 0) { + printf ("Warning: non-zero merge file data in boot block\n"); + break; + } + } + } + fiblk = 0; /* build the dummy boot */ + memset (fibuf, 0, BLKSIZE); /* clear it out */ + memcpy (fibuf, dummyboot, sizeof (dummyboot)); + memcpy (fibuf + sizeof (dummyboot), dummytext, sizeof (dummytext)); + fbwrite (); /* and write it */ + readdcn (1); /* re-read pack label */ + if (sw.merge != NULL) { /* see if overwriting merge data */ + for (n = 0; n < BLKSIZE; n++) { + if (fibuf[n] != 0) { + printf ("Warning: non-zero merge file data in pack label\n"); + break; + } + } + } + l = use(packlabel,0); + l->fill1 = 0177777; + l->ppcs = pcs; /* pack cluster size */ + if (plevel > RDS0) { /* if new pack, set new fields: */ + l->mdcn = mfddcn; /* MFD DCN */ + l->plvl = newlevel; /* and rev level */ + l->ulnk = 1; /* link field = 1 by convention */ + l->mntdat = l->mnttim = 0; /* never mounted yet */ + } + l->pstat = pflags; /* set pack flags */ + cvtnametor50 (packid.name, l->pckid); /* set the pack label */ + fbwrite (); /* write the pack label */ + rclose (); /* and that's all! */ +} diff --git a/extracters/rstsflx/doinit.h b/extracters/rstsflx/doinit.h new file mode 100644 index 0000000..5da173d --- /dev/null +++ b/extracters/rstsflx/doinit.h @@ -0,0 +1,2 @@ +extern int getclusize(void); +extern void doinit(int argc , char * argv[]); diff --git a/extracters/rstsflx/dolist.c b/extracters/rstsflx/dolist.c new file mode 100644 index 0000000..41a5361 --- /dev/null +++ b/extracters/rstsflx/dolist.c @@ -0,0 +1,218 @@ +/* handler for the "list" command */ + +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "dolist.h" +#include "fip.h" +#include "rtime.h" +#include "filename.h" +#include "scancmd.h" + +#define COLUMNS 5 + +long files, blocks, tfiles, tblocks; +byte curproj, curprog; + +static void dolistfqb (firqb *f) +{ + word utc; + ufdae *a; + ufdrms1 *r1; + ufdrms2 *r2; + int pos; + int line2; + char rts[RTSLEN]; + char stat[4]; + char credate[DATELEN], acdate[DATELEN], cretime[RTIMELEN]; + char *sp; + + if (sw.narrow != NULL) sw.bswitch = sw.narrow; /* -1 implies -b */ + if (f->cproj != curproj || f->cprog != curprog) + { + if (curproj != 0 || curprog != 0) + { + if (sw.bswitch != NULL) + { + if (sw.narrow != NULL + || files % COLUMNS == 0) + printf ("\n"); + else printf ("\n\n"); + } + else + { + printf (" Total of %ld blocks in %ld files in [%d,%d]\n", + blocks, files, curproj, curprog); + } + } + files = 0; + blocks = 0; + curproj = f->cproj; + curprog = f->cprog; + if (sw.summary == NULL) + { + if (sw.bswitch != NULL) + { + if (sw.narrow == NULL) + printf ("[%d,%d]\n", curproj, curprog); + } + else + { + printf ("\nDirectory of [%d,%d]\n" + " Name .Ext Size Prot Access" + " Creation Clu" + " RTS Pos\n", + curproj, curprog); + } + } + } + files++; /* accumulate totals */ + tfiles++; + blocks += f->size; + tblocks += f->size; + if (sw.summary != NULL) return; + if (sw.bswitch != NULL) { /* brief listing */ + if (sw.narrow != NULL || files % COLUMNS == 0) + printf ("%-10s\n", f->cname); + else printf ("%-10s ", f->cname); + return; + } + sp = stat; /* point to status buffer */ + if (f->stat & us_nox) *sp++ = 'C'; + if (f->stat & us_nok) *sp++ = 'P'; + if (f->stat & us_plc) *sp++ = 'L'; + *sp = '\0'; /* put in terminator */ + readlk (f->alink); /* make sure we have the AE */ + a = use(ufdae,k); /* and point to it */ + cvtdate (a->udla, acdate); /* convert dates and time */ + cvtdate (a->udc, credate); + utc = a->utc; /* save time (for flags) */ + cvttime (utc, cretime); + if (a->urts[0] != 0) + r50toascii2 (a->urts, rts, TRUE); + else memcpy (rts, " ", RTSLEN); + if (f->size == 0) + printf ("%-10s%8ld%-3s <%3d> %11s %11s %8s %3d %-6s ----\n", + f->cname, f->size, stat, f->prot, + acdate, credate, cretime, f->clusiz, rts); + else + { + if (!readlk (f->rlink)) rabort (CORRUPT); + pos = use(ufdre,k)->uent[0]; /* Get first retrieval entry */ + printf ("%-10s%8ld%-3s <%3d> %9s %9s %8s %3d %-6s %6d\n", + f->cname, f->size, stat, f->prot, + acdate, credate, cretime, f->clusiz, rts, pos); + } + if (sw.full != NULL) { /* full listing */ + line2 = FALSE; /* no flags line yet */ + if (f->nlink & ul_che) + { + line2 = TRUE; + printf (" cache:on"); + if (f->alink & ul_che) printf (":seq"); + else printf (":ran"); + } + if (utc & (utc_ig | utc_bk)) + { + if (line2) printf (" "); + line2 = TRUE; + if (utc & utc_ig) printf (" ignore"); + if (utc & utc_bk) printf (" nobackup"); + } + if (line2) printf ("\n"); + if (readlk (f->rmslink)) { /* if RMS attributes present */ + r1 = use(ufdrms1,k); + printf (" rfm:"); + switch (r1->fa_typ & fa_rfm) + { + case rf_udf: printf ("ufd"); break; + case rf_fix: printf ("fix"); break; + case rf_var: printf ("var"); break; + case rf_vfc: printf ("vfc"); break; + case rf_stm: printf ("stm"); break; + } + switch (r1->fa_typ & fa_org) + { + case fo_seq: printf (":seq"); break; + case fo_rel: printf (":rel"); break; + case fo_idx: printf (":idx"); break; + } + if (r1->fa_typ & fa_rat) + { + printf (" rat"); + if (r1->fa_typ & ra_ftn) printf (":ftn"); + if (r1->fa_typ & ra_imp) printf (":imp"); + if (r1->fa_typ & ra_spn) printf (":nospan"); + } + printf (" rsz:%d size:%ld eof:%ld:%d", + r1->fa_rsz, + ((long)(r1->fa_siz[0]) << 16) + r1->fa_siz[1], + ((long)(r1->fa_eof[0]) << 16) + r1->fa_eof[1], + r1->fa_eofb); + if (readlk (r1->ulnk)) + { + r2 = use(ufdrms2,k); + printf (" bkt:%d hdr:%d msz:%d ext:%d", + r2->fa_bkt, r2->fa_hsz, + r2->fa_msz, r2->fa_ext); + } + printf ("\n"); + } + } + if (sw.oattr != NULL && readlk (f->rmslink)) + { + r1 = use(ufdrms1,k); + printf (" %06o %06o %06o %06o %06o %06o %06o", + r1->fa_typ, r1->fa_rsz, + r1->fa_siz[0], r1->fa_siz[1], + r1->fa_eof[0], r1->fa_eof[1], + r1->fa_eofb); + if (readlk(r1->ulnk)) + { + r2 = use(ufdrms2,k); + printf (" %03o %03o %06o %06o", + r2->fa_bkt, r2->fa_hsz, + r2->fa_msz, r2->fa_ext); + } + printf ("\n"); + } +} + +void dolist (int argc, char **argv) +{ + if (argc == 0) + { + argv[0] = "[*,*]"; + argc = 1; + } + tfiles = 0; + tblocks = 0; + curproj = 0; + curprog = 0; + rmount (); /* mount the disk */ + sw.query = NULL; /* force -query to be absent */ + dofiles (argc, argv, dolistfqb, NULLISWILD); + if (tfiles != 0) + { + if (sw.bswitch != NULL) + { + if (sw.narrow == NULL && files % COLUMNS != 0) + printf ("\n"); + } + else + { + if (sw.summary == NULL) + printf (" Total of %ld blocks in %ld files\n", + blocks, files); + else printf (" Total of %ld blocks in %ld files in [%d,%d]\n", + blocks, files, curproj, curprog); + if (tfiles != files) + printf (" Grand total of %ld blocks in %ld files\n", + tblocks, tfiles); + } + } + rumount (); /* done with disk */ +} + diff --git a/extracters/rstsflx/dolist.h b/extracters/rstsflx/dolist.h new file mode 100644 index 0000000..062c16c --- /dev/null +++ b/extracters/rstsflx/dolist.h @@ -0,0 +1 @@ +extern void dolist(int argc , char ** argv); diff --git a/extracters/rstsflx/doprot.c b/extracters/rstsflx/doprot.c new file mode 100644 index 0000000..09577d3 --- /dev/null +++ b/extracters/rstsflx/doprot.c @@ -0,0 +1,54 @@ +/* handler for the "prot" command */ + +#include + +#include "flx.h" +#include "fldef.h" +#include "doprot.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +void doprot2 (firqb *f) +{ + ufdne *n; + + readlk (f->nlink); /* read the NE for this file */ + n = use(ufdne,k); + if (sw.prot != NULL) { + n->ustat |= us_nok; /* set no-kill bit */ + if (sw.verbose != NULL) { + printcurname (f); + printf (" marked no-delete\n"); + } + } else if (sw.unprot != NULL) { + n->ustat &= ~us_nok; /* clear no-kill bit */ + if (sw.verbose != NULL) { + printcurname (f); + printf (" no longer marked marked no-delete\n"); + } + } else { + if ((f->flags & f_prot) == 0) { + printf ("File "); + printcurname (f); + printf (" not changed, no protection specified\n"); + return; + } + n->uprot = f->newprot; + if (sw.verbose != NULL) { + printf ("File "); + printcurname (f); + printf (" protection changed to <%d>\n", f->newprot); + } + } + MARKF; + upddlw (f); +} + +void doprot (int argc, char **argv) +{ + rmountrw (); /* mount the disk */ + dofiles (argc, argv, doprot2, NOTNULL); + rumountrw (); /* done with disk */ +} diff --git a/extracters/rstsflx/doprot.h b/extracters/rstsflx/doprot.h new file mode 100644 index 0000000..218d7cc --- /dev/null +++ b/extracters/rstsflx/doprot.h @@ -0,0 +1,4 @@ +extern void doprot2(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void doprot(int argc , char ** argv); diff --git a/extracters/rstsflx/doput.c b/extracters/rstsflx/doput.c new file mode 100644 index 0000000..d048f1d --- /dev/null +++ b/extracters/rstsflx/doput.c @@ -0,0 +1,301 @@ +/* handler for "put" command */ + +#include +#include +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "doput.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +typedef struct { + const char *ext; + const char *rts; +} rtsent; + +const rtsent rtstbl[] = { + { "tsk", "...rsx" }, + { "sav", "rt11 " }, + { "4th", "forth " }, + { "bas", "basic " }, + { "tec", "teco " }, + { "com", "dcl " }, + { "alc", "algol " }, + { "wps", "wpsedt" }, + { NULL, NULL }}; + +/* check for extension match against runtime system runnable extensions. + * Return TRUE and rts name if a match, false and zeroes otherwise. + */ + +static int checkrts (firqb *f, word16 *rtsname) +{ + const rtsent *r; + + for (r = rtstbl; r->ext != NULL; r++) { + if (strncmp (&(f->cname[7]), r->ext, 3) == 0) { + cvtnametor50 (r->rts, rtsname); + return (TRUE); + } + } + rtsname[0] = rtsname[1] = 0; + return (FALSE); +} + +static void putname (void *name) { + fputs ((char *) name, stdout); +} + +void doput (int argc, char **argv) +{ + char *p, *pp; + FILE *inf; + long newsize; + int newclu; + word16 rtsname[2]; + char *inspec, *outspec; + firqb outf; + firqb tmpf; + long savelbn; + int arg, j; + const char *mode; + int binmode; + char answer; + long bytes, totalbytes, files, insize; + word dirne; + byte defprot; + struct stat sbuf; + ufdrms1 rms1; + ufdrms1 *a1; + ufdrms2 rms2; + ufdrms2 *a2; + + if (argc < 2) { + printf ("Usage: %s put file... dest\n", progname); + return; + } + outspec = argv[--argc]; + if (sw.size == NULL) newsize = 0; + else { + newsize = strtoul (sw.size, &p, 10); + if (*p != '\0') { + printf ("Invalid size %s\n", sw.size); + return; + } + } + if (sw.contig == NULL && newsize != 0) { + newsize = 0; + printf ("-size switch ignored, -contiguous not specified\n"); + } + if (!parse (outspec, &outf)) { + printf ("Invalid destination spec %s\n", outspec); + return; + } + if ((outf.flags & f_name) == 0) { + for (j = 0; j < 6; j++) outf.name[j] = '?'; + outf.flags |= f_name | f_namw; + } + if ((outf.flags & f_ext) == 0) { + outf.name[7] = '?'; + outf.name[8] = '?'; + outf.name[9] = '?'; + outf.flags |= f_ext | f_extw; + } + if (sw.tree == NULL && (outf.flags & f_ppnw) != 0) { + printf ("Wildcard PPN without -tree not allowed in %s\n", + outspec); + return; + } + rmountrw (); /* mount disk R/W */ + if (sw.clusiz == NULL) newclu = pcs; + else { + newclu = strtol (sw.clusiz, &p, 10); + if (newclu < 0) { + newclu = -newclu; + if (newclu < pcs) newclu = pcs; + } + if (*p != '\0' || newclu < pcs || newclu > 128 || + (newclu & (-newclu)) != newclu) { + rumountrw (); /* remember to dismount */ + printf ("Invalid clustersize %s\n", sw.clusiz); + return; + } + } + if (sw.tree == NULL) { + if ((dirne = initfilescan (&outf, gfdatrtbl)) == 0) { + rumountrw (); /* remember to dismount */ + printf ("Account does not exist %s\n", outspec); + return; + } + readlk (dirne); + if ((savelbn = allocufd (dirne, &outf)) == 0) { /* allocate UFD if needed */ + rumountrw (); /* remember to dismount */ + printf ("No room to allocate UFD\n"); + return; + } + } + files = 0; + totalbytes = 0; + for (arg = 0; arg < argc; arg++) { + inspec = argv[arg]; /* pick up a name */ + mergename (inspec, &outf, sw.tree != NULL); + /* construct output name */ + if (outf.cproj == 0 && outf.cprog == 0) { + printf ("Bad directory spec from input filespec %s\n", inspec); + continue; + } + answer = doquery (putname, inspec); + if (answer == 'q') break; + if (answer == 'n') continue; + if (sw.ascii != NULL) binmode = FALSE; + else if (sw.bswitch != NULL) binmode = TRUE; + else binmode = !textfile (outf.cname); + if (binmode) mode = "rb"; + else mode = "r"; + if (sw.debug != NULL) printf ("put mode %s\n", mode); + if ((inf = fopen (inspec, mode)) == NULL) { + printf ("Can't open %s\n", inspec); + perror (progname); + continue; /* skip this one */ + } + if (fstat (fileno(inf), &sbuf)) { /* get info about input file */ + printf ("Can't stat input file %s", inspec); + perror (progname); + fclose (inf); /* close input */ + continue; /* and carry on */ + } + insize = UP(sbuf.st_size,BLKSIZE) / BLKSIZE; + if (sw.tree != NULL) { + memcpy (&tmpf, &outf, sizeof (firqb)); + tmpf.proj = tmpf.cproj; + tmpf.prog = tmpf.cprog; + dirne = initfilescan (&tmpf, gfdatrtbl); /* does PPN exist yet? */ + if (dirne == 0) { + if (!makedir (&outf, pcs)) { + printf ("Cannot create PPN [%d,%d]\n", + outf.cproj, outf.cprog); + fclose (inf); + continue; + } + if (plevel > RDS0) { + fbread (curgfd + gfdatrtbl); + dirne = fibufw[outf.cprog]; + readlktbl (dirne); + } else { + dirne = prevppnlink; + readlk (dirne); + } + } + if ((savelbn = allocufd (dirne, &outf)) == 0) { + printf ("No room to allocate UFD [%d,%d]\n", + outf.cproj, outf.cprog); + fclose (inf); + continue; + } + } + fbread (savelbn); /* read output directory */ + readlk2 (0); /* read UFD label */ + prevlink = 0; /* start there */ + nextlink = use(ufdlabel,0)->ulnk; /* and initialize scan */ + memcpy (&tmpf, &outf, sizeof (firqb)); + memcpy (tmpf.name, outf.cname, NAMELEN); + if (nextfileindir (&tmpf)) { /* file exists... */ + if (protfile (&tmpf)) { + fclose (inf); /* protected file, skip */ + continue; + } + if (sw.prot != NULL) { + printf ("File "); + printcurname (&tmpf); + printf (" exist, not replaced\n"); + fclose (inf); + continue; + } + delfile (&tmpf); /* now really delete the file */ + fbread (savelbn); /* read output directory */ + readlk2 (0); /* read UFD label */ + prevlink = 0; /* start there */ + nextlink = use(ufdlabel,0)->ulnk; /* and initialize scan */ + memcpy (tmpf.name, outf.cname, NAMELEN); + nextfileindir (&tmpf); /* find end of directory */ + } + outf.clusiz = newclu; + if (sw.contig == 0) outf.size = 0; + else { + if (newsize == 0) outf.size = insize; + else outf.size = newsize; + } + defprot = 60; /* default not runnable */ + if (checkrts (&outf, rtsname)) { + if (newsize >> 16) { /* if large file */ + printf ("warning: can't set rts for large file "); + printcurname (&outf); + outf.newprot &= ~up_run; /* never runnable */ + } else defprot = 124; /* default is now runnable */ + } + if ((outf.flags & f_prot) == 0) outf.newprot = defprot; + if (outf.size) outf.stat = us_nox; + else outf.stat = 0; + a1 = NULL; /* assume no attributes */ + a2 = NULL; + memset (&rms1, 0, sizeof(rms1)); /* and clear them in case */ + memset (&rms2, 0, sizeof(rms2)); + if (sw.rmsvar != NULL || sw.rmsfix != NULL || + sw.rmsstm != NULL) { + a1 = &rms1; + if (sw.rmsvar != NULL) { + a1->fa_typ = rf_var | fo_seq; + a2 = &rms2; + memset (&rms2, 0, sizeof(rms2)); + a2->fa_msz = 512; /* dummy value */ + } + if (sw.rmsstm != NULL) a1->fa_typ = rf_stm | fo_seq; + if (sw.rmsfix != NULL) { + a1->fa_typ = rf_fix | fo_seq; + a2 = &rms2; + a1->fa_rsz = strtoul (sw.rmsfix, &pp, 10); + if (*pp != '\0') a1->fa_rsz = 0; + a2->fa_msz = a1->fa_rsz; + insize = (insize / (a1->fa_rsz / BLKSIZE)) * + (a1->fa_rsz / BLKSIZE); + insize++; + } + a1->fa_siz[0] = a1->fa_eof[0] = insize >> 16; + a1->fa_siz[1] = a1->fa_eof[1] = insize & 0xffff; + a1->fa_eofb = 0; + } + if (crefile (&outf, rtsname, a1, a2)) { + bytes = putfile (inf, &outf, binmode); + if (bytes < 0 || (bytes == 0 && outf.size != 0)) { + bytes = -bytes; + printf ("Failure copying %s to ", inspec); + printcurname (&outf); + printf (" -- %ld bytes copied in ", bytes); + if (binmode) printf ("block mode\n"); + else printf ("line mode\n"); + } else if (sw.verbose) { + printf ("%s =>> ", inspec); + printcurname (&outf); + printf (" (%ld bytes) in ", bytes); + if (binmode) printf ("block mode\n"); + else printf ("line mode\n"); + } + files++; + totalbytes += bytes; + } else { + printf ("No room to create file "); + printcurname (&outf); + printf ("\n"); + } + fclose (inf); + } + if (sw.verbose != NULL) + printf ("Total files: %ld, total bytes: %ld\n", files, totalbytes); + rumountrw (); /* done with R/W disk */ +} diff --git a/extracters/rstsflx/doput.h b/extracters/rstsflx/doput.h new file mode 100644 index 0000000..53e89dc --- /dev/null +++ b/extracters/rstsflx/doput.h @@ -0,0 +1 @@ +extern void doput(int argc , char ** argv); diff --git a/extracters/rstsflx/dorename.c b/extracters/rstsflx/dorename.c new file mode 100644 index 0000000..9780299 --- /dev/null +++ b/extracters/rstsflx/dorename.c @@ -0,0 +1,96 @@ +/* handler for the "rename" command */ + +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "dorename.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +firqb newf; /* new name */ + +void renamefile (firqb *f) +{ + ufdne *n; + firqb tmpf; + word saveprev, savenext; + + if (protfile (f)) return; /* quit if file protected */ + mergename (f->cname, &newf, FALSE); + readlk2 (0); /* read UFD label */ + saveprev = prevlink; /* save current scan pointers */ + savenext = nextlink; + prevlink = 0; /* start there */ + nextlink = use(ufdlabel,0)->ulnk; /* and initialize scan */ + memcpy (&tmpf, &newf, sizeof (firqb)); + memcpy (tmpf.name, newf.cname, NAMELEN); + if (nextfileindir (&tmpf)) /* file exists... */ + { + if (f->nlink == tmpf.nlink) + { + printf ("New name matches old name "); + printcurname (f); + printf ("\n"); + return; + } + if (protfile (&tmpf)) return; /* protected file, skip */ + if (sw.replace == NULL) + { + printf ("Cannot rename "); + printcurname (f); + printf (" to %s -- file already exists\n", tmpf.name); + return; + } + delfile (&tmpf); /* now really delete the file */ + } + prevlink = saveprev; /* restore pointers */ + nextlink = savenext; + readlk (f->nlink); /* read the NE */ + n = use(ufdne,k); + cvtnameexttor50 (newf.cname, n->unam); /* write new RAD50 name into NE */ + MARKF; + upddlw (f); + if (sw.verbose != NULL) + { + printcurname (f); + printf (" renamed to %s\n", newf.cname); + } +} + +void dorename (int argc, char **argv) +{ + char *newname; + int j; + + if (--argc < 1) + { + printf ("Usage: %s rename file ... newname\n", progname); + return; + } + newf.flags = 0; /* clear parse flags */ + newname = argv[argc]; /* save name pointer */ + if (*parsenameext (newname, &newf) != '\0') + { + printf ("Invalid new name %s\n", newname); + return; + } + if ((newf.flags & f_name) == 0) + { + for (j = 0; j < 6; j++) newf.name[j] = '?'; + newf.flags |= f_name | f_namw; + } + if ((newf.flags & f_ext) == 0) + { + newf.name[7] = '?'; + newf.name[8] = '?'; + newf.name[9] = '?'; + newf.flags |= f_ext | f_extw; + } + rmountrw (); /* mount the disk */ + dofiles (argc, argv, renamefile, NOTNULL); + rumountrw (); /* done with disk */ +} diff --git a/extracters/rstsflx/dorename.h b/extracters/rstsflx/dorename.h new file mode 100644 index 0000000..f29648d --- /dev/null +++ b/extracters/rstsflx/dorename.h @@ -0,0 +1,4 @@ +extern void renamefile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void dorename(int argc , char ** argv); diff --git a/extracters/rstsflx/dorts.c b/extracters/rstsflx/dorts.c new file mode 100644 index 0000000..f0c5d04 --- /dev/null +++ b/extracters/rstsflx/dorts.c @@ -0,0 +1,56 @@ +/* handler for the "rts" command */ + +#include + +#include "flx.h" +#include "fldef.h" +#include "dorts.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +char *rtsname; /* new rts in ascii */ +word16 rtsr50[2]; /* and in rad50 */ + +void rtsfile (firqb *f) +{ + ufdae *a; + + if (protfile (f)) return; /* quit if file protected */ + readlk (f->alink); /* read the AE */ + a = use(ufdae,k); + if (a->urts[0] == 0 && a->urts[1] != 0) { + printcurname (f); + printf (" is a large file\n"); + return; + } + a->urts[0] = rtsr50[0]; + a->urts[1] = rtsr50[1]; + MARKF; + upddlw (f); + if (sw.verbose != NULL) { + printcurname (f); + printf (" rts changed to %s\n", rtsname); + } +} + +void dorts (int argc, char **argv) +{ + firqb rtsf; + + if (--argc < 1) { + printf ("Usage: %s rts file ... rts\n", progname); + return; + } + rtsf.flags = 0; /* clear parse flags */ + rtsname = argv[argc]; /* save name pointer */ + if (*parsename (rtsname, &rtsf) != '\0' || rtsf.flags != f_name) { + printf ("Invalid rts name %s\n", rtsname); + return; + } + cvtnametor50 (rtsf.name, rtsr50); + rmountrw (); /* mount the disk */ + dofiles (argc, argv, rtsfile, NOTNULL); + rumountrw (); /* done with disk */ +} diff --git a/extracters/rstsflx/dorts.h b/extracters/rstsflx/dorts.h new file mode 100644 index 0000000..702f0f6 --- /dev/null +++ b/extracters/rstsflx/dorts.h @@ -0,0 +1,4 @@ +extern void rtsfile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void dorts(int argc , char ** argv); diff --git a/extracters/rstsflx/dosabsio.c b/extracters/rstsflx/dosabsio.c new file mode 100644 index 0000000..47217f2 --- /dev/null +++ b/extracters/rstsflx/dosabsio.c @@ -0,0 +1,337 @@ +/* absread and abswrite services for use with DJGPP GNU C implementation + * + * Paul Koning 94.10.16 + * 94.11.18 added bios i/o + * 94.11.21 dos i/o for hard disk, bios i/o for floppy + * 94.12.19 add retry for bios I/O + * 95.01.05 update for generalized abs i/o in flx + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "flx.h" +#include "absio.h" + +#define tb _go32_info_block.linear_address_of_transfer_buffer + +#define BIOSBUF (_go32_info_block.size_of_transfer_buffer) + /* size of djgpp bios disk I/O buffer */ +#define BIOSMAX (18 * BLKSIZE) /* max size in biosdisk() call */ +#define BIOSRESET 0 /* error reset */ +#define BIOSREAD 2 /* bios disk read function code */ +#define BIOSWRITE 3 /* bios disk write function code */ +#define BIOSTRIES 4 /* retry count */ +#define ABSREAD 0x25 /* abs read int code */ +#define ABSWRITE 0x26 /* abs write int code */ +#define BIOS_DATA_SEG 0x0040 /* BIOS data segment number */ +#define BIOS_DSK_STATE 0x0090 /* offset to drive 0 media state */ +#define DISK_STATE ((BIOS_DATA_SEG << 4) + BIOS_DSK_STATE) + +#define BIOS_DSK_360K 0x74 /* 360kb media established */ +#define BIOS_DSK_RX50 0x54 /* RX50 media established in drive */ + /* (same as 360kb except single steps */ + /* for 96 tpi media) */ + +static int secsize = 0; +static int param_segment = 0; +static int rx_segment; +static _go32_dpmi_seginfo oldvec; +static _go32_dpmi_seginfo rx50table_vec; +static unsigned short int dosparam[5]; +static int rxflag = 0; /* set if accessing 5.25 inch floppy */ +static int gdrive = -1; /* drive to which geometry data applies */ +static int drive; /* disk unit number currently open */ +static int sectors, heads, cylinders, drives; +static _go32_dpmi_seginfo param_info; + +/* + * Disk parameter table for RX50 floppies in 1.2MB drive + * (set INT 1Eh vector to point to this) + */ +static byte dparm[] = { 0xDF,0x02, /* "specify" cmd bytes */ + 0x25, /* motor turn-on time */ + 2,10, /* 512 b/s, 10 sec/tk */ + 20, /* gap length */ + -1, /* max transfer */ + 24, /* gap length (format) */ + 0xE5, /* fill byte (format) */ + 15, /* head settle time (ms) */ + 8 }; /* motor start time (1/8 sec) */ + +/* The param_buffer is used for two things: + * 1. to hold the dos abs disk I/O parameter block + * 2. to hold the rx50 disk parameter table data + * We put both into the same buffer, in separate segments. + */ + +static void free_param_buffer() +{ + _go32_dpmi_free_dos_memory(¶m_info); + param_segment = 0; +} + +static void alloc_param_buffer() +{ + if (param_segment) return; + param_info.size = (UP(sizeof(param_info),16) + + UP(sizeof(dparm),16)) / 16; + if (_go32_dpmi_allocate_dos_memory(¶m_info)) { + param_segment = 0; + return; + } + param_segment = param_info.rm_segment; + rx_segment = param_segment + UP(sizeof(param_info),16) / 16; + dosmemput(dparm, sizeof(dparm), rx_segment << 4); + rx50table_vec.rm_segment = rx_segment; + rx50table_vec.rm_offset = 0; + atexit(free_param_buffer); +} + +/* convert dos style drive number to bios style number */ + +static int biosdrive (int drive) +{ + if (drive < 3) return (drive - 1); + else return ((drive - 3) + 0x80); /* need to do partitions */ +} + +/* do bios I/O with retries */ + +static int biosdiskr (int func, int drive, int track, int cyl, + int sec, int count, void *buffer) +{ + int tries, status; + + for (tries = 0; tries < BIOSTRIES; tries++) { + status = biosdisk (func, biosdrive (drive), track, cyl, + sec, count, buffer); + if (status == 0) break; + + /* strictly speaking one should do error classification + * at this point... + */ + biosdisk (BIOSRESET, biosdrive (drive), 0, 0, 0, 0, NULL); + } + return (status); +} + +static void getgeom (int drive) +{ + byte status[4]; + + gdrive = drive; + biosdisk (8, biosdrive (drive), 0, 0, 0, 1, status); + heads = status[3] + 1; + drives = status[2]; + cylinders = status[1] + ((status[0] >> 6) << 8) + 1; + sectors = status[0] & 0x3f; + if (status[0] == 15 && status[1] == 79 & status[3] == 1) + rxflag = 1; + else rxflag = 0; +} + +/* Convert block number to cylinder, head, sector for RT11-RX50. + * This is different for RT11 than for Rainbow DOS: + * For DOS, for cylinders 2 through 79, the sectors are interleaved 2:1. + * (DOS capability is not supported in this RT11 version). + * For RT11, all sectors are interleaved 2:1, and each subsequent + * track has the first logical block offset by 2 more sectors. + */ + +static void makechs_rx50 (int block, int *trk, int *sec) +{ + int t, s; + + t = block / 10; + s = block % 10 + 1; + if (s < 6) s = (s - 1) * 2 + 1; + else s = (s - 5) * 2; + s += t * 2; + while (s > 10) s -= 10; + t++; + if (t == 80) t = 0; /* wrap around last 10 blocks */ + *trk = t; + *sec = s; +} + +/* do single block disk I/O to DEC RX50 floppy */ +static int rx50io (int func, int drive, int dsksec, void *buffer) +{ + byte oldstate; + byte newstate = BIOS_DSK_RX50; + int cyl, sec; + int status; + + alloc_param_buffer(); + + /* save old state and set up for RX50 I/O */ + _go32_dpmi_get_real_mode_interrupt_vector (0x1E, &oldvec); + _go32_dpmi_set_real_mode_interrupt_vector (0x1E, &rx50table_vec); +#ifdef NOT + dosmemget (DISK_STATE, 1, &oldstate); + dosmemput (&newstate, 1, DISK_STATE); +#endif + + makechs_rx50 (dsksec, &cyl, &sec); + status = biosdiskr (func, drive, 0, cyl, sec, 1, buffer); + + /* restore BIOS state as it was on entry */ + _go32_dpmi_set_real_mode_interrupt_vector (0x1E, &oldvec); +#ifdef NOT + dosmemput (&oldstate, 1, DISK_STATE); +#endif + return (status); +} + +/* do bios disk I/O call + * if this is a 5.25" floppy, we do the required magic to read it as + * a DEC RX50 format floppy. + */ + +static int biosio (int func, int drive, int dsksec, int count, void *buffer) +{ + int track, sec, cyl; + int tcount, status; + + if (drive != gdrive) getgeom (drive); + while (count) { + if (rxflag) { + tcount = BLKSIZE; + status = rx50io (func, drive, dsksec, buffer); + } else { + tcount = count; + if (tcount > BIOSMAX) tcount = BIOSMAX; + sec = dsksec % sectors; + if ((sectors - sec) * BLKSIZE < tcount) + tcount = (sectors - sec) * BLKSIZE; + sec++; /* weird 1-based numbering */ + track = (dsksec / sectors) % heads; + cyl = dsksec / (sectors * heads); + status = biosdiskr (func, drive, track, cyl, + sec, tcount / BLKSIZE, buffer); + } + if (status) return (status); + count -= tcount; + buffer += tcount; + dsksec += (tcount / BLKSIZE); + } + return (0); +} + +/* do absolute dos disk read/write + * arguments: + * function code (0x25 = read, 0x26 = write) + * drive number (1 = a:, etc) + * starting sector number + * byte count (must be multiple of sector size) + * buffer pointer + */ + +static int dosio (int func, int drive, int sec, int count, void *buffer) +{ + int bseg, bofs, xfer=0, before=0, tcount; + _go32_dpmi_registers r; + + while (count) { + tcount = count; + if (tcount > BIOSBUF) tcount = BIOSBUF; + alloc_param_buffer(); + dosparam[0] = sec & 0xffff; + dosparam[1] = sec >> 16; + dosparam[2] = (tcount / secsize) & 0xffff; + dosparam[3] = (unsigned int) tb & 15; + dosparam[4] = (unsigned int) tb >> 4; + dosmemput(dosparam, sizeof(dosparam), param_segment << 4); + if (func == ABSWRITE) + dosmemput(buffer, tcount, tb); + memset(&r, 0, sizeof(r)); + r.h.al = drive - 1; /* 0-based numbering here */ + r.x.ds = param_segment; + r.x.bx = 0; + r.x.cx = -1; + _go32_dpmi_simulate_int(func, &r); + if (func == ABSREAD) + dosmemget(tb, tcount, buffer); + if (r.x.flags & 1) + return (r.h.al); + count -= tcount; + buffer += tcount; + sec += (tcount / secsize); + } + return (0); +} + +/* return size of specified disk, in blocks. Saves sector size in a local + * static variable as a side effect. A flag is set if the disk is a + * 5.25 inch floppy. + * Note: this must be called before any abs I/O is done. + */ + +static int disksize (int drive) +{ + _go32_dpmi_registers r; + byte mid; + + if (drive >= 3) { /* hard disk */ + memset(&r, 0, sizeof(r)); + r.h.ah = 0x1c; + r.h.dl = drive; + _go32_dpmi_simulate_int(0x21, &r); + secsize = r.x.cx; + return (r.h.al * r.x.dx * secsize / BLKSIZE); + } else { + getgeom (drive); + secsize = 512; + return (cylinders * heads * sectors); + } +} + +/* this routine is called to scan a supplied container file/device + * name. If the name refers to a real disk, then absflag is set + * and rsize is set to the device size. Otherwise, no action is taken. + */ + +void absname (const char *rname) +{ + if (rname[strlen(rname) - 1] == ':') { /* device name alone */ + absflag = TRUE; + drive = tolower (rname[0]) - 'a' + 1; /* set drive number */ + rsize = disksize (drive); + if (sw.debug != NULL) + printf ("disk size for drive %d is %d\n", drive, rsize); + } +} + +int absopen (const char *rname, const char *mode) +{ + return (0); /* always ok, nothing to do */ +} + +void absseek (int block) { } /* nothing to do */ + +void absclose () { } /* nothing to do */ + +int absread (int sec, int count, void *buffer) +{ + if (drive >= 3) /* hard disk */ + return (dosio (ABSREAD, drive, sec, count, buffer)); + else + return (biosio (BIOSREAD, drive, sec, count, buffer)); +} + +int abswrite (int sec, int count, void *buffer) +{ +#ifdef NOT_YET + if (drive >= 3) /* hard disk */ + return (dosio (ABSWRITE, drive, sec, count, buffer)); + else + return (biosio (BIOSWRITE, drive, sec, count, buffer)); +#endif +} + diff --git a/extracters/rstsflx/dosabsio.h b/extracters/rstsflx/dosabsio.h new file mode 100644 index 0000000..1f1355e --- /dev/null +++ b/extracters/rstsflx/dosabsio.h @@ -0,0 +1,3 @@ +extern int absread (int drive, int sec, int count, void *buffer); +extern int abswrite (int drive, int sec, int count, void *buffer); +extern int disksize (int drive); diff --git a/extracters/rstsflx/dosrxio.c b/extracters/rstsflx/dosrxio.c new file mode 100644 index 0000000..1082abd --- /dev/null +++ b/extracters/rstsflx/dosrxio.c @@ -0,0 +1,203 @@ +/* floppy disk I/O for DOS + * + * based on RXRTDVRA.ASM by Robert Morse and John Dudeck + */ + +/* --------------------------------------------------------------- + * IBM ROM BIOS Definitions + * --------------------------------------------------------------- + */ + +#define DKOP_RUPT 013h /* interrupt to call ROM BIOS */ +#define DKOP_RESET 000h /* reset controller */ +#define DKOP_STATUS 001h /* read status from last operation */ +#define DKOP_READ 002h /* read sectors */ +#define DKOP_WRITE 003h /* write sectors */ +#define DKOP_VERIFY 004h /* verify sectors */ +#define DKOP_CHANGE 016h /* test changed status */ +#define DKOP_SETTYPE 017h /* set media type in drive */ + +#define DKST_TIMEOUT 080h /* drive not ready */ +#define DKST_BADSEEK 040h /* seek failed */ +#define DKST_BADNEC 020h /* NEC controller failed */ +#define DKST_BADCRC 010h /* read CRC error */ +#define DKST_BADDMA 009h /* attempt to DMA over 64K boundary */ +#define DKST_OVERRUN 008h /* DMA overrun */ +#define DKST_CHANGED 006h /* media changed */ +#define DKST_RNF 004h /* sector not found */ +#define DKST_WRPROT 003h /* write-protected diskette */ +#define DKST_ADRMARK 002h /* address mark not found */ +#define DKST_BADCMD 001h /* invalid command */ + + +#define BIOS_DATA_SEG 0040h + +/* #define BIOSDATA segment at BIOS_DATA_SEG /* BIOS data segment-- */ + +#define bios_dsk_state (*(byte *)(0x0090)) /* drive 0 media state */ + +#define BIOS_DSK_360K 074h /* 360kb media established */ +#define BIOS_DSK_RX50 054h /* RX50 media established in drive */ + /* (same as 360kb except single steps */ + /* for 96 tpi media) */ + +/* Convert block number to cylinder, head, sector for RT11-RX50. + * This is different for RT11 than for Rainbow DOS: + * For DOS, for cylinders 2 through 79, the sectors are interleaved 2:1. + * (DOS capability is not supported in this RT11 version). + * For RT11, all sectors are interleaved 2:1, and each subsequent + * track has the first logical block offset by 2 more sectors. + */ + +void makechs_rx50 (int block, int *trk, int *sec) +{ + int t, s; + + t = block / 10; + s = block % 10 + 1; + if (s < 6) s = (s - 1) * 2 + 1; + else s = (s - 5) * 2; + s += t * 2; + while (s > 10) s -= 10; + t++; + *trk = t; + *sec = s; +} + +;Common routine for read, write and verify. +; +;Given: AL = operation code +; ES:DI = pointer to IOP, which contains +; iop_block = starting block number +; iop_bufptr = starting buffer address +; iop_count = number of blocks +;Returns: AX = IOP error code +; xx_count = number of requested blocks NOT transferred + +do_readwrite: + mov es:iop_rwvoloff[di], offset vol_name + mov es:iop_rwvolseg[di], cs + + mov xx_oper, al ;save operation code + + mov ax, es:iop_block[di] ;set starting block number + + test ax, ax ;JRD check for negative + jge do_rw1 ;JRD + xor ax, ax ;JRD +do_rw1: + push si ;JRD + mov si, bpb_pointer ;JRD + cmp ax, bpb_totsects[si] ;JRD test for too big + jle do_rw2 ;JRD + mov ax, bpb_totsects[si] ;JRD limit to maximum +do_rw2: + pop si ;JRD + + mov xx_block, ax + mov ax, es:iop_count[di] ;set block count + mov xx_count, ax + test ax, ax + jz dorw_success ; quit if 0 sectors to do + + mov ax, es:iop_bufoff[di] ;set starting buffer offset + mov xx_offset, ax ; and segment + mov ax, es:iop_bufseg[di] + mov xx_seg, ax + +dorw_loop: + mov xx_retries, 5 ;set retry counter +dorw_again: + mov ax, BIOS_DATA_SEG ;set diskette status to single + mov es, ax ; stepping for 96 tpi + mov es:bios_dsk_state, BIOS_DSK_RX50 + + mov ax, xx_block ;load block number + call makechs_rx50 ; and convert to CHS + mov dl, PHYS_DRIVE_0 ;set drive number + mov ah, xx_oper ;operation code + mov al, 1 ;transfer 1 sector + les bx, xx_buf ;set ES:BX to buffer address + int DKOP_RUPT ;invoke ROM BIOS to do it + mov xx_status, ah ; and save returned status + test ah, ah ;test for error + jnz dorw_error ; break loop on error + + inc xx_block ;advance to next block + add xx_offset, PHYS_BLKSIZE ;advance buffer pointer + dec xx_count ;count blocks + jnz dorw_loop ; and continue until done +dorw_success: + xor ax, ax ;set no-error code + ret + ;Analyze read/write errors and either make another attempt or +;set the error code and return. + +dorw_error: + mov al, IOPST_NOTRDY + test ah, DKST_TIMEOUT + jnz dorw_giveup + + mov al, IOPST_SEEK + test ah, DKST_BADSEEK + jnz dorw_retry + + mov al, IOPST_IOERR + test ah, DKST_BADNEC + jnz dorw_retry + + cmp ah, DKST_OVERRUN + je dorw_retry + + mov al, IOPST_CRC + cmp ah, DKST_BADCRC + je dorw_retry + + mov al, IOPST_BADCMD + cmp ah, DKST_BADDMA + je dorw_giveup + + cmp ah, DKST_BADCMD + je dorw_giveup + + mov al, IOPST_BADCHNG + cmp ah, DKST_CHANGED + jne dorw_nochange + cmp open_count, 0 + jg dorw_giveup ;error if change with any files open + jmp short dorw_reset ; else do it again +dorw_nochange: + mov al, IOPST_RNF + cmp ah, DKST_RNF + je dorw_retry + + mov al, IOPST_WRPROT + cmp ah, DKST_WRPROT + je dorw_giveup + + mov al, IOPST_UNKMEDIA + cmp ah, DKST_ADRMARK + je dorw_retry + + mov al, IOPST_IOERR + jmp short dorw_giveup +dorw_retry: + dec xx_retries ;count retries + jle dorw_giveup +dorw_reset: + mov ah, DKOP_RESET ;reset the disk controller + int DKOP_RUPT + jmp dorw_again ; and try again +dorw_giveup: + mov ah, high IOPST_ERR ;complete the driver error return code + ret + +int rxread (int block, int size, void *buffer) +{ + return (rxio (DKOP_READ, block, size, buffer)); +} + +int rxwrite (int block, int size, void *buffer) +{ + return (rxio (DKOP_WRITE, block, size, buffer)); +} diff --git a/extracters/rstsflx/dotype.c b/extracters/rstsflx/dotype.c new file mode 100644 index 0000000..27cb5c6 --- /dev/null +++ b/extracters/rstsflx/dotype.c @@ -0,0 +1,28 @@ +/* handler for the "type" command */ + +#include + +#include "flx.h" +#include "fldef.h" +#include "dotype.h" +#include "fip.h" +#include "filename.h" +#include "fileio.h" +#include "scancmd.h" + +void typefile (firqb *f) +{ + if (sw.verbose != NULL) { + printf ("\n----- "); + printcurname (f); + printf (" -----\n"); + } + getfile (stdout, f, FALSE); /* put it on stdout */ +} + +void dotype (int argc, char **argv) +{ + rmount (); /* mount the disk */ + dofiles (argc, argv, typefile, NOTNULL); + rumount (); /* done with disk */ +} diff --git a/extracters/rstsflx/dotype.h b/extracters/rstsflx/dotype.h new file mode 100644 index 0000000..9c7ba98 --- /dev/null +++ b/extracters/rstsflx/dotype.h @@ -0,0 +1,4 @@ +extern void typefile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void dotype(int argc , char ** argv); diff --git a/extracters/rstsflx/fdprm b/extracters/rstsflx/fdprm new file mode 100644 index 0000000..0cd6030 --- /dev/null +++ b/extracters/rstsflx/fdprm @@ -0,0 +1,29 @@ +# /etc/fdprm - floppy disk parameter table + +# Common disk formats. Names are of the form +# actual media capacity/maximum drive capacity +# (Note: although 5.25" HD drives can format disks at 1.44M, they're listed +# as 1200 because that's the common maximum size.) + +# size sec/t hds trk stre gap rate spec1 fmt_gap +360/360 720 9 2 40 0 0x2A 0x02 0xDF 0x50 +1200/1200 2400 15 2 80 0 0x1B 0x00 0xDF 0x54 +360/720 720 9 2 40 1 0x2A 0x02 0xDF 0x50 +720/720 1440 9 2 80 0 0x2A 0x02 0xDF 0x50 +720/1440 1440 9 2 80 0 0x2A 0x02 0xDF 0x50 +360/1200 720 9 2 40 1 0x23 0x01 0xDF 0x50 +720/1200 1440 9 2 80 0 0x23 0x01 0xDF 0x50 +1440/1440 2880 18 2 80 0 0x1B 0x00 0xCF 0x6C + +# Non-standard disk formats: + +# BEWARE: They're incomplete and possibly incorrect. The only reason why +# they are in this file is to show how such formats are added. + +1440/1200 2880 18 2 80 0 ???? ???? ???? ???? # ????? +1680/1440 3360 21 2 80 0 0x0C 0x00 0xCF 0x6C # ????? + +# Add user-specific formats here +cbm1581 1600 10 2 80 2 0x2A 0x02 0xDF 0x2E +800/720 1600 10 2 80 0 0x2A 0x02 0xDF 0x2E +rx50 800 10 1 80 0 0x23 0x01 0xDF 0x50 diff --git a/extracters/rstsflx/fileio.c b/extracters/rstsflx/fileio.c new file mode 100644 index 0000000..3775620 --- /dev/null +++ b/extracters/rstsflx/fileio.c @@ -0,0 +1,592 @@ +/* subroutines to do rsts file (virtual block) I/O */ + +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "fileio.h" +#include "filename.h" +#include "diskio.h" +#include "fip.h" + +long totalbytes; /* total bytes transferred for get/put */ +long curvbn; /* current file vbn (0-based) */ +word curre; /* link of current RE */ +word lastre; /* and last one seen */ +int curreoff; /* offset into current RE */ +int cluoff; /* offset into current file cluster */ +int dcnperfcs; /* fcs / dcs */ + + +static int rmseof (firqb *f, char *recp, long iocount) +{ + long curblk; + int curbyt; + + curblk = curvbn + (recp - iobuf - iocount) / BLKSIZE; + curbyt = (recp - iobuf) % BLKSIZE; + if (curblk > f->eofblk) return (TRUE); + return (curblk == f->eofblk && curbyt >= f->eofbyte); +} + +/* in each of the following "get a record" routines (one for each record + * format defined for RMS-11) the arguments are: + * f pointer to firqb struct + * len pointer to record length return variable + * eor pointer to end of record return variable (flag) + * iocount amount of data in I/O buffer (from last seqio call) + * + * len is set to the length of the record or partial record returned. + * the pointer to the record is the return value of the function. + * eor is set true if a whole record was transferred, and false if only + * a partial record is returned. (If eor is set, then a line delimiter + * should be added by the caller if it is not contained in the record + * itself.) + * If nothing was transferred (i.e., the caller should retry) then + * these functions return NULL. Otherwise they return a record pointer. + * Note that in the latter case the length may be zero, which means + * the record was an empty line. + */ + +static char *getfix (firqb *f, long *len, int *eor, long iocount) +{ + long left; /* amount left in I/O buffer */ + char *recp; + + recp = f->currec; + left = &iobuf[iocount] - recp; /* compute what's left */ + *eor = FALSE; /* default to not EOR */ + if (left <= 0 || rmseof (f, recp, iocount)) { + *len = 0; + f->currec = NULL; + return (NULL); + } + if (left < f->recsiz) { + *len = left; + f->currec = NULL; + return (recp); + } + *len = f->recsiz; + f->currec += f->recsiz; + *eor = TRUE; + return (recp); +} + +static char *getvar (firqb *f, long *len, int *eor, long iocount) +{ + char *recp; + word16 reclen; + word16 *reclenp; + long left; + + recp = f->currec; + *eor = FALSE; /* default to not EOR */ + left = (&iobuf[iocount] - recp); + if (left <= 0 || rmseof (f, recp, iocount)) { + *len = 0; + f->currec = NULL; + f->currecsiz = 0; + return (NULL); + } + if ((reclen = f->currecsiz) == 0) { + reclenp = (word16 *)recp; + reclen = *reclenp; + if (reclen == 0xffff) { /* end of data in block */ + left &= -BLKSIZE; /* get what's left in remaining blocks */ + if (left == 0) { + *len = 0; + f->currec = NULL; + f->currecsiz = 0; + return (NULL); + } else { + recp = &iobuf[iocount - left]; + reclenp = (word16 *) recp; + reclen = *reclenp; + } + } + left -= 2; /* discount length field */ + recp += 2; /* and skip it */ + } + if (reclen > left) { + *len = left; + f->currecsiz = reclen - left; /* do this next time */ + f->currec = NULL; + return (recp); + } + f->currec = recp + UP(reclen,2); /* point to where next count is */ + f->currecsiz = 0; /* no partial record left to do */ + *len = reclen; + *eor = TRUE; + return (recp); +} + +static char *getvfc (firqb *f, long *len, int *eor, long iocount) +{ + char *recp; + word16 reclen; + word16 *reclenp; + long left, skip; + + recp = f->currec; + *eor = FALSE; /* default to not EOR */ + left = (&iobuf[iocount] - recp); + if ((reclen = f->currecsiz) != 0) skip = f->recskip; + else { + reclenp = (word16 *)recp; + reclen = *reclenp; + if (reclen == 0xffff) { /* end of data in block */ + left &= -BLKSIZE; /* get what's left in remaining blocks */ + if (left == 0) { + *len = 0; + f->currec = NULL; + f->currecsiz = 0; + return (NULL); + } else { + recp = &iobuf[iocount - left]; + reclenp = (word16 *) recp; + reclen = *reclenp; + } + } + left -= 2; /* discount length field */ + recp += 2; /* and skip it */ + skip = f->rechdrsiz; /* skip over whole header */ + } + if (reclen > left) { + f->currecsiz = reclen - left; /* do this next time */ + if (left > skip) { + *len = left - skip; + f->recskip = 0; /* nothing to skip */ + f->currec = NULL; + return (recp + skip); + } else { + *len = 0; + f->recskip = skip - left; + return (NULL); + } + } + f->currec = recp + UP(reclen,2); /* point to where next count is */ + f->currecsiz = 0; /* no partial record left to do */ + *len = reclen - skip; + *eor = TRUE; + return (recp + skip); +} + +static char *getstm (firqb *f, long *len, int *eor, long iocount) +{ + char *lfpos; + char *recp; + + *eor = FALSE; /* default to not EOR */ + while (f->currec < &iobuf[iocount]) + if (*(f->currec)) break; + else f->currec++; /* skip nulls */ + if (f->currec == &iobuf[iocount]) { + *len = 0; + f->currec = NULL; + return (NULL); + } + lfpos = (char *) memchr (f->currec, 012, &iobuf[iocount] - f->currec); + recp = f->currec; + if (lfpos == NULL || lfpos == f->currec) { + *len = &iobuf[iocount] - f->currec; + *eor = FALSE; + f->currec = NULL; + } else { + if (*(lfpos - 1) == '\015') *len = lfpos - f->currec - 1; + else *len = lfpos - f->currec; + *eor = TRUE; + f->currec = lfpos + 1; + } + return (recp); +} + +/* note that a partial record may be returned; if so, eor is set to false */ + +static char *getrec (firqb *f, long *len, int *eor, long iocount) /* get next text record */ +{ + switch (f->recfmt & fa_rfm) { + case rf_udf: + case rf_stm: + return (getstm (f, len, eor, iocount)); + case rf_fix: + return (getfix (f, len, eor, iocount)); + case rf_var: + return (getvar (f, len, eor, iocount)); + case rf_vfc: + return (getvfc (f, len, eor, iocount)); + } + rabort (INTERNAL); /* should never get here */ + return (NULL); /* to make the compiler happy */ +} + +/* Routine to do sequential I/O, either read or write according to the + * third argument passed. + */ +long seqio (firqb *f, long iolen, iohandler io, void *buffer) +{ + long startlbn; /* lbn at which to start transfer */ + long count; /* and byte count */ + word prevdcn = 0; /* previous RE entry */ + + if (curvbn >= f->size) return (0); /* nothing left */ + for (count = 0; ; ) { + if (cluoff == 0) { + if (curreoff == 0 && (f->stat & us_ufd) == 0) { + if (!readlk (curre)) rabort(BADRE); + lastre = curre; + } + if (count != 0) { + if (f->stat & us_ufd) { + if (clumap->uent[curreoff] - prevdcn != dcnperfcs) + break; + } else { + if (use(ufdre,k)->uent[curreoff] - prevdcn != dcnperfcs) + break; + } + } + if (sw.debug != 0) + printf ("seqio() RE entry %o\n", use(ufdre,k)->uent[curreoff]); + } + if (count++ == 0) { + if (f->stat & us_ufd) + startlbn = dcntolbn(clumap->uent[curreoff]) + + cluoff; + else startlbn = dcntolbn(use(ufdre,k)->uent[curreoff]) + + cluoff; + if (sw.debug != NULL) + printf ("seqio() start lbn %lo\n", startlbn); + } + /* contiguous file is treated as having one giant cluster... */ + if (++cluoff == f->clusiz && ((f->stat & us_nox) == 0)) { + cluoff = 0; + prevdcn = use(ufdre,k)->uent[curreoff]; + curreoff++; /* on to the next RE entry */ + if (curreoff == 7) { /* time to read anothe RE */ + if (f->stat & us_ufd) curre = 0; + else curre = use(ufdre,k)->ulnk; + curreoff = 0; + } + } + if (count == iolen / BLKSIZE || curvbn + count == f->size) break; + } + (*io) (startlbn, count * BLKSIZE, buffer); + curvbn += count; /* account for what we transferred */ + return (count * BLKSIZE); /* and return the byte count */ +} + +void openfile (firqb *f) /* set up file I/O at VBN 0 */ +{ + curvbn = 0; /* currently at first block */ + lastre = 0; /* working on first RE */ + curre = f->rlink; /* set current RE link */ + curreoff = 0; /* working on RE entry 0 */ + cluoff = 0; /* and start of that cluster */ +/* note: on big disks (dcs > 16) dcnperfcs will end up 0 for directories. + * that's fine; the result is that no transfer that crosses retrieval + * entries will be done in a single I/O -- exactly what we want. + */ + dcnperfcs = f->clusiz / dcs; /* how many dcn's in file cluster */ + if (f->size) /* read first RE if non-null */ + if ((f->stat & us_ufd) == 0 && !readlk (f->rlink)) + rabort(BADRE); +} + +word *relist = NULL; /* list of pointers to RE's */ + +void initrandom (firqb *f) +{ + long recount; + + if (relist != NULL) free (relist); + if (f->stat & us_ufd) return; /* UFDs are easy */ + openfile (f); /* first do common setup */ + /* Note: do not use UP() here since we don't round to + * a power of 2! + */ + recount = (f->size + 7 * f->clusiz - 1) / (7 * f->clusiz); + if ((relist = (word *) malloc (recount * sizeof (word))) == NULL) + rabort(NOMEM); + memset (relist, 0, recount * sizeof (word)); + relist[0] = f->rlink; +} + +void fileseek (firqb *f, long vbn) /* seek to (0-based) vbn */ +{ + int clu, re, renum; + word prevre; + + if (vbn >= f->size) rabort(INTERNAL); + clu = vbn / f->clusiz; /* get cluster number */ + if ((f->stat & us_ufd) == 0) { /* more work for non-UFDs */ + renum = clu / 7; /* get RE number */ + if (relist[renum] == 0) { /* load RE list if we haven't been here */ + for (re = 0; re <= renum; re++) { + if (relist[re]) prevre = relist[re]; + else { + if (!readlk (prevre)) rabort(CORRUPT); + relist[re] = prevre = use(ufdre,k)->ulnk; + } + } + } + readlk (curre = relist[renum]); /* read appropriate RE */ + } + curreoff = clu % 7; /* set index into RE */ + cluoff = vbn % f->clusiz; /* and offset into cluster */ + curvbn = vbn; /* and finally, current vbn */ +} + +/* get a RSTS file and copy it to a specified local file. Transfers in + * binary (block) mode or ascii (record) mode according to the third + * argument. The return value is the count of bytes transferred. + */ + +long getfile (FILE *to, firqb *f, int binary) +{ + long reclen, iocount; + int eor; + char *recp; + + if (f->size == 0) return (0); /* null file, nothing transferred */ + openfile (f); /* set up file transfer */ + totalbytes = 0; + if (binary) { + while ((iocount = seqio (f, iobufsize, rread, iobuf)) != 0) { + fwrite (iobuf, 1, iocount, to); + totalbytes += iocount; + } + } else { + iocount = seqio (f, iobufsize, rread, iobuf); /* do initial buffer fill */ + f->currec = iobuf; /* init current record pointer */ + f->currecsiz = 0; /* no current record size */ + while (TRUE) { + recp = getrec (f, &reclen, &eor, iocount); + if (recp != NULL) { + totalbytes += reclen; + if (reclen) fwrite (recp, 1, reclen, to); + if (eor) { + fputc ('\n', to); +#if (defined(__MSDOS__) && !defined(__unix__)) + totalbytes += 2; +#else + totalbytes++; +#endif + } + } + if (f->currec == NULL) { + if ((iocount = seqio (f, iobufsize, rread, iobuf)) == 0) + break; + else f->currec = iobuf; /* init current record pointer */ + } + } + } + return (totalbytes); +} + +/* extend the currently open file to the specified size, if not already + * that big. + */ + +long extfile (firqb *f, long blocks) +{ + int clus, reoff, clunum; + word re; + + if (sw.debug != NULL) + printf ("extfile(,%ld) from %ld\n", blocks, f->size); + if (f->size >= blocks) return (TRUE); /* already big enough */ + if (f->stat & us_nox) return (FALSE); /* error if contiguous */ + clus = (UP(blocks,f->clusiz) - UP(f->size,f->clusiz)) / f->clusiz; + if (clus == 0) { /* no new clusters needed */ + f->size = blocks; /* so just do it */ + return (TRUE); + } + if (cluoff == 0) reoff = curreoff; + else { + reoff = curreoff + 1; + if (reoff > 6) reoff = 0; /* overflowed current RE */ + } + f->size = UP(f->size,f->clusiz); /* round up to full cluster */ + while (clus > 0) { /* allocate what we need */ + if (reoff == 0) { /* need to start new RE */ + if ((re = getent ()) == 0) return (FALSE); + if (NULLINK(curre)) curre = re; /* this is now current */ + readlk (re); /* read it */ + use(ufdre,k)->ulnk = 1; /* mark it allocated */ + MARKF; + if (lastre) { /* link it to earlier RE */ + readlk (lastre); + use(ufdre,k)->ulnk = re; + } else { /* link first RE to NE */ + readlk (f->nlink); + use(ufdne,k)->uar = re; + f->rlink = re; /* record in firqb also */ + } + MARKF; + lastre = re; /* this is now the last RE */ + readlk (re); /* read the new RE */ + } + if ((clunum = getclu (f->clusiz, f->clusiz)) == 0) return (FALSE); + use(ufdre,k)->uent[reoff] = clunum; + MARKF; + f->size += f->clusiz; /* adjust file size */ + reoff++; + if (reoff > 6) reoff = 0; /* overflowed current RE */ + clus--; /* any clusters left to do? */ + } + f->size = blocks; /* it worked, all done */ + readlk (curre); /* make sure we have the right RE */ + return (TRUE); /* return with success */ +} + +/* read a local file and put it to a specified RSTS file. Transfers in + * binary (block) mode or ascii (record) mode according to the third + * argument. The return value is the count of bytes transferred if the + * copy completed, or the negative of what was transferred if the transfer + * did not finish (i.e., due to no room on the disk). + */ + +/* writefile is a support routine that writes some number of bytes from iobuf + * to the rsts output file. It returns FALSE if the write did not finish, e.g., + * due to lack of disk space. + */ + +long writefile (firqb *f, long count) +{ + long offset, blocks, wcount; + + if (sw.debug != NULL) printf ("writefile(,%ld)\n", count); + count = UP(count,BLKSIZE); + offset = 0; + blocks = (totalbytes + count) / BLKSIZE; + extfile (f, blocks); /* extend if needed */ + while (count) { + wcount = seqio (f, count, rwrite, iobuf + offset); + if (wcount == 0) { + totalbytes = -totalbytes; + return (FALSE); + } + offset += wcount; + totalbytes += wcount; + count -= wcount; + } + return (TRUE); /* write suceeded */ +} + +long putfile (FILE *from, firqb *f, int binary) +{ + long blocks, wcount, iocount, iocount2, adjust; + long oldsize, offset; + long ilen, llen; + char *iptr, *eol; + ufdne *n; + ufdae *a; + + openfile (f); /* set up file transfer */ + totalbytes = 0; + if (binary) { + while ((iocount = fread (iobuf, 1, iobufsize, from)) != 0) { + iocount2 = UP(iocount, BLKSIZE); + adjust = iocount2 - iocount; + if (adjust) memset (iobuf + iocount, 0, adjust); + if (!writefile (f, iocount2)) break; + if (adjust) { + totalbytes -= adjust; + break; /* short read, done with file */ + } + } + } else { + iptr = iobuf; /* start getting lines at the start */ + ilen = iobufsize + 2; /* use all including 2 extra bytes */ + for ( ; ; ) { + if (fgets (iptr, ilen, from) == NULL) break; + llen = strlen (iptr); /* get length of this line */ + eol = iptr + llen; /* point to terminator */ + if (*--eol == '\n') { /* if we got a complete line */ + if (*(eol - 1) == '\r') { /* terminator = cr-lf? */ + eol++; /* next line starts here */ + } else { /* only \n at eol */ + *eol++ = '\r'; /* put in the cr */ + *eol++ = '\n'; /* and overwrite null with lf */ + llen ++; /* account for cr */ + } + } else eol++; /* skip to end of data */ + iptr = eol; /* advance read ptr */ + ilen -= llen; /* compute space left */ + if (ilen <= 2) { /* full buffer */ + if (!writefile (f, iobufsize)) { + ilen = 0; /* don't write more */ + break; /* quit this file */ + } + iptr = iobuf; /* reinit pointer */ + ilen = 2 - ilen; /* # bytes to move */ + eol = iobuf + iobufsize; /* move from here */ + for ( ; ilen > 0; ilen--) *iptr++ = *eol++; + ilen = iobufsize + 2 - (iptr - iobuf); + } + } + ilen = iptr - iobuf; /* get amount buffered */ + adjust = UP(ilen,BLKSIZE) - ilen; /* get amount to pad */ + if (adjust) memset (iptr, 0, adjust); /* do it */ + iptr += adjust; /* point past it */ + if (iptr != iobuf) writefile (f, iptr - iobuf); /* write pending data */ + totalbytes -= adjust; /* don't report pad */ + } + readlk (f->alink); /* read file's AE */ + a = use(ufdae,k); + oldsize = a->usiz; /* get old file size */ + if (a->urts[0] == 0) oldsize += a->urts[1] >> 16; + if (f->size != oldsize ) { /* size changed */ + if (f->size < oldsize) rabort(INTERNAL); /* can't shrink */ + updqb (f, UP(f->size,f->clusiz) - UP(oldsize,f->clusiz)); + a->usiz = f->size & 0xffff; + MARKF; + if (f->size >> 16) { /* large file */ + a->urts[1] = f->size >> 16; + if ((oldsize >> 16) == 0) { /* it was small */ + if (a->urts[0]) { + printf ("Warning - RTS name cleared for large file "); + printcurname (f); + printf ("\n"); + a->urts[0] = 0; + } + readlk (f->nlink); + n = use(ufdne,k); + if (n->uprot & up_run) { + n->uprot &= ~up_run; + MARKF; + printf ("Warning - runnable protection bit cleared for large file "); + printcurname (f); + printf ("\n"); + } + } + } + } + return (totalbytes); +} + +/* return TRUE if the filename has an extension that suggests it's a text + * file, and FALSE otherwise. + */ + +const char textlist[][4] = + { "txt", "lst", "map", "sid", "log", "lis", + "rno", "doc", "mem", "bas", "b2s", "mac", + "for", "ftn", "fth", "cbl", "dbl", "com", + "cmd", "bat", "tec", "ctl", "odl", "ps ", + "c ", "h ", "ps", "c", "h", "src", + "alg", "" }; + +int textfile (char *name) +{ + char *p; + int i; + + p = strchr (name, '.'); + if (p == NULL) return (FALSE); /* no extension */ + p++; /* skip past the dot */ + for (i = 0; textlist[i][0] != '\0'; i++) + if (strcmp (textlist[i], p) == 0) return (TRUE); + return (FALSE); +} diff --git a/extracters/rstsflx/fileio.h b/extracters/rstsflx/fileio.h new file mode 100644 index 0000000..d26a0fe --- /dev/null +++ b/extracters/rstsflx/fileio.h @@ -0,0 +1,25 @@ +extern long seqio(firqb * f , long iolen , iohandler io , void * buffer); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void openfile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void initrandom(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void fileseek(firqb * f , long vbn); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern long getfile(FILE * to , firqb * f , int binary); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern long extfile(firqb * f , long blocks); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern long writefile(firqb * f , long count); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern long putfile(FILE * from , firqb * f , int binary); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int textfile(char * name); diff --git a/extracters/rstsflx/filename.c b/extracters/rstsflx/filename.c new file mode 100644 index 0000000..64e5245 --- /dev/null +++ b/extracters/rstsflx/filename.c @@ -0,0 +1,309 @@ +/* subroutines to handle rsts file name conversion and file spec parse */ + +#include +#include +#include +#include +#include + +#include "flx.h" +#include "filename.h" +#include "fldef.h" + +#define isr50(c) (isalnum (c) || (c) == ' ' || (c) == '?' || (c) == '*') + +const char *parsename (const char *p, firqb *out) /* parse the name part of a spec */ +{ + int n; + + for (n = 0; n < 6; n++) out->name[n] = ' '; + out->name[6] = '\0'; /* put in terminator */ + if (isr50(*p)) { /* name present */ + n = 0; + while (isr50(*p)) { + if (*p == ' ') { /* skip blanks */ + p++; + continue; + } + out->flags |= f_name; + if (*p == '*') { + if (n < 6) { + out->name[n++] = '?'; + out->flags |= f_namw; + } else p++; + } else { + if (n < 6) out->name[n++] = tolower (*p); + if (*p++ == '?') out->flags |= f_namw; + } + } + } + return (p); +} + +const char *parsenameext (const char *p, firqb *out) /* parse the name.ext part of a spec */ +{ + int n; + + for (n = 0; n < NAMELEN - 1; n++) out->name[n] = ' '; + p = parsename (p, out); /* parse the name part */ + out->name[6] = '.'; + out->name[NAMELEN - 1] = '\0'; /* put in terminator */ + if (*p == '.') { /* extension present */ + p++; + out->flags |= f_ext; + if (isr50(*p)) { + n = 0; + while (isr50(*p)) { + if (*p == ' ') { /* skip blanks */ + p++; + continue; + } + if (*p == '*') { + if (n < 3) { + out->name[7 + n++] = '?'; + out->flags |= f_extw; + } else p++; + } else { + if (n < 3) out->name[7 + n++] = tolower (*p); + if (*p++ == '?') out->flags |= f_extw; + } + } + } + } + return (p); +} + +int parse (const char *p, firqb *out) /* returns FALSE if error, TRUE if ok */ +{ + char *pp; + + out->proj = 0; + out->prog = 0; + out->flags = 0; + if (*p == '[' || *p == '(' || *p == '/') { /* PPN first */ + p++; + out->flags |= f_ppn; /* flag PPN present */ + if (*p == '*') { /* wild proj */ + p++; + out->proj = 255; + out->flags |= f_ppnw; + } else { + out->proj = strtoul (p, &pp, 10); + if (pp == p || out->proj > 254) return (FALSE); + p = pp; + } + if (*p != ',' && *p != '/') return (FALSE); + p++; + if (*p == '*') { /* wild prog */ + p++; + out->prog = 255; + out->flags |= f_ppnw; + } else { + out->prog = strtoul (p, &pp, 10); + if (pp == p || out->prog > 254) return (FALSE); + p = pp; + } + if (out->proj == 0 && out->prog == 0) return (FALSE); + if (*p != ']' && *p != ')' && + *p != '/' && *p != '\0') return (FALSE); + if (*p != '\0') p++; + } else switch (*p) { /* see if special PPN char */ + case '$': + out->proj = 1; /* supply [1,2] */ + out->prog = 2; + out->flags |= f_ppn; /* indicate PPN present */ + p++; /* skip that char */ + break; + case '!': + out->proj = 1; /* supply [1,3] */ + out->prog = 3; + out->flags |= f_ppn; /* indicate PPN present */ + p++; /* skip that char */ + break; + case '%': + out->proj = 1; /* supply [1,4] */ + out->prog = 4; + out->flags |= f_ppn; /* indicate PPN present */ + p++; /* skip that char */ + break; + case '&': + out->proj = 1; /* supply [1,5] */ + out->prog = 5; + out->flags |= f_ppn; /* indicate PPN present */ + p++; /* skip that char */ + break; + + default: /* no PPN supplied */ + out->proj = 1; /* supply default of [1,2] */ + out->prog = 2; /* don't set f_ppn flag */ + } + p = parsenameext (p, out); + if (*p == '<') { /* protection code present */ + p++; + out->flags |= f_prot; + out->newprot = strtoul (p, &pp, 10); + if (pp == p) return (FALSE); + p = pp; + if (*p++ != '>') return (FALSE); + } + return (*p == '\0'); /* success if all was parsed */ +} + +static const char r50table[] = " abcdefghijklmnopqrstuvwxyz$.?0123456789:"; + +char *r50toascii (word16 r50, char *string, int space) +{ + int t, c, pos; + + pos = 03100; + for (t = 0; t<3; t++) { + c = r50 / pos; + if (c || space) *string++ = r50table[c]; + r50 %= pos; + pos /= 050; + } + *string = '\0'; /* put in string terminator */ + return (string); +} + +char *r50toascii2 (word16 r50[], char *string, int space) +{ + string = r50toascii (r50[0], string, space); + return (r50toascii (r50[1], string, space)); +} + +void r50filename (word16 r50[], char *name, int space) +{ + name = r50toascii2 (r50, name, space); + *name++ = '.'; + name = r50toascii (r50[2], name, space); +} + +void printfqbppn (const firqb *f) +{ + if (f->proj == 255) printf ("[*,"); + else printf ("[%d,", f->proj); + if (f->prog == 255) printf ("*]"); + else printf ("%d]", f->prog); +} + +void printfqbname (const firqb *f) +{ + int n; + + printfqbppn (f); + for (n = 0; n < NAMELEN - 1; n++) + if (f->name[n] != ' ') putchar (f->name[n]); +} + +void printcurname (const firqb *f) +{ + if (f->stat & us_ufd) + { + if (f->cproj == 255) + printf ("[*,*]"); + else if (f->cprog == 255) + printf ("[%d,*]", f->cproj); + else printf ("[%d,%d]", f->cproj, f->cprog); + } + else printf ("[%d,%d]%s", f->cproj, f->cprog, f->cname); +} + +/* merge a native (unix or dos) input filespec or RSTS name.ext with a + * (possibly wild) rsts output file spec to produce the specific output + * filename as a 3-word rad50 value. If the third argument is TRUE, then + * the last directory element in the input filename path must be numeric, + * and is used to set the current PPN fields in the output FIRQB. + */ +void mergename (char *iname, firqb *oname, int tree) +{ + int n, spflag; + firqb inf; + char c; + char *in1, *in2; + char tname[FILENAME_MAX]; + int ppn; + + if ((in1 = strrchr (iname, '/')) != NULL) in1++; + else in1 = iname; + if ((in2 = strrchr (in1, '\\')) != NULL) in1 = in2 + 1; + inf.flags = 0; /* clear parse flags */ + if (*(parsenameext (in1, &inf)) != '\0' /* see if we can parse that */ + || (inf.flags & F_WILD)) /* it should not have * or ? */ + memcpy (inf.name, "xxxxxx.xxx", NAMELEN); /* use xxx if bad name */ + oname->cname[6] = '.'; /* make sure . is in */ + spflag = FALSE; /* no spaces yet */ + for (n = 0; n < NAMELEN - 1; n++) { + if (n == 6) { + spflag = FALSE; /* no spaces yet in ext */ + continue; /* skip the '.' separator */ + } + c = oname->name[n]; /* start with output spec */ + if (c == '?' && !spflag) + c = inf.name[n]; /* use input if output wild */ + if (c == ' ') spflag = TRUE; /* stop if we find a space */ + if (spflag) c = ' '; /* force spaces after space */ + oname->cname[n] = c; /* store result */ + } + oname->cname[NAMELEN - 1] = '\0'; /* ensure terminator */ + if (tree) { + n = in1 - iname; /* get offset to name part */ + if (n) n--; /* now to the / */ + else { + oname->cproj = oname->cprog = 0; /* can't set PPN from iname */ + return; + } + strcpy (tname, iname); /* copy the name */ + tname[n] = '\0'; /* chop off directory part */ + if ((in1 = strrchr (tname, '/')) != NULL) in1++; + else in1 = tname; + if ((in2 = strrchr (in1, '\\')) != NULL) in1 = in2 + 1; + ppn = strtoul (in1, &in2, 10); /* convert to decimal */ + if (*in2 != '\0') ppn = 0; /* check for error */ + if (oname->proj == 255) { + if (strlen (in1) < 4) ppn = 0; + oname->cproj = ppn / 1000; /* proj = first digits */ + } else oname->cproj = oname->proj; + if (oname->prog == 255) + oname->cprog = ppn % 1000; + else oname->cprog = oname->prog; + if (oname->cproj > 254 || oname->cprog > 254) + oname->cproj = oname->cprog = 0; + } + return; +} + +/* routines to convert ascii names to rad50. These assume that the name + * is valid rad50, i.e., letters and digits only. Special case: for the + * parsing of RTS names, '.' is also accepted as a rad50 character. + * Any non-rad50 character is treated as space, i.e., rad50 0. + */ + +word cvtr50 (const char *in) +{ + int mul, r50, n; + + for (r50 = 0, mul = 03100, n = 0; n < 3; in++, mul /= 050, n++) { + if (isdigit (*in)) r50 += (*in - '0' + 036) * mul; + else if (isalpha (*in)) r50 += (tolower (*in) - 'a' + 001) * mul; + else if (*in == '.') r50 += 034 * mul; + } + return (r50); +} + +/* convert 6-character name */ + +void cvtnametor50 (const char *in, word16 *out) +{ + out[0] = cvtr50 (in); + out[1] = cvtr50 (in + 3); +} + +/* convert name.ext */ + +void cvtnameexttor50 (const char *in, word16 *out) +{ + cvtnametor50 (in, out); + out[2] = cvtr50 (in + 7); /* skip the "." */ +} + diff --git a/extracters/rstsflx/filename.h b/extracters/rstsflx/filename.h new file mode 100644 index 0000000..1c702f1 --- /dev/null +++ b/extracters/rstsflx/filename.h @@ -0,0 +1,39 @@ +extern const char * parsename(const char * p , firqb * out); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern const char * parsenameext(const char * p , firqb * out); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int parse(const char * p , firqb * out); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern char * r50toascii(word16 r50 , char * string , int space); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern char * r50toascii2(word16 r50[] , char * string , int space); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void r50filename(word16 r50[] , char * name , int space); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void printfqbppn(const firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void printfqbname(const firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void printcurname(const firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void mergename(char * iname , firqb * oname , int tree); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern word cvtr50(const char * in); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void cvtnametor50(const char * in , word16 * out); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void cvtnameexttor50(const char * in , word16 * out); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ diff --git a/extracters/rstsflx/fip.c b/extracters/rstsflx/fip.c new file mode 100644 index 0000000..2462120 --- /dev/null +++ b/extracters/rstsflx/fip.c @@ -0,0 +1,1544 @@ +/* rsts file processing subroutines */ + +#include +#include +#include + +#include "flx.h" +#include "fldef.h" +#include "fip.h" +#include "diskio.h" +#include "rtime.h" +#include "filename.h" + +byte fibuf[BLKSIZE]; /* buffer for directories */ +byte *sattbufp; /* pointer to SATT buffer */ +int sattsize; /* size of SATT.SYS file in bytes */ +long pcns; /* number of pack clusters on this disk */ +long sattlbn; /* start LBN of SATT */ +long satptr; /* current allocation pointer (PCN) */ +int womsat; /* TRUE if SATT needs to be written back */ +long fiblk; /* current block in FIBUF */ +int fiblkw; /* TRUE if FIBUF needs to be written back */ + +void fbwrite (void) /* write current block from fibuf */ +{ + rwrite (fiblk, BLKSIZE, fibuf); + fiblkw = FALSE; +} + +void checkwrite (void) +{ + if (fiblkw) fbwrite (); +} + +void fbread (long block) /* read block into fibuf if needed */ +{ + if (fiblk != block) + { + checkwrite (); + rread (block, BLKSIZE, fibuf); + fiblk = block; + } +} + +void readdcn (long dcn) +{ + fbread (dcntolbn(dcn)); +} + +long i,k; /* current directory entry pointers */ + +/* ulk unpacks a rsts directory link, returning the LBN in i and + * the byte offset in k. + * it returns 0 if ok, BADLINK if not. bad" means block offset out + * of range (should be less than cluster size), cluster number 7, + * or byte offset 760 octal (belongs to fdcm). + */ + +int ulk (word link) +{ + int clu, blk; + + k = (link & ul_eno); /* k = byte offset to entry */ + clu = (link & ul_clo) >> sl_clo; /* cluster number */ + blk = (link & ul_blo) >> sl_blo; /* block in cluster */ + if (sw.debug != NULL) + printf ("ulk(%o), k=%lo, clu=%d, blk=%d, clumap=%d\n", + link, k, clu, blk, clumap->uent[clu]); + if (blk >= clumap->uclus || + clu > 6 || + k == 0760 || + clumap->uent[clu] == 0) + return (BADLINK); + i = blk + dcntolbn(clumap->uent[clu]); /* LBN of entry */ + return (0); /* ok */ +} + +/* readlk reads the directory block pointed to by the supplied link. + * i and k are set as for ulk. If the link is null, this routine + * returns FALSE; otherwise it returns TRUE. readlk2 works similarly, + * but it unconditionally reads what the link points to; thus it can be + * used to read the label blockette of a directory (and readlk cannot!!!) + * readlktbl is similar to readlk, except that it is meant to be called + * when the block currently in fibuf is the GFD name entry link table -- + * which doesn't have a cluster map. curgfd must be set for it to work. + */ + +void readlk2 (word link) +{ + if (ulk (link)) + rabort(CORRUPT); /* unpack the link */ + fbread (i); /* read the directory block */ +} + +int readlk (word link) +{ + if (NULLINK(link)) + return (FALSE); /* reject null link */ + readlk2 (link); /* otherwise read it */ + return (TRUE); +} + +int readlktbl (word link) +{ + if (NULLINK(link)) + return (FALSE); /* null link, exit now */ + if (link & ul_clo) + fbread (curgfd); /* get gfd block with fdcm */ + else + fbread (curgfd + ((link & ul_blo) >> sl_blo)); + return (readlk (link)); /* now do the actual read */ +} + +/* utility routines for getclu */ + +/* both of these scan the satt from "start" through "last", looking + * to allocate a chunk of "clucount" clusters, with clustersize + * "clusiz" (i.e., aligned on "clusiz" boundary) -- both of the latter + * being expressed as a count of pack clusters. + * scanbytes works for clusiz >= 8, where the scan is for whole bytes of + * zero. scanbits works for smaller clusiz values, and looks for fields + * of zero bits. In both cases, if a spot is found, it is allocated, + * satptr is set to the next cluster after the allocated area, and the + * start DCN returned; zero means failure (and SATT and satptr are + * unchanged). + */ + +long scanbytes (long start, long last, int clusiz, long clucount) +{ + long clusizbyt, clu, cluoff, clucountbyt, found; + byte *s; + + clusizbyt = clusiz / 8; /* byte alignment needed */ + clucountbyt = clucount / 8; /* allocation size in bytes */ + s = sattbufp + (start / 8); /* byte pointer to start of scan */ + for (clu = start; clu <= last; clu += clusiz, s+= clusizbyt) + { + if (*s != 0) + continue; /* if not free, keep scanning */ + found = TRUE; /* found something... */ + for (cluoff = 1; cluoff < clucountbyt; cluoff++) + if (*(s + cluoff) != 0) + { + cluoff = DOWN(cluoff,clusizbyt); + s += cluoff; + clu += cluoff * 8; + found = FALSE; /* never mind... */ + break; + } + if (!found) + continue; /* keep going if no luck */ + for (cluoff = 0; cluoff < clucountbyt; cluoff++) *s++ = 0xff; + satptr = clu + clucount; /* update satptr */ + MARKS; /* SATT is dirty */ + return (pcntodcn(clu)); + } + return (0); /* nothing found */ +} + +long scanbits (long start, long last, int clusiz, long clucount) +{ + long mask, mask1, mask2, cluoff, clu, found; + byte *s, *s2; + + clucount /= clusiz; /* make it count of file clusters */ + mask1 = (1 << clusiz) - 1; /* mask to match on */ + s = sattbufp + start / 8; /* byte pointer to start of scan */ + mask = mask1 << (start % 8); /* form starting bit field */ + for (clu = start; clu <= last; clu += clusiz) + { + if ((*s & mask) != 0) /* not all free, keep looking... */ + { + if (mask < 0x80) + mask <<= clusiz; + else + { + mask = mask1; + s++; + } + continue; + } + found = TRUE; /* found something... */ + mask2 = mask; /* now look for contiguous piece */ + s2 = s; + for (cluoff = 0; cluoff < clucount; cluoff++) + { + if ((*s2 & mask2) != 0) /* not all free, keep looking... */ + { + clu += cluoff; + if (mask2 < 0x80) + mask2 <<= clusiz; + else + { + mask2 = mask1; + s2++; + } + s = s2; + mask = mask2; /* continue just past here */ + found = FALSE; /* never mind... */ + break; + } + if (mask2 < 0x80) + mask2 <<= clusiz; + else + { + mask2 = mask1; + s2++; + } + } + if (!found) + continue; /* keep going if no luck */ + for (cluoff = 0; cluoff < clucount; cluoff++) + { + *s |= mask; + if (mask < 0x80) + mask <<= clusiz; + else + { + mask = mask1; + s++; + } + } + satptr = clu + clucount; /* update satptr */ + MARKS; /* SATT is dirty */ + return (pcntodcn(clu)); + } + return (0); /* nothing found */ +} + +/* getclu allocates clusters of the specified size, for a file of specified + * total size. before calling this routine, the pack should be mounted + * read/write to ensure a rebuild is forced if things abort after this point. + * If there is no room, zero is returned. Otherwise the starting DCN + * is returned. + * A single allocation is done, so the "size" argument should be equal to + * the clustersize unless a contiguous allocation is being done. + */ + +int pcs; /* pack clustersize */ + +long getclu (int clusiz, long size) +{ + long start, alloc, clucount; + + if (sw.debug != NULL) + printf ("getclu(%d,%ld)\n", clusiz, size); + if (sattsize == 0) + rabort(INTERNAL); + clusiz /= pcs; /* fcs as count of clusters */ + clucount = size / pcs; /* ditto for total size wanted */ + if (clusiz <= 0) + rabort(INTERNAL); + if (clucount <= 0) + rabort(INTERNAL); + start = UP(satptr,clusiz); /* align start of scan */ + if (clusiz < 8) /* scanning bitwise */ + { + alloc = scanbits (start, pcns - clucount, clusiz, clucount); + if (alloc) + return (alloc); /* found it in rest of satt */ + return (scanbits (0, start - clusiz, clusiz, clucount)); + } + else /* scanning whole bytes */ + { + alloc = scanbytes (start, pcns - clucount, clusiz, clucount); + if (alloc) + return (alloc); /* found it in rest of satt */ + return (scanbytes (0, start - clusiz, clusiz, clucount)); + } +} + +/* retclu returns a single cluster. "pos" is the DCN of the cluster, + * (i.e., as found in retrieval entries); "clusiz" is the file clustersize. + */ + +void retclu (long pos, int clusiz) +{ + long m, n; + byte *s; + + if (sw.debug != NULL) + printf ("retclu(%lo,%d)\n", pos, clusiz); + if (sattsize == 0) + rabort(INTERNAL); + pos = dcntopcn(pos); /* convert to pcn */ + clusiz /= pcs; /* fcs as count of clusters */ + if (clusiz <= 0) + rabort(INTERNAL); + s = sattbufp + pos / 8; /* byte pointer to start of cluster */ + if (clusiz < 8) /* scanning bitwise */ + { + m = (1 << clusiz) - 1; /* mask to match on */ + m <<= (pos % 8); /* form starting bit field */ + *s &= ~m; /* free this cluster */ + } + else /* scanning whole bytes */ + { + clusiz /= 8; /* change to count of bytes to free */ + for (n = 0; n < clusiz; n++) *s++ = 0; + } + MARKS; /* mark SATT dirty */ +} + +int pflags; /* pack flags */ +int plevel; /* pack structure revision level */ +long mfddcn; /* DCN of start of MFD */ +long mfdlbn; /* LBN of start of MFD */ +char pname[7]; /* pack ID in ascii */ + +void readlabel (void) +{ + packlabel *p; + + readdcn (1); /* get pack label */ + p = use(packlabel,0); + pcs = p->ppcs; /* get PCS */ + pflags = p->pstat; /* get pack flags */ + if (pflags & uc_new) + { + plevel = p->plvl; /* get RDS level */ + mfddcn = p->mdcn; /* get MFD pointer */ + } + else + { + plevel = 0; /* set to 0 if old pack */ + mfddcn = 1; /* MFD is at 1 for old format */ + } + mfdlbn = dcntolbn(mfddcn); /* for convenience, LBN also */ + r50toascii2 (p->pckid, pname, FALSE); /* translate pack ID */ +} + +long curgfd; /* LBN of start of current GFD */ +long curqblbn; /* LBN where current ppn quota block lives */ +word curqb; /* and link pointing to it */ +int entptr; /* current directory entry allocation pointer */ +word nextlink; /* link to next file */ +word prevlink; /* link to prececessor of file */ +word nextppnlink; /* link to next PPN for RDS 0 */ +word prevppnlink; /* link to prececessor of PPN for RDS 0*/ + +void setppn (firqb *f, int proj, int prog, word ppnent, int which) +{ + f->cproj = proj; + f->cprog = prog; + curqb = 0; /* haven't found quota block yet */ + if (which == gfddcntbl) /* looking for UFD */ + { + ppnent = dcntolbn(ppnent); + fbread (ppnent); /* read it */ + prevlink = 0; + nextlink = use(ufdlabel,0)->ulnk; + entptr = sizeof (ufdlabel); + } + else readlktbl (ppnent); +} + +word nextppn (firqb *f, int which) /* find next ppn */ +{ + int firstproj, firstprog, lastproj, lastprog; + int j, n; + word ppnent; + word curlink; + gfdne *d; + + nextlink = 0; /* assume nothing found */ + if (plevel == RDS0) /* if old pack */ + { + readlktbl (nextppnlink); /* read next MFD NE */ + while (!NULLINK(nextppnlink)) + { + readlk (nextppnlink); /* read it */ + curlink = nextppnlink; + d = use(gfdne,k); + nextppnlink = d->ulnk; /* point to next one */ + if ((d->ustat & (us_del | us_ufd)) == us_ufd + && (f->proj == 255 || f->proj == (d->unam[0] >> 8)) + && (f->prog == 255 || f->prog == (d->unam[0] & 0xff))) + { + f->cproj = d->unam[0] >> 8; + f->cprog = d->unam[0] & 0xff; + if (which == gfddcntbl) /* looking for UFD */ + { + ppnent = dcntolbn(d->uar); + if (ppnent == 0) + /* PPN without UFD, skip */ + continue; + fbread (ppnent); /* read it */ + prevlink = 0; + nextlink = use(ufdlabel,0)->ulnk; + entptr = sizeof (ufdlabel); + } + else ppnent = curlink; + return (ppnent); + } + prevppnlink = curlink; + } + return (0); + } + firstproj = f->cproj; + if (f->proj == 255) lastproj = 254; + else lastproj = f->proj; + if (f->prog == 255) + { + firstprog = 0; + lastprog = 254; + } + else firstprog = lastprog = f->prog; + n = f->cprog + 1; /* next prog number to try */ + for (j = firstproj; j <= lastproj; j++) + { + fbread (mfdlbn + gfddcntbl); + if ((curgfd = dcntolbn(fibufw[j])) == 0) + continue; + fbread (curgfd + which); + for ( ; n <= lastprog; n++) + { + if ((ppnent = fibufw[n]) == 0) + continue; + setppn (f, j, n, ppnent, which); + return (ppnent); + } + n = firstprog; /* next project, start at firstprog */ + } + return (0); +} + +word initfilescan (firqb *f, int which) /* setup file scan to the beginning */ +{ + int firstproj, firstprog, lastproj, lastprog; + int j, n; + word ppnent; + + nextlink = prevlink = 0; /* assume nothing found */ + if (plevel == RDS0) /* if old pack */ + { + prevppnlink = 0; + curgfd = mfdlbn; /* pretent MFD is also GFD */ + fbread (mfdlbn); /* read start of MFD */ + nextppnlink = use(packlabel,0)->ulnk; + return (nextppn (f, which)); /* and look for first match */ + } + if ((f->flags & f_name) == 0) + { + f->cproj = f->proj; + f->cprog = f->prog; + if (f->proj == 255) + { + fbread (mfdlbn); + return (mfddcn); + } + if (f->prog == 255) + { + fbread (mfdlbn + gfddcntbl); + if ((ppnent = fibufw[f->proj]) == 0) + return (0); + curgfd = dcntolbn (ppnent); + fbread (curgfd); + return (ppnent); + } + firstproj = lastproj = f->proj; + firstprog = lastprog = f->prog; + } + else + { + if (f->proj == 255) + { + firstproj = 0; + lastproj = 254; + } + else firstproj = lastproj = f->proj; + if (f->prog == 255) + { + firstprog = 0; + lastprog = 254; + } + else firstprog = lastprog = f->prog; + } + for (j = firstproj; j <= lastproj; j++) + { + fbread (mfdlbn + gfddcntbl); + if ((curgfd = dcntolbn(fibufw[j])) == 0) + continue; + fbread (curgfd + which); + for (n = firstprog; n <= lastprog; n++) + { + if (n == 0 && j == 0) + continue; + if ((ppnent = fibufw[n]) == 0) + continue; + setppn (f, j, n, ppnent, which); + return (ppnent); + } + } + return (0); +} + +int wmatch (const char *wn, const char *n) /* wildcard match */ +{ + while (*wn != '\0') + { + if (*wn != *n && *wn != '?') + return (FALSE); + wn++; + n++; + } + return (TRUE); +} + +/* nextfileindir looks for a file in the current directory. If found, it + * updates the file informationin the supplied firqb (name, links, status, + * protection code, size, clustersize). + * A return of TRUE means match, FALSE means nothing found. + * Special case: if the filename is null, the indicated director is opened. + * In that case, "prevlink" is set non-zero to indicate that this is the + * only "match" on this directory. "Indicated directory" can be the GFD + * or MFD if the proj and prog were wild. + */ + +int nextfileindir (firqb *f) +{ + ufdne *n; + ufdae *a; + ufdrms1 *r; + int ent; + + if ((f->flags & f_name) == 0) /* null name, open UFD */ + { + if (prevlink) + return (FALSE); + prevlink++; /* return no match next time */ + if (f->prog == 255) + { + if (f->proj == 255) + fbread (mfdlbn); + else + fbread (curgfd); + } + f->stat = us_ufd | us_nok; + f->prot = 63; + f->clusiz = clumap->uclus; + f->size = 0; + for (ent = 0; ent < 7; ent++) + if (clumap->uent[ent]) + f->size += clumap->uclus; + f->rmslink = 0; + f->recfmt = rf_stm; /* default to stream */ + f->eofblk = f->size; + f->eofbyte = 0; + sprintf (f->cname, "%03d%03d.dir", f->cproj, f->cprog); + return (TRUE); + } + while (readlk (nextlink)) /* read next entry, if any */ + { + n = use(ufdne,k); + f->nlink = nextlink; /* save this link */ + nextlink = n->ulnk; /* link to next entry */ + if ((n->ustat & (us_ufd | us_del)) == 0) + { + r50filename (n->unam, f->cname, TRUE); + if (wmatch (f->name, f->cname)) + { + f->stat = n->ustat; + f->prot = n->uprot; + f->rlink = n->uar; + f->alink = n->uaa; + if (!readlk (f->alink)) + rabort(CORRUPT); + a = use(ufdae,k); + f->size = a->usiz; + f->clusiz = a->uclus; + f->rmslink = a->ulnk; + if (a->urts[0] == 0) + f->size += a->urts[1] << 16; + if (NULLINK(f->rmslink)) + { + f->recfmt = rf_stm; /* default to stream */ + f->eofblk = f->size; + f->eofbyte = 0; + } + else + { + readlk (f->rmslink); + r = use(ufdrms1,k); + f->recfmt = r->fa_typ; + f->recsiz = r->fa_rsz; + f->eofblk = ((long)(r->fa_eof[0]) << 16) + r->fa_eof[1]; + f->eofbyte = r->fa_eofb; + if (f->eofbyte == BLKSIZE) + { + f->eofbyte = 0; + f->eofblk++; + } + if ((r->fa_typ & fa_rfm) == rf_vfc) + { + if (NULLINK(r->ulnk)) + f->rechdrsiz = 0; + else + { + readlk(r->ulnk); + f->rechdrsiz = use(ufdrms2,k)->fa_hsz; + } + } + } + return (TRUE); + } + } + prevlink = f->nlink; /* save link to predecessor */ + } + return (FALSE); /* not found */ +} + +/* nextfile looks for the next matching filespec, going across directories + * as needed. If a match is found, it returns TRUE and loads the supplied + * firqb with information about the file. Otherwise, FALSE is returned. + * Special case: if the filename is null, the current UFD is opened. + */ + +int nextfile (firqb *f) /* find next match for this filespec */ +{ + for (;;) + { + if (nextfileindir (f)) + { + return (TRUE); + } + if (nextppn (f, gfddcntbl) == 0) + return (FALSE); + } +} + +int findfile (firqb *f, const char *name) /* find a single file by name */ +{ + parse (name, f); + initfilescan (f, gfddcntbl); + return (nextfile (f)); +} + +int findqb (const firqb *f) /* find quota block for current ppn */ +{ + word link; + ua_quo *a; + + if (plevel < RDS11) + rabort(INTERNAL); + if (curgfd == 0) + rabort(INTERNAL); + fbread (curgfd + gfdatrtbl); /* read attribute link table */ + link = fibufw[f->cprog]; /* fetch appropriate link */ + if (link & ul_clo) fbread (curgfd); /* get gfd block with fdcm */ + else fbread (curgfd + ((link & ul_blo) >> sl_blo)); + if (!readlk (link)) rabort(INTERNAL); /* read dir NE */ + link = use(gfdne,k)->ulnk; /* get link to first attribute */ + while (link) + { + readlk (link); /* read an attribute entry */ + a = use(ua_quo,k); + if (a->uatyp == aa_quo) return (link); /* found it */ + link = a->ulnk; /* follow the link */ + } + rabort(CORRUPT); /* bogus -- no quota block */ + return (0); /* to make the compiler happy */ +} + +void updqb (const firqb *f, long delta) /* adjust quota by delta blocks */ +{ + long quo, savefiblk; + ua_quo *q; + + if (sw.debug != NULL) + printf ("updqb(,%ld), RDS %d.%d\n", + delta, plevel >> 8, plevel & 0xff); + if (plevel < RDS12) + return; /* NOP if not RDS 1.2 */ + if (f->cproj == 0 && f->cprog == 1) + return; /* NOP for [0,1] */ + savefiblk = fiblk; /* remember current block */ + if (curqb == 0) /* if we haven't been here yet */ + { + curqb = findqb (f); /* find it */ + curqblbn = fiblk; /* and remember LBN also */ + } + else + { + fbread (curqblbn); /* read block where it lives */ + ulk (curqb); /* and set up "k" */ + } + q = use(ua_quo,k); /* point to it */ + quo = (q->aq_crm << 16) + q->aq_crl; + quo += delta; /* adjust the usage */ + q->aq_crl = quo & 0xffff; /* update low order */ + q->aq_crm = quo >> 16; /* and high order */ + MARKF; /* mark FIBUF for write */ + fbread (savefiblk); /* restore caller's FIBUF content */ +} + +/* upddlw updates the dlw/dla field; it is called when the file has + * been changed. note that we don't implement date of last access + * recording; this avoids having to write to disks that would otherwise + * only be read. + */ + +void upddlw (const firqb *f) /* update date of last write */ +{ + if (sw.debug != NULL) + printf ("upddlw( )\n"); + if (f->stat & us_ufd) + return; /* nop on directories! */ + if (!readlk (f->alink)) + rabort(INTERNAL); + use(ufdae,k)->udla = curdate (); + MARKF; +} + +/* extdir extends the current directory by one cluster, if possible. + * it returns the DCN of the cluster allocated, if successful, or 0 + * if allocation failed. If it succeeded, all directory clustermaps + * have been updated, and the new cluster has been otherwise set to zero. + * This routine works for any kind of directory, MFD and GFD included. + * On completion, some directory block is in FIBUF. If successful, + * it is the FIRST block of the directory (NOT any of the allocated + * cluster!). + * + * extdir2 either creates the first cluster of a directory or extends + * a directory by one cluster. It is called from extdir (and also + * directly in processing the "init" command). It is passed the clustersize, + * clustermap entry offset, clustermap flags, and directory label data + * to be used. (If a cluster other than first is being allocated, only + * entry offset, flags, and clustersize arguments are used.) The flags + * argument is used to control whether an mfd/gfd vs. a ufd is being + * extended. Since this affects which blocks have to be updated, it + * is important to pass the correct value. + */ + +int extdir2 (int newcm, int clusiz, byte flags, const ufdlabel *newl) +{ + long clu, lbn; /* new cluster and its lbn */ + int cm, off; /* clustermap entry and offset */ + int realclu; /* clustersize for getclu */ + ufdlabel *u; + + if (sw.debug != NULL) + { + printf ("extdir2(%d,%d,%o)\n", newcm, clusiz, flags); + printf (" old map: %03o %03o %06o %06o %06o %06o %06o %06o %06o\n", + clumap->uclus, clumap->uflag, clumap->uent[0], + clumap->uent[1], clumap->uent[2], + clumap->uent[3], clumap->uent[4], + clumap->uent[5], clumap->uent[6]); + } + checkwrite (); /* make sure pending write is done */ + realclu = clusiz; + if (clusiz < pcs) + realclu = pcs; /* for big disks, if pcs > 16 */ + clu = getclu (realclu, realclu); /* get one cluster that size */ + if (clu == 0) + return (FALSE); /* sorry, nothing available */ + lbn = dcntolbn(clu); /* get corresponding start LBN */ + for (cm = 0; cm < newcm; cm++) /* update old clusters, if any */ + { + for (off = 0; off < clusiz; off++) + { + if (cm == 0) /* first cluster needs some checks */ + { + if (off == 0) + continue; /* do this last */ + if ((flags & fd_new) && off <= gfdatrtbl) + continue; /* skip tables */ + } + fbread (dcntolbn(clumap->uent[cm]) + off); + clumap->uent[newcm] = clu; + fbwrite (); /* write updated data */ + } + } + + if (newcm == 0) /* creating the first cluster */ + { + off = 1; /* Assume updating a UFD */ + if (flags & fd_new) + off = gfdatrtbl + 1; /* Adjust if MFD/GFD */ + memset (fibuf, 0, BLKSIZE); /* zero entire block */ + if (flags & fd_new) /* erase table blocks if MFD/GFD */ + { + rwrite (lbn + gfddcntbl, BLKSIZE, fibuf); + rwrite (lbn + gfdatrtbl, BLKSIZE, fibuf); + } + clumap->uclus = clusiz; /* set up fixed fields in cluster map */ + clumap->uflag = flags; /* flags too */ + clumap->uent[0] = clu; /* this is the only cluster */ + } + else + { + /* Special case: if we're creating the second cluster of a + * directory of cluster size 1, then the above code does + * nothing. So we need to read cluster 0 explicitly to get + * the old cluster map. + */ + if (newcm == 1 && clusiz == 1) + { + readdcn (clumap->uent[0]); + clumap->uent[newcm] = clu; + } + memset (fibuf, 0, BLKSIZE - sizeof (fdcm)); + off = 0; /* updating entire new cluster */ + } + for ( ; off < clusiz; off++) + rwrite (lbn + off, BLKSIZE, fibuf); + if (newcm == 0) /* initialize directory label */ + { + fiblk = lbn; /* we're building this block */ + u = use(ufdlabel,0); + memcpy (u, newl, sizeof (ufdlabel)); + } + else + { + fiblk = -1; /* nothing in fibuf */ + readdcn (clumap->uent[0]); /* read first block of dir */ + clumap->uent[newcm] = clu; /* update that last */ + } + fbwrite (); /* write updated data */ + if (sw.debug != NULL) + printf (" new map: %03o %03o %06o %06o %06o %06o %06o %06o %06o\n", + clumap->uclus, clumap->uflag, clumap->uent[0], + clumap->uent[1], clumap->uent[2], + clumap->uent[3], clumap->uent[4], + clumap->uent[5], clumap->uent[6]); + return (clu); /* it worked! return new DCN */ +} + +int extdir (void) /* extend current directory */ +{ + int clusiz; /* directory clustersize */ + int newcm; /* clustermap entry to update */ + + if (sw.debug != NULL) + printf ("extdir()\n"); + if (clumap->uent[6]) + return (0); /* already max length dir */ + for (newcm = 0; ; newcm++) if (clumap->uent[newcm] == 0) break; + clusiz = clumap->uclus; /* get dir clustersize */ + return (extdir2 (newcm, clusiz, clumap->uflag, NULL)); +} + +/* Check if the UFD has been allocated yet for a PPN; if not, allocate + * the first cluster. Returns 0 on failure, or start LBN of the UFD + * otherwise (including if the UFD already exists). + */ + +/* the 255,255 is overwritten with the PPN */ + +ufdlabel newulabel = { 0, 0177777, {0, 0, 0, 0}, {255, 255}, UFD }; + +int allocufd (word dirne, firqb *f) +{ + long savegfdlbn, savelbn; + word dirae; + gfdne *d; + gfdae *a; + + if (sw.debug != NULL) + printf ("allocufd (%d) for [%d,%d]\n", + dirne, f->cproj, f->cprog); + readlk (dirne); /* read the NE */ + d = use(gfdne,k); + if ((savelbn = dcntolbn(d->uar)) == 0) /* no UFD allocated yet */ + { + savegfdlbn = fiblk; /* remember where NE is */ + dirae = d->uaa; /* read AE for PPN */ + if (!readlk (dirae)) + rabort(CORRUPT); + a = use(gfdae,k); + newulabel.lppn[1] = f->cproj; /* fill in the label */ + newulabel.lppn[0] = f->cprog; + if (!extdir2 (0, a->uclus, 0, &newulabel)) + return (0); + savelbn = clumap->uent[0]; /* pick up DCN of UFD */ + fbread (savegfdlbn); /* re-read GFD */ + readlk (dirne); /* and set up for NE */ + use(gfdne,k)->uar = savelbn; /* set DCN of UFD */ + MARKF; + fbread (curgfd + gfddcntbl); /* read UFD pointer block */ + fibufw[f->cprog] = savelbn; /* set the new pointer (DCN) */ + MARKF; + savelbn = dcntolbn(savelbn); /* now make it an LBN */ + entptr = sizeof (ufdlabel); /* initialize the entry allocator */ + } + return (savelbn); +} +/* free entry search runs from entptr through end of directory. entptr + * initially points to start of dir. Anytime an entry is freed, entptr + * should be backed up to that entry if necessary. + * The value returned is the link to the entry, or 0 if none is available. + * The directory is extended if necessary, so 0 will be returned only if + * the disk is full or the directory already has 7 clusters, all full. + * In all cases, fibuf is left with a valid directory block in it. + * If the allocation succeeded, is it the block with the free entry, and + * k has the offset to it. If the allocation failed, it is some unspecified + * block of the directory. + * The entry is completely zeroed, and entptr points to it (not to the + * entry after it). So a second call to getent before any changes are + * made will find the same entry again! + */ + +int getent (void) /* get a free directory blockette */ +{ + int clu, blk, n; /* cluster and block being scanned */ + lword32 *l; + + if (sw.debug != NULL) + printf ("getent()\n"); + readlk2 (entptr); /* read starting point */ + clu = (entptr & ul_clo) >> sl_clo; /* convert entptr */ + blk = (entptr & ul_blo) >> sl_blo; + for (;;) + { + if (*use(lword,k) == 0) /* found an entry */ + { + entptr = k + (clu << sl_clo) + (blk << sl_blo); + readlk2 (entptr); /* read it */ + l = use (lword32, k); /* point to it */ + *l++ = 0; /* and clear it out */ + *l++ = 0; + *l++ = 0; + *l++ = 0; + MARKF; /* and mark it */ + return (entptr); /* this is what we found */ + } + if ((k += sizeof (ufdne)) == BLKSIZE - sizeof (fdcm)) + { + k = 0; + if (++blk < clumap->uclus) + { + if ((clumap->uflag & fd_new) + && clu == 0 && blk == gfddcntbl) + blk = gfdatrtbl + 1; + fbread (dcntolbn(clumap->uent[clu]) + blk); + } + else + { + blk = 0; + if (++clu > 6) return (0); /* we're FULL */ + if (clumap->uent[clu]) + readdcn (clumap->uent[clu]); + else + { + if ((n = extdir ()) != 0) + { + readdcn (n); + entptr = clu << sl_clo; + readlk2 (entptr); /* read it */ + return (entptr); + } + else + return (0); /* no room */ + } + } + } + } +} + +/* Release a directory entry. entptr is updated if necessary. + * The entire entry is cleared out. + */ + +void retent (word link) +{ + lword32 *l; + + if (sw.debug != NULL) printf ("retent(%o)\n", link); + if (!readlk (link)) rabort(INTERNAL); /* read the entry */ + l = use (lword32, k); /* point to it */ + *l++ = 0; /* and mark it as free */ + *l++ = 0; + *l++ = 0; + *l++ = 0; + MARKF; + if ((link & ul_clo) < (entptr & ul_clo) || + ((link & ul_clo) == (entptr & ul_clo) && link < entptr)) + entptr = link; /* move entptr back if needed */ +} + +/* Release the directory entries and allocated clusters for a file. + * This routine does not unlink it from the directory linked list; + * the caller has to do that. Nor does it make any protection checks. + */ + +void retfile (word nlink) +{ + word alink, rlink, rlink2, rmslink, clu, clusiz; + ufdne *n; + ufdae *a; + ufdrms1 *rms; + ufdre *r; + + if (sw.debug != NULL) + printf ("retfile(%o)\n", nlink); + if (!readlk (nlink)) + rabort(INTERNAL); /* read the NE */ + n = use(ufdne,k); + alink = n->uaa; + rlink = n->uar; /* save the links */ + retent (nlink); /* release the NE */ + if (!readlk (alink)) + rabort(CORRUPT); /* read the AE */ + a = use(ufdae,k); + clusiz = a->uclus; /* save fcs */ + rmslink = a->ulnk; + retent (alink); /* release the AE */ + if (!NULLINK(rmslink)) /* if RMS attributes present */ + { + readlk (rmslink); /* read the first */ + rms = use(ufdrms1,k); + if (!NULLINK(rms->ulnk)) + retent (rms->ulnk); + retent (rmslink); + } + while (!NULLINK(rlink)) /* release all RE's */ + { + readlk (rlink); /* read this one */ + r = use(ufdre,k); + rlink2 = r->ulnk; /* save link to next */ + for (clu = 0; clu < 7; clu++) + if (r->uent[clu]) + retclu (r->uent[clu], clusiz); + retent (rlink); /* release the RE */ + rlink = rlink2; + } +} + +void delfile (firqb *f) +{ + readlk2 (prevlink); + use(ufdne,k)->ulnk = nextlink; /* link previous to next */ + MARKF; + retfile (f->nlink); /* deallocate this file */ + updqb (f, -UP(f->size,f->clusiz)); /* adjust quota block */ + f->nlink = 0; /* zap link to former file */ +} + +/* Create a file given a filled-in firqb. The file is initially null, + * unless it is to be contiguous; in that case, it is pre-extended to + * the given size. The rts name to be assigned is also passed. The third + * and fourth arguments are used to supply RMS attribute block data if + * desired; if these are passed as NULL, no attribute blockettes are + * allocated for the file. + * prevlink must be set on entry (normally from an earlier call to nextfile). + * Return is TRUE if success, FALSE if failure. On failure, everything is + * released with the exception of any directory extension that may have been + * done. + * NOTE: this routine assumes that the file does NOT currently exist. + * The caller must verify this. + */ + +int crefile (firqb *f, const word16 *rtsname, + const ufdrms1 *rms1, const ufdrms2 *rms2) +{ + long dcn, startdcn, clu, clucount; + int dcnperfcs, reoff; + word re, prevre; + word rmslink2 = 0; + ufdne *n; + ufdae *a; + ufdrms1 *a1; + ufdrms2 *a2; + + if (sw.debug != NULL) + printf ("crefile()\n"); + if (pflags & uc_top) + { + prevlink = 0; /* link new file first */ + readlk2 (0); /* find current first */ + nextlink = use(ufdlabel,0)->ulnk; /* that will be next */ + } + else + nextlink = 0; /* otherwise no next */ + dcnperfcs = f->clusiz / dcs; /* # dev clu per file clu */ + if ((f->stat & us_nox) == 0) + f->size = 0; /* if not contiguous */ + f->rmslink = 0; + if (rms1 != NULL) /* if allocating attributes */ + { + if (rms2 != NULL) /* two of them! */ + { + if ((rmslink2 = getent ()) == 0) + return (FALSE); + readlk (rmslink2); + if (sw.debug != NULL) + printf ("crefile() rms2 at %o\n", rmslink2); + a2 = use(ufdrms2,k); + memcpy (a2, rms2, sizeof (ufdrms2)); + a2->ulnk = ul_use; /* mark in use */ + MARKF; + } + if ((f->rmslink = getent ()) == 0) + { + if (rmslink2) + retent (rmslink2); + return (FALSE); + } + readlk (f->rmslink); + if (sw.debug != NULL) + printf ("crefile() rms1 at %o\n", f->rmslink); + a1 = use(ufdrms1,k); + memcpy (a1, rms1, sizeof(ufdrms1)); + a1->ulnk = rmslink2 | ul_use; + MARKF; + } + if ((f->alink = getent ()) == 0) + { + if (f->rmslink) + retent (f->rmslink); + if (rmslink2) + retent (rmslink2); + return (FALSE); + } + readlk (f->alink); /* read new AE */ + if (sw.debug != NULL) + printf ("crefile() ae at %o\n", f->alink); + a = use(ufdae,k); + a->ulnk = f->rmslink | ul_use; /* mark in use */ + a->usiz = f->size & 0xffff; /* set low order size */ + a->udla = a->udc = curdate (); /* set dates */ + a->utc = curtime (); /* and creation time */ + a->uclus = f->clusiz; /* and clustersize */ + if (f->size >> 16) /* if large file */ + a->urts[1] = f->size >> 16; /* set high order size */ + else + { + a->urts[0] = rtsname[0]; /* set rts name */ + a->urts[1] = rtsname[1]; + } + MARKF; + if ((f->nlink = getent ()) == 0) /* try to get NE */ + { + if (f->rmslink) retent (f->rmslink); + if (rmslink2) retent (rmslink2); + retent (f->alink); /* no go, release AE */ + return (FALSE); + } + readlk (f->nlink); + if (sw.debug != NULL) + printf ("crefile() ne at %o\n", f->nlink); + n = use(ufdne,k); + cvtnameexttor50 (f->cname, n->unam); /* set file name.ext */ + n->uaa = f->alink; /* link AE to NE */ + n->ustat = f->stat; + n->uprot = f->newprot; /* set status and protection */ + MARKF; + f->rlink = 0; /* no RE's allocated yet */ + if (f->size) /* do contiguous extend */ + { + clucount = UP(f->size,f->clusiz); /* round size up to cluster */ + startdcn = getclu (f->clusiz, clucount); + clucount /= f->clusiz; /* now get cluster count */ + if (startdcn == 0) /* if it failed... */ + { + retfile (f->nlink); /* make file go away */ + return (FALSE); /* and exit */ + } + if (sw.debug != NULL) printf ("crefile() dcn %lo\n", startdcn); + prevre = 0; /* working on first RE */ + reoff = 0; + dcn = startdcn; /* start filling in RE's here */ + for (clu = 0; clu < clucount; clu++) + { + if (reoff == 0) /* time to get another RE */ + { + if ((re = getent ()) == 0) + { + for (clu = 0; clu < clucount; clu++) + retclu (startdcn + (clu * dcnperfcs), f->clusiz); + retfile (f->nlink); + return (FALSE); + } + if (sw.debug != NULL) + printf ("crefile() re at %o\n", re); + if (prevre) + { + readlk (prevre); + use(ufdre,k)->ulnk = re; + } + else + { + readlk (f->nlink); + use(ufdne,k)->uar = re; + f->rlink = re; /* save in firqb */ + } + MARKF; + prevre = re; /* next RE will link to this */ + readlk (re); /* read it */ + } + use(ufdre,k)->uent[reoff++] = dcn; + MARKF; + dcn += dcnperfcs; /* point to next file cluster */ + if (reoff > 6) reoff = 0; /* check for end of RE */ + } + } + readlk (f->nlink); /* read NE again */ + use(ufdne,k)->ulnk = nextlink; /* link it to next */ + MARKF; + readlk2 (prevlink); /* read previous */ + use(ufdne,k)->ulnk = f->nlink; /* link it to new file */ + MARKF; + prevlink = f->nlink; /* this is new previous */ + if (f->size) + updqb (f, UP(f->size,f->clusiz)); + return (TRUE); +} + +/* This routine checks whether a file is protected. It returns TRUE if so. + * It must be called after a call to nextfile or nextfileindir; the + * file information in the firqb is used to control the decisions. + */ + +int protfile (firqb *f) +{ + if (f->stat & us_nok) + { + printf ("File "); + printcurname (f); + printf (" is marked no-delete\n"); + return (TRUE); + } + if (sw.overwrite == NULL && f->prot & up_wpo) + { + printf ("File "); + printcurname (f); + printf (" is protected\n"); + return (TRUE); + } + return (FALSE); +} + +/* Makedir creates a new account. It allocates the GFD, if needed, and + * creates the accounting data for the specified PPN. It does not actually + * allocate a UFD; this will happen when a file is created there, or can + * be done at any time by calling allocufd. + * It returns TRUE on success, FALSE on failure. On failure, an explanatory + * message is also printed. + * The caller must verify that the account does not currently exist. curgfd + * must be set up to point to the gfd, if it exists. "initfilescan" can be + * used to do both these things. + */ + +/* the second (high order) 255 is overwritten with the project number */ + +ufdlabel newglabel = { 1, 0177777, {0, 0, 0, 0}, {255, 255}, GFD }; + +int makedir (firqb *f, int newclu) +{ + gfdne *n; + gfdae *a; + ua_quo *q; + ua_dat *d; + word ne, ae, quo, dat; + int gfdclu; + +/* note: when processing an RDS 0.0 disk, curgfd = mfdlbn = the start lbn + * of the MFD (DCN 1) + */ + + if (sw.debug != NULL) + { + printf ("makedir() for"); + printcurname (f); + printf ("\n"); + } + if (plevel == RDS0 && f->cproj == 0) + { + printf ("Invalid PPN [%d,%d] for RDS 0.0 format disk\n", f->cproj, f->cprog); + return (FALSE); + } + if (curgfd == 0) /* must create GFD */ + { + gfdclu = 4; + if (gfdclu < pcs) + gfdclu = pcs; + if (gfdclu > 16) + gfdclu = 16; + newglabel.lppn[1] = f->cproj; + if (!extdir2 (0, gfdclu, fd_new, &newglabel)) + { + printf ("No room to allocate GFD for [%d,*]\n", f->cproj); + return (FALSE); + } + curgfd = clumap->uent[0]; /* remember its DCN */ + fbread (mfdlbn + gfddcntbl); + fibufw[f->cproj] = curgfd; /* set new GFD pointer */ + MARKF; + curgfd = dcntolbn(curgfd); /* and remember the LBN */ + } + fbread (curgfd); /* read first block of GFD */ + entptr = sizeof (gfdlabel); /* initialize getent search */ + if ((ae = getent ()) == 0) + { + printf ("No room to create [%d,%d]\n", f->cproj, f->cprog); + return (FALSE); + } + readlk (ae); + a = use(gfdae,k); + a->ulnk = ul_use; + a->uclus = newclu; + MARKF; + if (plevel > RDS0) + { + if ((dat = getent ()) == 0) + { + printf ("No room to create [%d,%d]\n", f->cproj, f->cprog); + retent (ae); + return (FALSE); + } + readlk (dat); + d = use(ua_dat,k); + d->ulnk = ul_use; /* mark in use */ + d->uatyp = aa_dat; /* set type code */ + d->at_lti = at_npw; /* in case it's set to /user */ + d->at_cda = d->at_pda = curdate (); + d->at_pti = curtime () | at_nlk; /* set no-lookup flag */ + if (plevel >= RDS12) + d->at_exp = 65535U; + MARKF; + if ((quo = getent ()) == 0) + { + printf ("No room to create [%d,%d]\n", f->cproj, f->cprog); + retent (ae); + retent (dat); + return (FALSE); + } + readlk (quo); + q = use(ua_quo,k); + q->ulnk = dat; /* link to date/time */ + q->uatyp = aa_quo; /* set type code */ + q->aq_lol = 65535U; /* set disk quotas unlimited */ + q->aq_lil = 65535U; + q->aq_lom = 255U; + q->aq_lim = 255U; + MARKF; + } + if ((ne = getent ()) == 0) + { + printf ("No room to create [%d,%d]\n", f->cproj, f->cprog); + retent (ae); + if (plevel > RDS0) + { + retent (dat); + retent (quo); + } + return (FALSE); + } + readlk (ne); + n = use(gfdne,k); + n->unam[0] = (f->cproj << 8) + f->cprog; + n->ustat = us_nok | us_ufd; + n->uprot = 60; + n->uaa = ae; + MARKF; + if (plevel > RDS0) + { + n->ulnk = quo; /* link to quotas */ + fbread (curgfd + gfdatrtbl); /* read GFD table block */ + fibufw[f->cprog] = ne; /* set NE link */ + } + else + { + n->ulnk = nextppnlink; /* link this one to next */ + readlk2 (prevppnlink); /* read previous MFD NE */ + use(gfdne,k)->ulnk = ne; /* and link it to new NE */ + prevppnlink = ne; /* this is previous next time */ + } + MARKF; + return (TRUE); +} + +/* remdir removes a directory, or prints a message explaining why + * it can't. Returns TRUE on success, FALSE on failure. The name entry + * link for the PPN is supplied by the caller. + * + */ + +int remdir (firqb *f, word ne) +{ + word ae, attr, a2; + long savelbn, ufdclu; + gfdne *n; + int j; + + if (f->cproj == 0 && f->cprog == 1) + { + printf ("Directory [0,1] cannot be deleted\n"); + return (FALSE); + } + readlk (ne); /* read its NE */ + n = use(gfdne,k); + if (n->uar) /* it has a UFD */ + { + savelbn = fiblk; + readdcn(n->uar); /* read the UFD */ + if (!NULLINK(use(ufdlabel,0)->ulnk)) + { + printf ("Directory [%d,%d] is not empty\n", + f->cproj, f->cprog); + fbread (savelbn); + return (FALSE); + } + ufdclu = clumap->uclus; /* get clustersize */ + if (ufdclu < pcs) + ufdclu = pcs; /* for big disks */ + for (j = 0; j < 7; j++) + if (clumap->uent[j]) + retclu (clumap->uent[j], ufdclu); + fbread (curgfd + gfddcntbl); /* read UFD pointer table */ + fibufw[f->cprog] = 0; /* no more UFD */ + MARKF; + fbread (savelbn); /* restore GFD block */ + } + ae = n->uaa; + attr = n->ulnk; + if (NULLINK(ae)) + rabort(CORRUPT); + retent (ne); /* release NE */ + retent (ae); /* and AE */ + if (plevel > RDS0) + { + while (!NULLINK (attr)) + { + readlk (attr); + a2 = use(uattr,k)->ulnk; /* remember next link */ + retent (attr); /* release it */ + attr = a2; + } + fbread (curgfd + gfdatrtbl); + fibufw[f->cprog] = 0; /* no more PPN */ + } + else + { + readlk2 (prevppnlink); /* read previous MFD NE */ + use(gfdne,k)->ulnk = nextppnlink; /* and unlink this one */ + } + MARKF; + return (TRUE); +} + +/* Set up the SATT parameters by searching for [0,1]satt.sys if that + * hasn't been done yet. + */ + +void findsat (void) +{ + firqb f; + + if (sattsize) return; /* don't do it twice */ + if (!findfile (&f, "[0,1]satt.sys")) + { + printf ("SATT.SYS not found\n"); + rabort(CORRUPT); + } + if ((f.stat & us_nox) == 0) + { + printf ("SATT.SYS is not contiguous\n"); + rabort(CORRUPT); + } + pcns = (diskblocks - dcs)/ pcs; /* pack size in pack clusters */ + sattsize = UP(pcns,BLKSIZE*8); /* round up to block boundary */ + sattsize /= BLKSIZE * 8; /* and change bits to blocks */ + if (f.size != sattsize) + { + printf ("Expected SATT.SYS size is %d, actual size is %ld\n", + sattsize, f.size); + rabort(CORRUPT); + } + sattsize *= BLKSIZE; /* now size in bytes */ + if ((sattbufp = (byte *) malloc (sattsize)) == NULL) rabort(NOMEM); + readlk (f.rlink); + sattlbn = dcntolbn(use(ufdre,k)->uent[0]); + rread (sattlbn, sattsize, sattbufp); + satptr = 0; /* nothing allocated yet */ +} + +void rmount (void) /* "mount" the rsts pack */ +{ + ropen (DREADMODE); /* open it first */ + readlabel (); /* read and remember label data */ + if (pflags & uc_mnt) + printf ("** warning: disk was not properly dismounted **\n"); + sattsize = 0; /* SATT not looked up yet */ + womsat = FALSE; /* and SATT is clean */ + fiblkw = FALSE; /* FIBUF ditto */ +} + +void rmountrw (void) /* mount the RSTS pack read/write */ +{ + packlabel *p; + + if (sw.debug != NULL) + printf ("rmountrw()\n"); + ropen (DWRITEMODE); /* open it first */ + readlabel (); /* read and remember label data */ + if (pflags & uc_mnt) + rabort(DIRTY); + if ((pflags & uc_ro) && (sw.overwrite == NULL)) + rabort(ROPACK); + sattsize = 0; /* SATT not looked up yet */ + womsat = FALSE; /* and SATT is clean */ + fiblkw = FALSE; /* FIBUF ditto */ + findsat (); /* make sure we know where satt is */ + readdcn (1); /* read the pack label */ + p = use(packlabel,0); + p->pstat |= uc_mnt; /* mark mounted */ + if (plevel >= RDS12) /* if new pack */ + { + p->mntdat = curdate (); /* update timestamps */ + p->mnttim = curtime (); + } + fbwrite (); /* write it back */ +} + +void rumount (void) /* dismount for users of rmount() */ +{ + rclose (); /* close the device */ +} + +void rumountrw (void) /* dismount (no longer read/write) */ +{ + packlabel *p; + + if (sw.debug != NULL) + printf ("rumount()\n"); + readdcn (1); /* read the pack label */ + p = use(packlabel,0); + if ((p->pstat & uc_mnt) == 0) + rabort(INTERNAL); + if (womsat) + rwrite (sattlbn, sattsize, sattbufp); + womsat = FALSE; /* SATT written out if needed */ + free (sattbufp); /* release satt memory copy */ + p->pstat &= ~uc_mnt; /* mark no longer mounted */ + if (plevel >= RDS12) /* if new pack */ + { + p->mntdat = curdate (); /* update timestamps */ + p->mnttim = curtime (); + } + fbwrite (); /* write it back */ + /* this leaves FIBUF clean */ + rumount (); /* now do common dismount */ +} diff --git a/extracters/rstsflx/fip.h b/extracters/rstsflx/fip.h new file mode 100644 index 0000000..6b804b9 --- /dev/null +++ b/extracters/rstsflx/fip.h @@ -0,0 +1,87 @@ +extern void fbwrite(void); +extern void checkwrite(void); +extern void fbread(long block); +extern void readdcn(long dcn); +extern int ulk(word link); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void readlk2(word link); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int readlk(word link); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int readlktbl(word link); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern long scanbytes(long start , long last , int clusiz , long clucount); +extern long scanbits(long start , long last , int clusiz , long clucount); +extern long getclu(int clusiz , long size); +extern void retclu(long pos , int clusiz); +extern void readlabel(void); +extern void setppn(firqb * f , int proj , int prog , word ppnent , int which); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern word nextppn(firqb * f , int which); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern word initfilescan(firqb * f , int which); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int wmatch(const char * wn , const char * n); +extern int nextfileindir(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int nextfile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int findfile(firqb * f , const char * name); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int findqb(const firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void updqb(const firqb * f , long delta); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void upddlw(const firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void upddla(const firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int extdir2(int newcm , int clusiz , byte flags , const ufdlabel * newl); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int extdir(void); +extern int allocufd(word dirne , firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int getent(void); +extern void retent(word link); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void retfile(word nlink); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void delfile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int crefile(firqb * f , const word16 * rtsname, + const ufdrms1 *rms1, const ufdrms2 *rms2); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int protfile(firqb * f); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int makedir(firqb * f , int newclu); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern int remdir(firqb * f , word ne); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void findsat(void); +extern void rmount(void); +extern void rmountrw(void); +extern void rumount(void); +extern void rumountrw(void); diff --git a/extracters/rstsflx/fldef.h b/extracters/rstsflx/fldef.h new file mode 100644 index 0000000..95db67d --- /dev/null +++ b/extracters/rstsflx/fldef.h @@ -0,0 +1,299 @@ +/* fldef.h -- RSTS file system definitions + * + * Derived from fldef.mac, RSTS V10.1. + */ + +/* rad50 constants we need */ +#define MFD 0051064 /* rad50 "MFD" */ +#define GFD 0026264 /* rad50 "GFD" */ +#define UFD 0102064 /* rad50 "UFD" */ +#define TMP 0077430 /* rad50 "TMP" */ + +/* Disk file structure definitions + * Any definitions that apply only for certain disk structure levels + * are marked accordingly. They apply to the rev level stated and those + * after it. + */ + +/* Note: except for the pack label, each of these struct definitions + * must define a struct of size 16 bytes. + */ + +typedef struct { /* Pack label entry */ + word16 ulnk; /* Link if RDS0.0, otherwise 1 */ + int16 fill1; /* Reserved (-1) */ + word16 mdcn; /* Starting DCN of MFD (RDS1.1) */ + word16 plvl; /* Pack revision level */ + word16 ppcs; /* Pack cluster size */ + word16 pstat; /* Pack status/flags */ + word16 pckid[2]; /* Pack ID */ + word16 tapgvn[2]; /* TAP generation-version number (RDS1.1) */ + word16 bckdat; /* Date of last TAP full backup (RDS1.1) */ + word16 bcktim; /* Time of last TAP full backup (RDS1.1) */ + word16 mntdat; /* Date of last mount/dismount (RDS1.2) */ + word16 mnttim; /* Time of last mount/dismount (RDS1.2) */ + byte fill2[BLKSIZE-(14*sizeof(word16))]; /* Reserved */ +} packlabel; + +/* Flag bits in pack label field */ + +#define uc_top 0001000 /* New files first */ +#define uc_dlw 0004000 /* Maintain date of last write */ +#define uc_ro 0010000 /* Read-only pack */ +#define uc_new 0020000 /* "New" pack (RDS1.1) */ +#define uc_pri 0040000 /* Pack is private/system */ +#define uc_mnt 0100000 /* Pack is mounted (dirty) */ + +/* Rev levels */ +#define RDS0 0 /* RDS 0 -- V7.x and before */ +#define RDS11 ((1<<8)+1) /* RDS 1.1 -- V8 */ +#define RDS12 ((1<<8)+2) /* RDS 1.2 -- V9.0 and beyond */ + +/* MFD and GFD are new as of RDS1.1 */ + +typedef struct { /* MFD label entry */ + word16 fill1; /* Reserved (0) */ + int16 fill2; /* Reserved (-1) */ + word16 fill3[3]; /* Reserved (0) */ + word16 malnk; /* Link to pack attributes */ + byte lppn[2]; /* PPN [255,255] */ + word16 lid; /* Identification (RAD50 "MFD") */ +} mfdlabel; + +typedef struct { /* Directory cluster map */ + byte uclus; /* Directory clustersize */ + byte uflag; /* RDS1 GFD/MFD flag in high bit */ + word16 uent[7]; /* The dcn's of the cluster(s) */ +} fdcm; + +#define fd_new 0200 /* flag bit for GFD/MFD in uflag (RDS1.1) */ + +typedef struct { /* GFD label entry */ + word16 fill1; /* Reserved (0) */ + int16 fill2; /* Reserved (-1) */ + word16 fill3[4]; /* Reserved (0) */ + byte lppn[2]; /* PPN [x,255] */ + word16 lid; /* Identification (RAD50 "GFD") */ +} gfdlabel; + +/* mfd/gfd offsets */ +#define gfddcntbl 1 /* block with DCN pointer table */ +#define gfdatrtbl 2 /* block with attribute link table */ + +/* For RDS0, the "GFD NE" and "GFD AE" live in the MFD ([1,1] directory) + * which starts at DCN 1. They are in a linked list, possibly mixed + * with files, in the usual UFD fashion. + */ + +typedef struct { /* GFD name entry */ + word16 ulnk; /* Link to attributes */ + word16 unam[3]; /* PPN and password */ + byte ustat; /* Status byte */ + byte uprot; /* Protection code */ + word16 uacnt; /* Access count */ + word16 uaa; /* Link to accounting entry */ + word16 uar; /* Dcn of start of UFD */ +} gfdne; + +typedef struct { /* GFD accounting entry */ + word16 ulnk; /* Flags */ + word16 mcpu; /* Accum cpu time (LSB) */ + word16 mcon; /* Accum connect time */ + word16 mkct; /* Accum kct's (LSB) */ + word16 mdev; /* Accum device time */ + word16 mmsb; /* Accum cpu time and kct's (MSB's) */ + word16 mdper; /* Disk quota */ + word16 uclus; /* UFD cluster size */ +} gfdae; + +typedef struct { /* UFD label entry */ + word16 ulnk; /* Link to first name block in UFD */ + int16 fill2; /* Reserved (-1) */ + word16 fill3[4]; /* Reserved (0) */ + byte lppn[2]; /* PPN [x,y] */ + word16 lid; /* Identification (RAD50 "UFD") */ +} ufdlabel; + +typedef struct { /* UFD name entry */ + word16 ulnk; /* Link to next name entry */ + word16 unam[3]; /* File name and extension */ + byte ustat; /* Status byte */ + byte uprot; /* Protection code */ + word16 uacnt; /* Access count */ + word16 uaa; /* Link to UFD accounting entry */ + word16 uar; /* Link to retrieval entries */ +} ufdne; + +typedef struct { /* UFD accounting entry */ + word16 ulnk; /* Link to attributes and flags */ + word16 udla; /* Date of last access (or write) */ + word16 usiz; /* File size */ + word16 udc; /* Date of creation */ + word16 utc; /* Time of creation */ + word16 urts[2]; /* File's run-time system name or 0/MSB size */ + word16 uclus; /* File cluster size */ +} ufdae; + +typedef struct { /* UFD first RMS attribute blockette */ + word16 ulnk; /* Link to second attributes blockette */ + word16 fa_typ; /* File type (rfm, org, rat) */ + word16 fa_rsz; /* Record size */ + word16 fa_siz[2]; /* File size (32 bits) */ + word16 fa_eof[2]; /* File EOF block number (32 bits) */ + word16 fa_eofb; /* EOF byte offset */ +} ufdrms1; + +#define fa_rfm 0000007 /* record format field in fa_typ */ +#define rf_udf 0 /* undefined organization */ +#define rf_fix 1 /* fixed length records */ +#define rf_var 2 /* variable length records */ +#define rf_vfc 3 /* variable with fixed control header */ +#define rf_stm 4 /* stream (cr/lf delimiter) */ +#define fa_org 0000070 /* file organization format in fa_typ */ +#define fo_seq 000 /* sequential organization */ +#define fo_rel 020 /* relative organization */ +#define fo_idx 040 /* indexed organization */ +#define fa_rat 0007700 /* record attribute flags */ +#define ra_ftn 0000400 /* fortran carriage control */ +#define ra_imp 0001000 /* implied carriage control */ +#define ra_spn 0004000 /* no-span records */ + +typedef struct { /* UFD second RMS attribute blockette */ + word16 ulnk; /* Link (reserved) */ + byte fa_bkt; /* Bucket size */ + byte fa_hsz; /* Header size */ + word16 fa_msz; /* Max record size */ + word16 fa_ext; /* Default extension amount */ + word16 filler[4]; /* Reserved */ +} ufdrms2; + +/* All directory attributes are new as of RDS1.1 or later */ + +typedef struct { /* MFD/GFD attribute entry */ + word16 ulnk; /* Link to next, flags */ + byte uatyp; /* Type */ + byte uadat[16-3]; /* Data */ +} uattr; + +/* Time of creation flag bit definitions */ + +#define utc_tm 0003777 /* Bits needed for the time field */ +#define utc_ig 0004000 /* IGNORE flag (RDS1.2) */ +#define utc_bk 0010000 /* NOBACKUP flag (RDS1.2) */ + /* Other bits reserved */ + +typedef struct { /* UFD retrieval entry */ + word16 ulnk; /* Link to next retrieval entry */ + word16 uent[7]; /* The dcn's of the cluster(s) */ +} ufdre; + +/* Bit assignments in ustat and f$stat */ + +#define us_out 0001 /* File is 'out of sat' (historical) */ +#define us_plc 0002 /* File is "placed" */ +#define us_wrt 0004 /* Write access given out (not on disk if large files) */ +#define us_upd 0010 /* File open in update mode (not on disk if large files) */ +#define us_nox 0020 /* No file extending allowed (contiguous) */ +#define us_nok 0040 /* No delete and/or rename allowed */ +#define us_ufd 0100 /* Entry is MFD type entry */ +#define us_del 0200 /* File marked for deletion */ + +/* Bit assignments in uprot and f$prot */ + +#define up_rpo 0001 /* Read protect against owner */ +#define up_wpo 0002 /* Write " " " */ +#define up_rpg 0004 /* Read " " group */ +#define up_wpg 0010 /* Write " " " */ +#define up_rpw 0020 /* Read " " world */ +#define up_wpw 0040 /* Write " " " */ +#define up_run 0100 /* Executable file */ +#define up_prv 0200 /* Clear on delete, privileged if executable file */ + +/* Link and flag word fields */ + +#define ul_use 0000001 /* On to ensure entry is "in use" */ +#define ul_bad 0000002 /* Some bad block exists in file */ +#define ul_che 0000004 /* Cache (name entry) or sequential (accting entry) */ +#define ul_cln 0000010 /* Reserved for 'clean' */ +#define ul_eno 0000760 /* Entry offset within block (5 bits) */ +#define ul_clo 0007000 /* Cluster offset within UFD (3 bits) */ +#define ul_blo 0170000 /* Block offset within cluster (4 bits) */ +#define sl_clo 9 /* Shift count for ul_clo field */ +#define sl_blo 12 /* shift count for ul_blo field */ + +#define LINKBITS (ul_eno | ul_clo | ul_blo) /* bits to test for null */ +#define NULLINK(l) (((l) & LINKBITS) == 0) + +/* Account attribute codes */ + +#define aa_quo 1 /* Quotas */ +#define aa_prv 2 /* Privilege masks */ +#define aa_pas 3 /* Password */ +#define aa_dat 4 /* Date/time recording (creation, change, login) */ +#define aa_nam 5 /* User name (RDS1.2) */ +#define aa_qt2 6 /* Quotas part 2 (RDS1.2) */ + +/* Attribute blockette layouts */ + +typedef struct { /* Disk Quota Attribute Blockette */ + word16 ulnk; /* Link to next, flags */ + byte uatyp; /* Type */ + byte aq_djb; /* Detached job quota */ + word16 aq_lol; /* Logged out quota (LSB) */ + word16 aq_lil; /* Logged in quota (LSB) */ + byte aq_lim; /* Logged in quota (MSB) */ + byte aq_lom; /* Logged out quota (MSB) */ + byte aq_rsm; /* Reserved */ + byte aq_crm; /* Current usage (MSB) */ + word16 aq_rsl; /* Reserved */ + word16 aq_crl; /* Current usage (LSB) */ +} ua_quo; + +#define privsz 6 /* number of privilege bytes */ + +typedef struct { /* Privilege mask data */ + word16 ulnk; /* Link to next, flags */ + byte uatyp; /* Type */ + byte fill1; /* Filler */ + byte ap_prv[privsz]; /* Authorized privileges */ + byte fill2[020-privsz-1-3]; /* Filler */ +} ua_prv; + +typedef struct { /* Date/time data */ + word16 ulnk; /* Link to next, flags */ + byte uatyp; /* Type */ + byte at_kb; /* Keyboard of last login */ + word16 at_lda; /* Date of last login */ + word16 at_lti; /* Time of last login */ + word16 at_pda; /* Date of last password16 change */ + word16 at_pti; /* Time of last password change */ + word16 at_cda; /* Date of creation */ + word16 at_exp; /* Expiration date (RDS1.2) */ + /* Account creation time (RDS1.1 only) */ +} ua_dat; + +/* Fields within at_lti */ +#define at_msk 0003777 /* Bits needed for the time field */ +#define at_npw 0004000 /* No password required */ + /* Other bits reserved */ + +/* Fields within at_pti */ +/* at_msk 0003777 * Bits needed for the time field */ +#define at_nlk 0004000 /* Not readable password if set */ +#define at_ndl 0010000 /* No-dialups flag */ +#define at_nnt 0020000 /* No-network flag */ +#define at_nlg 0040000 /* No-login account */ +#define at_cap 0100000 /* Captive account */ + +typedef struct { /* Second quota and date/time block */ + word16 ulnk; /* Link to next, flags */ + byte uatyp; /* Type */ + byte a2_job; /* Total job quota */ + word16 a2_rib; /* RIB quota */ + word16 a2_msg; /* Message limit quota */ + word16 fill1; /* Reserved */ + byte fill2; /* Reserved */ + byte a2_pwf; /* Password failed count */ + word16 a2_ndt; /* Date of Last non-interactive login */ + word16 a2_nti; /* Time of Last non-interactive login */ +} ua_qt2; diff --git a/extracters/rstsflx/flx.dep b/extracters/rstsflx/flx.dep new file mode 100644 index 0000000..1c812ae --- /dev/null +++ b/extracters/rstsflx/flx.dep @@ -0,0 +1,45 @@ +rstsflx.o: rstsflx.c version.h flx.h rstsflx.h platform.h fldef.h \ + scancmd.h diskio.h +fip.o: fip.c flx.h rstsflx.h platform.h fldef.h fip.h diskio.h rtime.h \ + filename.h +rtime.o: rtime.c flx.h rstsflx.h platform.h rtime.h fldef.h +filename.o: filename.c flx.h rstsflx.h platform.h filename.h fldef.h +doget.o: doget.c flx.h rstsflx.h platform.h fldef.h doget.h fip.h \ + filename.h fileio.h scancmd.h +dolist.o: dolist.c flx.h rstsflx.h platform.h fldef.h dolist.h fip.h \ + rtime.h filename.h scancmd.h +doalloc.o: doalloc.c flx.h rstsflx.h platform.h fldef.h doalloc.h fip.h +docomp.o: docomp.c flx.h rstsflx.h platform.h fldef.h docomp.h diskio.h \ + fip.h +dotype.o: dotype.c flx.h rstsflx.h platform.h fldef.h dotype.h fip.h \ + filename.h fileio.h scancmd.h +doput.o: doput.c flx.h rstsflx.h platform.h fldef.h doput.h fip.h \ + filename.h fileio.h scancmd.h +dodump.o: dodump.c flx.h rstsflx.h platform.h fldef.h dodump.h fip.h \ + filename.h diskio.h fileio.h scancmd.h +dodelete.o: dodelete.c flx.h rstsflx.h platform.h fldef.h dodelete.h \ + fip.h filename.h fileio.h scancmd.h +dorename.o: dorename.c flx.h rstsflx.h platform.h fldef.h dorename.h \ + fip.h filename.h fileio.h scancmd.h +dorts.o: dorts.c flx.h rstsflx.h platform.h fldef.h dorts.h fip.h \ + filename.h fileio.h scancmd.h +doprot.o: doprot.c flx.h rstsflx.h platform.h fldef.h doprot.h fip.h \ + filename.h fileio.h scancmd.h +dodir.o: dodir.c flx.h rstsflx.h platform.h fldef.h dodir.h fip.h \ + filename.h +doident.o: doident.c flx.h rstsflx.h platform.h fldef.h doident.h fip.h \ + rtime.h +doinit.o: doinit.c flx.h rstsflx.h platform.h fldef.h doinit.h fip.h \ + diskio.h filename.h +dohook.o: dohook.c flx.h rstsflx.h platform.h fldef.h silfmt.h dohook.h \ + fip.h filename.h fileio.h diskio.h +scancmd.o: scancmd.c flx.h rstsflx.h platform.h fldef.h silfmt.h \ + scancmd.h fip.h diskio.h filename.h doalloc.h doget.h doident.h \ + dolist.h dotype.h dodump.h doput.h dodelete.h dorename.h dorts.h \ + dodir.h doprot.h doinit.h dohook.h docomp.h doclean.h +doclean.o: doclean.c flx.h rstsflx.h platform.h fldef.h diskio.h \ + filename.h doclean.h fip.h rtime.h +fileio.o: fileio.c flx.h rstsflx.h platform.h fldef.h fileio.h filename.h \ + diskio.h fip.h +diskio.o: diskio.c flx.h rstsflx.h platform.h diskio.h absio.h +unxabsio.o: unxabsio.c flx.h rstsflx.h platform.h absio.h diff --git a/extracters/rstsflx/flx.doc b/extracters/rstsflx/flx.doc new file mode 100644 index 0000000000000000000000000000000000000000..b80d3a3d63d3a1b4a3049804cba2d3816c59c49d GIT binary patch literal 123392 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
+0XJlF6J7S9NEWfI+pFL#z>F6oF2sN>QQRK; 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

*Aj2d&UI>7*qeX`8T6CwU;!9IQ&8AO^B1 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≫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%0D!SeNj@A){j@!Blw>r=FdQ|ck8PBwG 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 ZW-m|-*?(6$3IoGgT1i{m!fvM0{{Uub9eV%( literal 0 HcmV?d00001 diff --git a/extracters/rstsflx/linuxabsio.c b/extracters/rstsflx/linuxabsio.c new file mode 100644 index 0000000..fa2be6a --- /dev/null +++ b/extracters/rstsflx/linuxabsio.c @@ -0,0 +1,233 @@ +/* absolute I/O support for Linux + * + * Paul Koning 95.01.05 created + * 99.12.31 updated for Linux (from generic unxabsio.c) + * 00.01.03 added size determination and geometry test + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "flx.h" +#include "absio.h" + +/* this routine is called to scan a supplied container file/device + * name. If the name refers to a real disk, then absflag is set + * and rsize is set to the device size. Otherwise, no action is taken. + * + * More precisely, there are three things this routine may want to do, + * depending on the OS and the name supplied. + * + * If, for the specified name, the absolute I/O routines in this module + * need to be called, then absflag should be set to TRUE, and rsize must + * be set to the size of the device. Otherwise, absflag should be left + * alone (which leaves it FALSE); that way the other absolute I/O routines + * in this module will not be called and standard C I/O is used instead. + * + * If, for the specified name, "fstat" will not return a size (i.e., returns + * zero) then rsize must specify the correct size. This can be set in this + * module, based on OS specific operations, or it can simply be left + * unchanged, in which case it has to be supplied by the user. + * + * For example, in Unix the fstat function doesn't return a size for raw + * devices (it returns zero) but the stdio routines are otherwise perfectly + * suitable. So this routine does NOT set absflag since no special abs I/O + * routines are needed. It does check the return from stat(); if this + * indicates a raw device, it checks that rsize has been supplied and + * complains if not. Note that the code below does not attempt to obtain + * the device size, since there is no portable Unix way of doing this that + * I know of. + */ + +static dev_t rdev; +static int floppy; +static byte trackbuf[BLKSIZE * 10]; +static int curtrack = -1; +static int writecurrent; + +static void makechs_rx50 (int block, int *trk, int *sec) +{ + int t, s; + + t = block / 10; + s = block % 10 + 1; + if (s < 6) s = (s - 1) * 2 + 1; + else s = (s - 5) * 2; + s += t * 2; + while (s > 10) s -= 10; + t++; + if (t == 80) t = 0; /* wrap around last 10 blocks */ + *trk = t; + *sec = s - 1; +} + +static void flushtrack (void) +{ + if (writecurrent) + { + lseek (floppy, curtrack * sizeof (trackbuf), SEEK_SET); + if (write (floppy, trackbuf, sizeof (trackbuf)) != + sizeof (trackbuf)) + doabort (DISKIO, __FILE__, __LINE__); + writecurrent = FALSE; + } +} + +static void gettrack (int track) +{ + if (track != curtrack) + { + flushtrack (); + lseek (floppy, track * sizeof (trackbuf), SEEK_SET); + if (read (floppy, trackbuf, sizeof (trackbuf)) != + sizeof (trackbuf)) + doabort (DISKIO, __FILE__, __LINE__); + curtrack = track; + } +} + +void absname (const char *rname) +{ + struct stat sbuf; + int fd, i = -1; + long size; + struct hd_geometry loc; + + if (stat (rname, &sbuf)) return; /* try to get info about device */ + diskblocks = UP(sbuf.st_size,BLKSIZE) / BLKSIZE; + if (diskblocks == 0) + { + if (S_ISBLK(sbuf.st_mode)) + { + fd = open (rname, O_RDONLY); + if (fd >= 0) + { + i = ioctl (fd, BLKGETSIZE, &size); + if (i >= 0) + diskblocks = size; + i = ioctl (fd, HDIO_GETGEO, &loc); + close (fd); + } + else + diskblocks = rsize; + /* user can always override autoconfigured size */ + if (rsize != 0) + diskblocks = rsize; + if (diskblocks == 0) + { + printf ("Size not specified for RSTS disk %s\n", rname); + exit (EXIT_FAILURE); + } + if (diskblocks == 800 && + (i < 0 || + (loc.cylinders == 80 && + loc.heads == 1))) + { + /* Looks like an RX50 floppy, turn on + * special handling + */ + if (sw.debug != NULL) + printf ("rx50 handling enabled\n"); + absflag = TRUE; + } + /* if size wasn't overridden in command line, + * use the size we found + */ + if (rsize == 0) + rsize = diskblocks; + } + else + { + printf ("RSTS disk container is null or not a block device\n"); + exit (EXIT_FAILURE); + } + } +} + +/* This routine is called to do any device open actions that may be needed. + * The "mode" argument is a standard C open mode. The return value is zero + * for success, non-zero for error. + */ + +int absopen (const char *rname, const char *mode) +{ + int flags; + + if (strcmp (mode, DREADMODE) == 0) + flags = O_RDONLY; + else + flags = O_RDWR; + floppy = open (rname, flags); + return (floppy < 0); + curtrack = -1; +} + +/* This routine is called to do a seek on a device. You can do it here + * or as part of the read/write, whichever is easier. This routine is + * called only if the I/O operations are changing between read and write, + * or are not sequential. So you would want to do the work here if your + * OS does implicit sequential I/O, and make this a NOP if the read and + * write primitives take an explicit block number. + */ + +void absseek (long block) +{ +} + +/* This routine is called to do any needed "close" actions for absolute I/O */ + +void absclose () +{ + flushtrack (); + close (floppy); + floppy = -1; +} + +/* This routine is called to do an absolute device read. The block number + * is supplied, even though it could have been derived from a preceding + * absseek call. This is because absseek is not called when sequential + * reads are done. + */ + +long absread (long sec, long count, void *buffer) +{ + int track, tsec; + byte *b = (byte *) buffer; + + while (count) + { + makechs_rx50 (sec, &track, &tsec); + gettrack (track); + memcpy (b, trackbuf + (BLKSIZE * tsec), BLKSIZE); + b += BLKSIZE; + count -= BLKSIZE; + sec++; + } + return 0; /* success */ +} + +/* This routine is called to do an absolute device write. */ + +long abswrite (long sec, long count, void *buffer) +{ + int track, tsec; + byte *b = (byte *) buffer; + + while (count) + { + makechs_rx50 (sec, &track, &tsec); + gettrack (track); + memcpy (trackbuf + (BLKSIZE * tsec), b, BLKSIZE); + writecurrent = TRUE; + b += BLKSIZE; + count -= BLKSIZE; + sec++; + } + return 0; /* success */ +} diff --git a/extracters/rstsflx/platform.h b/extracters/rstsflx/platform.h new file mode 100644 index 0000000..1829d99 --- /dev/null +++ b/extracters/rstsflx/platform.h @@ -0,0 +1,65 @@ +/* Platform specific typedefs + * + * This file defines data types used for accessing external data, + * i.e., stuff that is a specific size. You may need to edit this + * to make the field sizes work right for a particular platform. + * (Likely cases are noted below.) + */ + +/* We'll try to figure out the sizes automatically. If this doesn't + * work right, define SHORTSIZE, LONGSIZE, and INTSIZE to equal the + * size (in bytes) of "short int", "long int" and "int" respectively. + */ + +#include + +#ifndef SHORTSIZE +#if (SHRT_MAX == 0x7fff) +#define SHORTSIZE 2 +#else +#error "Please define SHORTSIZE" +#endif +#endif + +#ifndef INTSIZE +#if (INT_MAX == 0x7fff) +#define INTSIZE 2 +#else +#if (INT_MAX == 0x7fffffff) +#define INTSIZE 4 +#else +#error "Please define INTSIZE" +#endif +#endif +#endif + +#ifndef LONGSIZE +#if (LONG_MAX == 0x7fffffff) +#define LONGSIZE 4 +#else +#if (LONG_MAX == 0x7fffffffffffffff) +#define LONGSIZE 8 +#else +#error "Please define LONGSIZE" +#endif +#endif +#endif + +#if (SHORTSIZE == 2) +typedef unsigned short int word16; +typedef short int int16; +#else +#error "can't typedef 16-bit integers..." +#endif + +#if (LONGSIZE == 4) +typedef unsigned long int lword32; +typedef long int long32; +#else +#if (INTSIZE == 4) +typedef unsigned int lword32; +typedef int long32; +#else +#error "can't typedef 32-bit integers..." +#endif +#endif diff --git a/extracters/rstsflx/rstsflx.c b/extracters/rstsflx/rstsflx.c new file mode 100644 index 0000000..9b46234 --- /dev/null +++ b/extracters/rstsflx/rstsflx.c @@ -0,0 +1,166 @@ +/* Program to manipulate RSTS disks and disk container files */ + +#include "version.h" /* set version number */ + +/* system includes */ + +#include +#include +#include +#include + +#include +#include + +/* application specific includes */ + +#include "flx.h" /* common definitions */ +#include "rstsflx.h" +#include "fldef.h" /* RSTS file system definitions */ +#include "scancmd.h" +#include "diskio.h" + +#define IOBLOCKS 64 + +#define IOSIZE IOBLOCKS*BLKSIZE /* size of general I/O buffer */ +#define IOEXTRA 10 /* number of extra bytes to allocate */ + +char *iobuf; /* pointer to buffer */ +long iobufsize; /* and size we allocated */ +char *cmdbuf; /* command line from readline */ + +static jmp_buf mainbuf; + +void doabort(int status, const char *srcfile, int srcline) +{ + switch (status) + { + case BADRE: + printf ("Invalid retrieval entries for file\n"); + break; + case BADBLK: + printf ("Block number out of range\n"); + break; + case BADDCS: + printf ("Invalid DCS (device too big)\n"); + break; + case CORRUPT: + printf ("Corrupt disk structure\n"); + break; + case NOMEM: + printf ("malloc failure\n"); + break; + case DIRTY: + printf ("Disk was not properly dismounted\n"); + break; + case ROPACK: + printf ("Disk is read-only and -Write was not specified\n"); + break; + case DISKIO: + printf ("I/O error on RSTS disk\n"); + perror (progname); /* print details */ + break; + case NOMSG: + /* no message, caller did that */ + break; + case BADPAK: + printf ("Disk cannot be rebuilt\n"); + break; + case INTERNAL: + default: + printf ("Internal error in program...\n"); + } + /* if it looks like our problem, report where it happened */ + if (status != DIRTY && + status != ROPACK && + status != NOMSG && + status != BADPAK) + { + printf (" in module %s, line %d\n", srcfile, srcline); + } + longjmp (mainbuf, 1); +} + +int main (int argc, char **argv) +{ + int cmdlen; + char **cmdargv = NULL; /* for scanning command line */ + int cmdargc; + char *word; + void (*command)(int, char **); + int endian; + char *s; + + /* set initial abort handler */ + if (setjmp (mainbuf)) + { + exit (EXIT_FAILURE); + } + + endian = 0; + *((char *)&endian) = 'A'; +#if (INTSIZE == 2) + if (endian == 0x4100) +#else + if (endian == 0x41000000) +#endif + { + printf ("FLX is not supported on big endian systems\n"); + exit (EXIT_FAILURE); /* quit right now */ + } + else if (endian != 0x41) + { + printf ("Error in endian test: %08x\n", endian); + exit (EXIT_FAILURE); /* quit right now */ + } + progname = argv[0]; /* remember our name */ + if ((iobuf = (char *) malloc (IOSIZE + IOEXTRA)) == NULL) + rabort (NOMEM); + iobufsize = IOSIZE; + initialize_readline (); /* Bind our completer. */ + if (argc > 1) /* arguments on command line */ + { + if ((command = scanargs (argc, argv)) == NULL) + exit (EXIT_FAILURE); /* scan arguments */ + (*command) (fargc, fargv); /* go execute the command */ + if (command != dodisk) return 0; /* done, exit */ + } + else + { + setrname (); + printf ("FLX %s\nDefault RSTS disk is %s\n\n", IDENT, rname); + } + for (;;) + { + /* in the case of abort, we come back here */ + setjmp (mainbuf); + cmdbuf = readline ("flx> "); + if (cmdbuf == NULL) break; /* control-d to quit */ + s = stripwhite (cmdbuf); + if (*s) + { + add_history (s); + newhistitems++; + if (cmdargv != NULL) free (cmdargv); + if ((cmdargv = (char **) malloc (sizeof (char *))) == NULL) + rabort (NOMEM); + cmdargv[0] = progname; /* match conventions */ + cmdargc = 1; + word = strtok (s, " "); + while (word != NULL) + { + cmdargv = (char **) realloc (cmdargv, + ++cmdargc * sizeof (char *)); + if (cmdargv == NULL) rabort (NOMEM); + cmdargv[cmdargc - 1] = word; + word = strtok (NULL, " "); + } + if (cmdargc == 1) continue; /* ignore null command */ + /* go execute the command */ + if ((command = scanargs (cmdargc, cmdargv)) != NULL) + (*command)(fargc, fargv); + } + free (cmdbuf); + } + doexit (0, NULL); +} diff --git a/extracters/rstsflx/rstsflx.h b/extracters/rstsflx/rstsflx.h new file mode 100644 index 0000000..2aaede8 --- /dev/null +++ b/extracters/rstsflx/rstsflx.h @@ -0,0 +1,3 @@ +extern void doabort(int status , const char * srcfile , int srcline) + __attribute__ ((noreturn)); +extern int main(int argc , char **argv); diff --git a/extracters/rstsflx/rtime.c b/extracters/rstsflx/rtime.c new file mode 100644 index 0000000..c438afa --- /dev/null +++ b/extracters/rstsflx/rtime.c @@ -0,0 +1,76 @@ +/* subroutines to handle RSTS date/time */ + +#include +#include +#include + +#include "flx.h" +#include "rtime.h" +#include "fldef.h" + +static const char months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +static int days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +char *cvtdate (word date, char *buf) +{ + long day, yr; + int mon; + + if (date == 0) { /* no date present */ + memcpy (buf, " none ", DATELEN); + return (buf + DATELEN - 1); /* point to terminator */ + } + yr = (long)date / 1000 + 1970; + day = date % 1000; + if (yr & 3) days[1] = 28; + else days[1] = 29; /* check for leap year */ + for (mon = 0; mon < 12; mon++) { + if (day <= days[mon]) break; + day -= days[mon]; + } + sprintf (buf, "%2ld-%3s-%04ld", day, months[mon], yr); + return (buf + DATELEN - 1); /* point to terminator */ +} + +char *cvttime (word time, char *buf) +{ + int hour, min; + char m; + + time &= at_msk; /* mask out any flags */ + if (time == 0) { /* no time present */ + memcpy (buf, " none ", RTIMELEN); + return (buf + RTIMELEN - 1); /* point to terminator */ + } + time = 1440 - time; /* now time since midnight */ + hour = time / 60; + min = time % 60; + if (hour >= 12) { + hour -= 12; + m = 'p'; + } else m = 'a'; + if (hour == 0) hour = 12; + sprintf (buf, "%2d:%02d %1cm", hour, min, m); + return (buf + RTIMELEN - 1); /* point to terminator */ +} + +word curdate () /* current date in rsts form */ +{ + struct tm *tmb; + time_t now; + + time (&now); + tmb = localtime (&now); + return ((tmb->tm_year - 70) * 1000 + tmb->tm_yday + 1); +} + +word curtime () /* current time in rsts form */ +{ + struct tm *tmb; + time_t now; + + time (&now); + tmb = localtime (&now); + return (1440 - (tmb->tm_hour * 60 + tmb->tm_min)); +} diff --git a/extracters/rstsflx/rtime.h b/extracters/rstsflx/rtime.h new file mode 100644 index 0000000..612db41 --- /dev/null +++ b/extracters/rstsflx/rtime.h @@ -0,0 +1,12 @@ +extern char * cvtdate(word date , char * buf); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern char * cvttime(word time , char * buf); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern word curdate(void); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern word curtime(void); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ diff --git a/extracters/rstsflx/scancmd.c b/extracters/rstsflx/scancmd.c new file mode 100644 index 0000000..f4f689c --- /dev/null +++ b/extracters/rstsflx/scancmd.c @@ -0,0 +1,577 @@ +/* command line handling for rstsflx */ + +#include +#include +#include +#include + +#include +#include + +/* Some unixes define this, some do not. */ +#ifndef whitespace +#define whitespace(c) ((c) == ' ' || (c) == '\t') +#endif + +#include "flx.h" +#include "fldef.h" +#include "silfmt.h" +#include "scancmd.h" +#include "fip.h" +#include "diskio.h" +#include "filename.h" +#include "doalloc.h" +#include "doget.h" +#include "doident.h" +#include "dolist.h" +#include "dotype.h" +#include "dodump.h" +#include "doput.h" +#include "dodelete.h" +#include "dorename.h" +#include "dorts.h" +#include "dodir.h" +#include "doprot.h" +#include "doinit.h" +#include "dohook.h" +#include "docomp.h" +#include "doclean.h" + +swtab sw; /* switch flag table */ + +char *progname; /* name of program (argv[0]) */ +char *cmdname; /* command name (argv[1]) */ +char **fargv = NULL; /* array of pointers to arguments */ +int fargc; /* and count of how many we found */ +char *defdevice = NULL; /* default device name */ +char *defsize = NULL; /* and size, as a string */ +char *histfile; /* name of history file */ +int hfilesize; /* size limit for history file */ +long newhistitems; /* number of history items added */ + +typedef struct { + const char *kw; + void (*hand)(int, char *[]); +} cmdent; + +/* This routine is used to ask (if -query was specified) whether a file + * should be processed or not. It returns the answer, which is a character + * "y", "n" or "q". Note that the answer "a" is returned as "y" and + * further prompting is turned off. + */ + +char doquery (void (*printfile)(void *), void *name) +{ + char answer[200]; + char first; + + if (sw.query == NULL) return ('y'); + else { + for (;;) { + printf (" %s ", cmdname); + (*printfile) (name); + printf (" (y,n,a,q)? "); + fflush (stdout); + fgets (answer, sizeof (answer), stdin); + first = tolower (answer[0]); + if (first == 'q' || first == 'n' || first == 'y') + return (first); + if (first == 'a') + { + sw.query = NULL; + return ('y'); + } + printf ("Invalid answer\n"); + } + } +} + +/* This routine is used as the generic main loop for many command + * processing routines. The first two arguments define the list of + * command (file) arguments. The third argument controls what to do + * if the name part of the filespec is null: + * NOTNULL error -- "missing filename" + * NULLISWILD ok, substitute wildcard ("?") for the missing name + * NULLISNULL ok, leave the name part null, so it's a directory + * reference -- and if it's [*,*] or [n,*], treat + * that as access to MFD and GFD respectively (rather + * than wild directories). + * + * -query switch processing is provided in this routine. If a command + * does not want -query to have effect, it should override the switch to + * be absent (sw.query = NULL). + */ + +void dofiles (int argc, char **argv, commandaction action, int nullflag) +{ + int fnum, j; + firqb f; + int matches; + char answer; + + if (argc == 0) printf ("Usage: %s %s files...\n", progname, cmdname); + for (fnum = 0; fnum < argc; fnum++) + { + if (!parse (argv[fnum], &f)) + { + printf ("Invalid filespec %s\n", argv[fnum]); + continue; + } + if (nullflag == NOTNULL && (f.flags & f_name) == 0) + { + printf ("Missing filename %s\n", argv[fnum]); + continue; + } + else if (nullflag == NULLISWILD) + { + if ((f.flags & f_name) == 0) + for (j = 0; j < 6; j++) f.name[j] = '?'; + f.flags |= f_name | f_namw; + if ((f.flags & f_ext) == 0) + { + f.name[7] = '?'; + f.name[8] = '?'; + f.name[9] = '?'; + f.flags |= f_ext | f_extw; + } + } + else if (nullflag == NULLISNULL && (f.flags & f_name) == 0) + { + if (f.prog == 255) + { + if (plevel == RDS0) + { + printf ("GFD or MFD not legal for RDS.0 pack\n"); + continue; + } + } + else if (f.proj == 255) + { + printf ("Invalid directory spec\n"); + continue; + } + } + matches = 0; + if (initfilescan (&f, gfddcntbl)) /* setup file scan */ + { + answer = 'y'; /* dummy */ + while (nextfile (&f)) + { + matches++; /* found another */ + answer = doquery ((void (*)(void *))printcurname, &f); + if (answer == 'q') break; + if (answer == 'n') continue; + (*action) (&f); /* do whatever */ + } + if (answer == 'q') break; /* out two levels... */ + } + if (matches == 0) + { + printf ("No files matching "); + printfqbname (&f); + printf ("\n"); + } + } +} + +void dodisk (int argc, char **argv) +{ + long rsize, tsize; + int flag; + + if (defdevice != NULL) free (defdevice); + if (defsize != NULL) free (defsize); + defdevice = NULL; + defsize = NULL; + if (argc > 0) + { + if (argc > 1) /* size also supplied */ + { + getsize (argv[1], &rsize, &tsize, &flag); + if (rsize == 0) + { + printf ("Invalid size %s\n", argv[1]); + return; + } + defdevice = (char *) malloc (strlen (argv[0]) + 1); + defsize = (char *) malloc (strlen (argv[1]) + 1); + if (defdevice == NULL || defsize == NULL) + rabort(NOMEM); + strcpy (defdevice, argv[0]); + strcpy (defsize, argv[1]); + } + else + { + defdevice = (char *) malloc (strlen (argv[0]) + 1); + if (defdevice == NULL) rabort(NOMEM); + strcpy (defdevice, argv[0]); + } + } + if (sw.verbose != NULL) + { + setrname (); + if (defsize != NULL) + printf ("Default RSTS disk name is %s, size %ld\n", + rname, rsize); + else printf ("Default RSTS disk name is %s\n", rname); + } +} + +void doexit (int argc, char **argv) +{ + int i; + +#ifndef __APPLE__ + i = append_history (newhistitems, histfile); + if (i) write_history (histfile); + else history_truncate_file (histfile, hfilesize); + free (histfile); +#endif + exit (EXIT_SUCCESS); +} + +const cmdent commands[] = +{ + { "list", dolist }, + { "directory", dolist }, + { "ls", dolist }, + { "type", dotype }, + { "cat", dotype }, + { "dump", dodump }, + { "exit", doexit }, + { "quit", doexit }, + { "bye", doexit }, + { "get", doget }, + { "put", doput }, + { "delete", dodelete }, + { "rm", dodelete }, + { "protect", doprot }, + { "rts", dorts }, + { "runtime", dorts }, + { "rename", dorename }, + { "mv", dorename }, + { "move", dorename }, + { "hook", dohook }, + { "mkdir", domkdir }, + { "rmdir", dormdir }, + { "identify", doident }, + { "allocation", doalloc }, + { "initialize", doinit }, + { "dskint", doinit }, + { "disk", dodisk }, + { "compress", docomp }, + { "clean", doclean }, + { "rebuild", doclean }, + { NULL, NULL } }; + +typedef struct +{ + char *kw; + char **flag; + int arg; /* TRUE if switch takes an argument */ +} swname; + +#define sd(x,y) { #x, &sw.y, FALSE } /* switch w/o arg */ +#define sda(x,y) { #x, &sw.y, TRUE } /* switch with arg */ + +const swname switches[] = +{ + sd(ascii,ascii), + sd(binary,bswitch), + sd(brief,bswitch), + sda(clustersize,clusiz), + sd(confirm,query), + sd(contiguous,contig), + sda(create,create), + sda(disk,rstsdevice), + sd(Debug,debug), + sda(end,end), + sda(filesize,size), + sd(full,full), + sd(image,bswitch), + sd(long,full), + sda(merge,merge), + sd(noprotect,unprot), + sd(oattributes,oattr), + sd(odt,odt), + sda(offset,offset), + sd(protect,prot), + sd(query,query), + sd(replace,replace), + sd(r,rmsvar), + sda(rf,rmsfix), + sd(rv,rmsvar), + sd(rs,rmsstm), + sda(size,size), + sda(Size,disksize), + sda(start,start), + sd(summary,summary), + sd(tree,tree), + sd(unprotect,unprot), + sd(verbose,verbose), + sd(wide, wide), + sd(Write,overwrite), + sd(1column,narrow), + sd(user,user), + sd(hex,hex), + { "", NULL, FALSE } }; + +commandhandler scanargs(int argc, char **argv) +{ + int n, l; + const cmdent *c; + const swname *s, *swn; + commandhandler command; + + memset (&sw, 0, sizeof (swtab)); /* Indicate no switches yet */ + if (fargv != NULL) free (fargv); + if ((fargv = (char **) malloc (argc * sizeof(char *))) == NULL) rabort (NOMEM); + fargc = 0; /* No arguments yet */ + cmdname = NULL; /* and no command name yet */ + for (n = 1; n < argc; n++) /* scan the program arguments */ + { + if (argv[n][0] == '-') /* it's a switch */ + { + s = switches; /* point to switch names */ + l = strlen (argv[n]) - 1; + swn = NULL; /* no match yet */ + while (s->flag != NULL) + { + if (strncmp (&argv[n][1], s->kw, l) == 0) { + if (strlen (s->kw) == l) + { + swn = s; + break; /* exact match */ + } + if (swn == NULL) swn = s; + else if (s->flag != swn->flag) + { + printf ("Ambiguous switch %s\n", + argv[n]); + return (NULL); + } + } + s++; + } + if (swn == NULL) + { + printf ("Unrecognized switch %s\n", argv[n]); + return (FALSE); + } + *(swn->flag) = argv[n]; + if (swn->arg) /* switch takes an argument */ + { + if (++n == argc) /* skip it */ + { + printf ("Missing argument for switch %s\n", argv[n - 1]); + return (FALSE); + } + *(swn->flag) = argv[n]; /* point to that */ + } + } + else + { + if (cmdname == NULL) cmdname = argv[n]; + else fargv[fargc++] = argv[n]; + } + + } + c = commands; + command = NULL; /* Nothing found yet */ + if (cmdname == NULL) + { + printf ("Missing command keyword\n"); + return NULL; + } + l = strlen (cmdname); /* get length of command */ + while (c->kw != NULL) /* look for matching command */ + { + if (strncmp (cmdname, c->kw, l) == 0) + { + if (strlen (c->kw) == l) + { + command = c->hand; + break; /* stop now on exact match */ + } + if (command == NULL) command = c->hand; + else if (command != c->hand) + { + printf ("Ambiguous command %s\n", cmdname); + return (NULL); + } + } + c++; + } + if (command == NULL) + { + printf ("Unrecognized command %s\n", cmdname); + return (NULL); + } + return (command); +} + +/* Strip whitespace from the start and end of STRING. Return a pointer + * into STRING. + */ +char *stripwhite (char *string) +{ + register char *s, *t; + + for (s = string; whitespace (*s); s++) ; + + if (*s == 0) return (s); + + t = s + strlen (s) - 1; + while (t > s && whitespace (*t)) t--; + *++t = '\0'; + + return s; +} + +/* **************************************************************** */ +/* */ +/* Interface to Readline Completion */ +/* */ +/* **************************************************************** */ + +/* some forward declarations */ +char * command_generator (const char *text, int state); +char * switch_generator (const char *text, int state); +char ** flx_completion (char *text, int start, int end); + +/* Tell the GNU Readline library how to complete. We want to try to complete + * on command names if this is the first word in the line, or on filenames + * if not. + */ +void initialize_readline (void) +{ + char *histfilesize; + char *histsize; + int hsize = 0; + char *home; + char *hf; + int i; + + /* get history parameters */ + hf = getenv ("FLXHISTFILE"); + histfilesize = getenv ("FLXHISTFILESIZE"); + histsize = getenv ("FLXHISTSIZE"); + hfilesize = 0; + newhistitems = 0; + if (hf == NULL) + { + home = getenv ("HOME"); + i = strlen (home); + histfile = malloc (i + strlen ("/.flx_history") + 1); + strcpy (histfile, home); + strcat (histfile, "/.flx_history"); + } + else histfile = strdup (hf); + if (histfilesize != NULL) hfilesize = atoi (histfilesize); + if (histsize != NULL) hsize = atoi (histsize); + if (hsize == 0) hsize = 100; + if (hfilesize == 0) hfilesize = hsize; + + /* set up history stuff */ + using_history (); + stifle_history (hsize); + read_history (histfile); + + /* Allow conditional parsing of the ~/.inputrc file. */ + rl_readline_name = "Flx"; + + /* Tell the completer that we want a crack first. */ + rl_attempted_completion_function = (CPPFunction *)flx_completion; + + /* supply some things that don't seem to be there in DOS... */ + rl_basic_word_break_characters = "n\"\\'`@$>"; + rl_completer_word_break_characters = + (char *) rl_basic_word_break_characters; +} + +/* Attempt to complete on the contents of TEXT. START and END show the + * region of TEXT that contains the word to complete. We can use the + * entire line in case we want to do some simple parsing. Return the + * array of matches, or NULL if there aren't any. + */ +char ** flx_completion (char *text, int start, int end) +{ + char **matches; + + matches = NULL; + + /* If this word is at the start of the line, then it is a command + * to complete. Otherwise it is the name of a file in the current + * directory. + */ + if (start == 0) + matches = rl_completion_matches (text, command_generator); + else if (*text == '-') + matches = rl_completion_matches (text, switch_generator); + + return (matches); +} + +/* Generator function for command completion. STATE lets us know whether + * to start from scratch; without any state (i.e. STATE == 0), then we + * start at the top of the list. + */ +char * command_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + + /* If this is a new word to complete, initialize now. This includes + * saving the length of TEXT for efficiency, and initializing the index + * variable to 0. + */ + if (!state) + { + list_index = 0; + len = strlen (text); + } + + /* Return the next name which partially matches from the command list. */ + while ((name = (char *) commands[list_index].kw)) + { + list_index++; + if (strncmp (name, text, len) == 0) + return strdup (name); + } + + /* If no names matched, then return NULL. */ + return NULL; +} + +/* ditto but for switches */ +char * switch_generator (const char *text, int state) +{ + static int list_index, len; + char *name; + char sw[20]; + + /* If this is a new word to complete, initialize now. This includes + * saving the length of TEXT for efficiency, and initializing the index + * variable to 0. + */ + if (!state) + { + list_index = 0; + len = strlen (text) - 1; + } + + /* Return the next name which partially matches from the switch list. */ + while (*(name = switches[list_index].kw)) + { + list_index++; + if (strncmp (name, text + 1, len) == 0) + { + sw[0] = '-'; + strcpy (sw + 1, name); + return strdup (sw); + } + } + + /* If no names matched, then return NULL. */ + return NULL; +} diff --git a/extracters/rstsflx/scancmd.h b/extracters/rstsflx/scancmd.h new file mode 100644 index 0000000..20ba6b3 --- /dev/null +++ b/extracters/rstsflx/scancmd.h @@ -0,0 +1,11 @@ +extern char doquery (void (*printfile)(void *), void *name); +extern void dodisk (int argc, char **argv); +extern void dofiles(int argc , char **argv , commandaction action , int nullflag); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void doexit(int argc , char **argv); +extern commandhandler scanargs(int argc , char **argv); + /* Prototype include a typedef name. + It should be moved after the typedef declaration */ +extern void initialize_readline (void); +extern char *stripwhite (char *string); diff --git a/extracters/rstsflx/silfmt.h b/extracters/rstsflx/silfmt.h new file mode 100644 index 0000000..a0593e9 --- /dev/null +++ b/extracters/rstsflx/silfmt.h @@ -0,0 +1,87 @@ +/* + * Edit history for SILFMT + * + * [RSTS V9_0] + * 000 WJS 22-Sep-83 Creation + * + * [RSTS V9_6] + * 001 KPH 13-Nov-87 Increase number of phases to 47 + * + * 002 GPK 23-Aug-94 Convert from .mac to .h + * 003 GPK 29-Aug-94 Add definition for SAV format SIL index, add + * STB and overlay descriptor format. + */ + +/* Set the number of SIL index blocks allowed for this release */ + +#define si_nbl 3 /* Maximum number of SIL index blocks */ + +/* Definitions of SIL Index entry */ + +typedef struct { + word16 se_nam[2]; /* Name of module */ + word16 se_idn[2]; /* Ident of module */ + word16 se_blk; /* Starting block of module */ + word16 se_stb; /* Starting block of STB */ + word16 se_stn; /* Number of entries in STB */ + word16 se_lod; /* Load address of this module */ + word16 se_siz; /* Size of module (in bytes) */ + word16 se_xfr; /* Transfer address */ + word16 se_szd; /* Size of module image of disk in blocks */ + word16 se_ovb; /* Block offset to module's overlay descriptors */ + word16 se_ovn; /* Number of overlay descriptors for module */ + word16 se_off; /* Starting offset on disk for this module */ + word16 filler; /* (reserved) */ + word16 se_xxx; /* Reserved for SAV format SILs */ +} silent; + +#define se_len (sizeof (silent)) /* Size of SIL Index entry */ + +/* Derive the number of modules si_nbl SIL index blocks can contain */ + +#define si_oth (1000/se_len) /* Number of entries in a non-first block */ +#define si_1st (si_oth-1) /* Number of entries in first block */ +#define si_nmd ((si_nbl-1)*si_oth+si_1st) /* Maximum total no of index entries */ + +/* Layout for SIL index as it would be directly read from disk */ + +typedef struct { + word16 si_num; /* Number of modules in SIL */ + silent si_ent[si_1st]; /* Space for first block's SIL Index entries */ + word16 si_rsv[12]; /* Reserved */ + word16 si_bls; /* Size of this SIL in blocks */ + word16 si_chk; /* Checksum of SIL Index */ + word16 si_sil; /* RAD50 "SIL" for identification */ + silent si_mor[si_nmd - si_1st]; /* Space for non-first blocks' entries */ +} silindex; + +/* Layout for SIL index in the case of a .SAV file SIL */ + +typedef struct { + word16 si_num; /* Number of modules (must be 1) */ + silent si_ent; /* One SIL index entry */ +#define initpc si_ent.se_xxx /* Initial PC value lives here */ + word16 initsp; /* Initial SP */ + word16 rtjsw; /* Reserved for JSW in RT11 */ + word16 rtusr; /* Reserved for USR ptr in RT11 */ + word16 usertop; /* High address of program */ + word16 si_rsv[(0774-052)/2]; /* Fill to end of block */ + word16 si_chk; /* Checksum of SIL Index */ + word16 si_sil; /* RAD50 "SIL" for identification */ +} savsilindex; + +/* Layout of SIL symbol table entry */ + +typedef struct { + word16 name[2]; /* Symbol name in RAD50 */ + word16 ovnum; /* Overlay number */ + word16 value; /* Symbol value */ +} stbent; + +/* Layout of overlay descriptor entry */ + +typedef struct { + word16 base; /* Base virtual address of overlay */ + word16 size; /* Size in bytes of overlay */ + word16 offset[2]; /* Offset (MSW, LSW) to overlay */ +} ovrent; diff --git a/extracters/rstsflx/unxabsio.c b/extracters/rstsflx/unxabsio.c new file mode 100644 index 0000000..652895a --- /dev/null +++ b/extracters/rstsflx/unxabsio.c @@ -0,0 +1,110 @@ +/* absolute I/O support for Unix + * + * Paul Koning 95.01.05 created + * + * Note that this particular version of absio is mostly a dummy, since + * there is very little special that has to be done on Unix for absolute + * I/O. Among other things, this file should serve as a template for + * those who want to create the equivalent for another operating system. + */ + +#include +#include +#include +#include + +#include "flx.h" +#include "absio.h" + +/* this routine is called to scan a supplied container file/device + * name. If the name refers to a real disk, then absflag is set + * and rsize is set to the device size. Otherwise, no action is taken. + * + * More precisely, there are three things this routine may want to do, + * depending on the OS and the name supplied. + * + * If, for the specified name, the absolute I/O routines in this module + * need to be called, then absflag should be set to TRUE, and rsize must + * be set to the size of the device. Otherwise, absflag should be left + * alone (which leaves it FALSE); that way the other absolute I/O routines + * in this module will not be called and standard C I/O is used instead. + * + * If, for the specified name, "fstat" will not return a size (i.e., returns + * zero) then rsize must specify the correct size. This can be set in this + * module, based on OS specific operations, or it can simply be left + * unchanged, in which case it has to be supplied by the user. + * + * For example, in Unix the fstat function doesn't return a size for raw + * devices (it returns zero) but the stdio routines are otherwise perfectly + * suitable. So this routine does NOT set absflag since no special abs I/O + * routines are needed. It does check the return from stat(); if this + * indicates a raw device, it checks that rsize has been supplied and + * complains if not. Note that the code below does not attempt to obtain + * the device size, since there is no portable Unix way of doing this that + * I know of. + */ + +void absname (const char *rname) +{ + struct stat sbuf; + + if (stat (rname, &sbuf)) return; /* try to get info about device */ + diskblocks = UP(sbuf.st_size,BLKSIZE) / BLKSIZE; + if (diskblocks == 0) { + if (S_ISCHR(sbuf.st_mode)) { + diskblocks = rsize; + if (rsize == 0) { + printf ("Size not specified for RSTS disk %s\n", rname); + exit (EXIT_FAILURE); + } + } + } +} + +/* This routine is called to do any device open actions that may be needed. + * The "mode" argument is a standard C open mode. The return value is zero + * for success, non-zero for error. + */ + +int absopen (const char *rname, const char *mode) +{ + rabort(INTERNAL); /* should never get here */ +} + +/* This routine is called to do a seek on a device. You can do it here + * or as part of the read/write, whichever is easier. This routine is + * called only if the I/O operations are changing between read and write, + * or are not sequential. So you would want to do the work here if your + * OS does implicit sequential I/O, and make this a NOP if the read and + * write primitives take an explicit block number. + */ + +void absseek (long block) +{ + rabort(INTERNAL); /* should never get here */ +} + +/* This routine is called to do any needed "close" actions for absolute I/O */ + +void absclose () +{ + rabort(INTERNAL); /* should never get here */ +} + +/* This routine is called to do an absolute device read. The block number + * is supplied, even though it could have been derived from a preceding + * absseek call. This is because absseek is not called when sequential + * reads are done. + */ + +long absread (long sec, long count, void *buffer) +{ + return (0); /* should never get here */ +} + +/* This routine is called to do an absolute device write. */ + +long abswrite (long sec, long count, void *buffer) +{ + return (0); /* should never get here */ +} diff --git a/extracters/rstsflx/version.h b/extracters/rstsflx/version.h new file mode 100644 index 0000000..e16f0b0 --- /dev/null +++ b/extracters/rstsflx/version.h @@ -0,0 +1 @@ +#define IDENT "v2.6" /* program version number */