summaryrefslogtreecommitdiff
path: root/dviware/beebe/src/bintnxvm.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/beebe/src/bintnxvm.c
Initial commit
Diffstat (limited to 'dviware/beebe/src/bintnxvm.c')
-rw-r--r--dviware/beebe/src/bintnxvm.c390
1 files changed, 390 insertions, 0 deletions
diff --git a/dviware/beebe/src/bintnxvm.c b/dviware/beebe/src/bintnxvm.c
new file mode 100644
index 0000000000..ff71700f68
--- /dev/null
+++ b/dviware/beebe/src/bintnxvm.c
@@ -0,0 +1,390 @@
+/***********************************************************************
+Convert a TOPS-20 file transferred in FTP "binary" mode to "tenex" mode.
+In "binary" mode, we have 2 36-bit words in 9 8-bit bytes. In "tenex"
+mode, we want the top 32 bits of each 36-bit group, giving 8 8-bit
+bytes.
+
+Who knows what FTP did if the file had an odd number of 36-bit words.
+
+[08-Oct-87]
+
+This version is intended for VAX VMS only. Modified by Jerry Leichter
+(LEICHTER@VENUS.YCC.YALE.ARPA).
+
+Usage:
+ bintnxvms [-f[xx]] [filespec]
+
+Filespec may be wild-carded; if it is missing, *.* is assumed. Each
+matching file is read, and a new version the same specification is
+created. (Note that you can only specify one filespec, however.) If
+-fxx is specified, the last block of the file is filled with bytes of
+the given value (xx), which must be a hex number. If -f is given with
+no value, 0 is assumed. Appropriate values seem to be:
+
+ * DVI DF
+ * GF DF
+ PK F6 (File spec defines no filler, F6 may be an artifact)
+ PXL ?? (Unknown, probably not significant)
+ TFM 00 (File spec defines no filler)
+
+"Fill" is definitely significant, at least in some applications, for the
+file types marked, with a "*"; it probably doesn't matter for others.
+Note, how- ever, that there is no certainty that files filled this way
+will actually be readable to all programs, since the transfer process
+may insert other random junk at the end of the file.
+
+The filler is used by programs that wish to read the files from end to
+beginning - for example, by DVI file translators that need to reverse
+page order. The author has observed that "fixed up" files often follow
+the pattern:
+
+ <data> <fill-bytes> <FFFFFFFF> <fill-bytes> end-of-block
+
+The first set of fill bytes were probably inserted by the program that
+wrote the file to being with. (There should be from 1 to 4 of them,
+bringing the file to an even number of 4-byte longwords.) The
+<FFFFFFFF> filler is four bytes of hex FF characters, and probably
+were inserted by VMS FTP to mark the end of the file on the TOPS-20
+system. The rest of the <fill-bytes> were inserted by fixfile. If
+you run into a program that is unable to read a file produced by
+fixfile, DUMP the last block of the file and see if this pattern
+occurs. If so, it should be straightforward to over-write the FF's
+with more <fill-byte>'s.
+***********************************************************************/
+
+#include <ctype.h>
+#include <stdio.h>
+#include <rms.h>
+
+FILE *fwild();
+FILE *fnext();
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ FILE *infile;
+ FILE *outfile;
+ int fill = FALSE;
+ int fillchar = 0;
+ char *fspec;
+ char thefile[NAM$C_MAXRSS + 1];
+ char *c;
+ int d;
+
+ if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'f')
+ {
+ fill = TRUE;
+ c = &argv[1][2];
+ while (isxdigit(*c))
+ {
+ if (isdigit(*c))
+ d = *c - '0';
+ else
+ d = 10 + toupper(*c) - 'A';
+ fillchar = (fillchar << 4) | d;
+ c++;
+ }
+ argc--;
+ argv++;
+ }
+ if (argc > 1)
+ fspec = argv[1];
+ else
+ fspec = "*.*";
+
+ if ((infile = fwild(fspec, "r")) == NULL)
+ {
+ perror("Bad file spec");
+ exit(0);
+ }
+
+ while (fnext(infile) != NULL)
+ {
+ fgetname(infile, thefile);
+ /* Remove version number */
+ d = strlen(thefile) - 1;
+ while (thefile[d] != ';')
+ d--;
+ thefile[d] = '\0';
+ (void)printf("[%s", thefile);
+ if ((outfile = fopen(thefile, "wb", "rfm=fix", "mrs=512"))
+ == NULL)
+ {
+ perror("] Can't open output file");
+ continue;
+ }
+ dofile(infile, outfile, fill, fillchar);
+ fclose(outfile);
+ (void)printf("]\n");
+ }
+
+}
+
+dofile(infile, outfile, fill, fillchar)
+FILE *infile;
+FILE *outfile;
+int fill;
+int fillchar;
+{
+ int c;
+ int d;
+ unsigned int bytecount = 0;
+
+#define GET() fgetc(infile)
+#define PUT(c) (fputc((c),outfile),bytecount++)
+#define ECHO() PUT(GET())
+
+ for (;;)
+ {
+ c = GET();
+ if (c == EOF)
+ break;
+
+ PUT(c); /* 0..7 */
+ ECHO(); /* 8..15 */
+ ECHO(); /* 16..23 */
+ ECHO(); /* 24..31 */
+
+ d = GET();
+ c = (d << 4);
+ d = GET();
+ c |= 0xFF & (d >> 4);
+ PUT(c); /* 4..11 */
+
+ c = (d << 4);
+ d = GET();
+ c |= 0xFF & (d >> 4);
+ PUT(c); /* 12..19 */
+
+ c = (d << 4);
+ d = GET();
+ c |= 0xFF & (d >> 4);
+ PUT(c); /* 20..27 */
+
+ c = (d << 4);
+ d = GET();
+ c |= 0xFF & (d >> 4);
+ PUT(c); /* 28..36 */
+ }
+
+ if (fill)
+ {
+ while (bytecount & 511)
+ PUT(fillchar);
+ }
+}
+
+/*
+ * Fwild and fnext for vms. Written by Martin Minow; taken from the
+ * DECUS C VMS compatibility collection.
+ */
+
+/* #include <stdio.h> */
+/* #include <rms.h> */
+#include <ssdef.h>
+#include <descrip.h>
+#include <ctype.h>
+
+#define TRUE 1
+#define FALSE 0
+#define EOS 0
+
+typedef struct rmsstuff
+{
+ int flag; /* Flag for nonwildcard calls */
+ char *wildmode;
+ struct FAB fab;
+ struct NAM nam;
+ char starname[NAM$C_MAXRSS + 1];
+ char filename[NAM$C_MAXRSS + 1];
+} RMSSTUFF;
+
+static RMSSTUFF *wilddata[_NFILE]; /* RMS struct for each file */
+
+/*
+ * rms->flag can take on the following values:
+ * ISWILD A file with wild-card bytes.
+ * UNWILD A file without wild-cards, unopened.
+ * UNWILD_OPENED A file without wild-cards, opened.
+ */
+#define ISWILD 0
+#define UNWILD 1
+#define UNWILD_OPENED 2
+
+extern FILE *cleanup();
+FILE *
+fwild(filename, mode)
+char *filename;
+char *mode;
+/*
+ * Do wildcard setup
+ */
+{
+ register FILE *fd;
+ register RMSSTUFF *r;
+ register int index;
+
+ /* First get a file to work with. In the process, make sure the
+ mode we got passed is valid. Note that every file we will open
+ from here on already exists, so an open for write will fail
+ (since the open will include the fully-expanded file name,
+ including the version number). Unfortunately, opening a file on
+ the null device always succeeds. So, to simplify matters, we
+ just reject a "w" mode request right here. (We could as well let
+ it go and then find "no matching files" when all later open
+ requests fail. But this makes more sense.) */
+ if (*mode == 'w' || (fd = fopen("_nl:", mode)) == NULL)
+ {
+ return (NULL);
+ }
+ /* Warning: the package depends on fileno(fd) remaining
+ unchanged after calls to freopen(). */
+ index = fileno(fd);
+ /* If we've been here before, make sure buffers are released. */
+ cleanup(index);
+ if ((r = malloc(sizeof(RMSSTUFF))) == NULL
+ || (r->wildmode = malloc(strlen(mode) + 1)) == NULL)
+ return (cleanup(index));
+ strcpy(r->wildmode, mode);
+ wilddata[index] = r;
+ /* Setup the fab and nam blocks. */
+ r->fab = cc$rms_fab; /* Initialize fab */
+ r->nam = cc$rms_nam; /* and nam blocks */
+ r->fab.fab$l_nam = &r->nam; /* fab -> nam */
+ r->fab.fab$l_fna = filename; /* Argument filename */
+ r->fab.fab$b_fns = strlen(filename); /* filename size */
+ r->nam.nam$l_esa = r->starname; /* Expanded file name */
+ r->nam.nam$b_ess = NAM$C_MAXRSS; /* ... size */
+ r->nam.nam$l_rsa = r->filename; /* Result filename */
+ r->nam.nam$b_rss = NAM$C_MAXRSS; /* ... size */
+ /* Parse the file name */
+ if (sys$parse(&r->fab) != RMS$_NORMAL)
+ return (cleanup(index));
+ /* Success. Null-terminate expanded file name and set flag to
+ distinguish between "wild" and "non-wild" filenames. */
+ ((char *) r->nam.nam$l_esa)[r->nam.nam$b_esl] = EOS;
+ r->flag = ((r->nam.nam$l_fnb & NAM$M_WILDCARD) == 0) ?
+ UNWILD : ISWILD;
+ return (fd);
+}
+
+
+FILE *
+fnext(fd)
+FILE *fd;
+/*
+ * Open the next valid file. return fd if successful, NULL if finished.
+ */
+{
+ register int index;
+ register RMSSTUFF *r;
+ register int errorcode;
+ FILE *test;
+
+ index = fileno(fd);
+ if ((r = wilddata[index]) == NULL || r->flag == UNWILD_OPENED)
+ {
+ /* It wasn't ours, or wasn't a wildcard and has already been
+ processed. */
+ fclose(fd);
+ fd = NULL;
+ }
+ else
+ if (r->flag == UNWILD)
+ {
+ /* Not a wildcard file, first time through */
+ fd = freopen(r->starname, r->wildmode, fd);
+ r->flag = UNWILD_OPENED;
+ }
+ else
+ {
+ /* Look for the next match -- who says you can't write obscure
+ structured code? */
+ for (;;)
+ {
+ /* Look 'em up but skip any with protection violation
+ errors. */
+ r->fab.fab$w_ifi = 0; /* Internal file index */
+ if ((errorcode = sys$search(&r->fab)) == RMS$_NORMAL)
+ {
+ /* We have a file. Open it if we have access rights.
+ Determining this isn't as simple as it might be
+ because the access() function checks the wrong thing:
+ It ignores ACL's and any special privileges. So we
+ just open the file twice. (We have to check first
+ since if we fail, freopen will free up our file
+ pointer and we can't be sure of getting it back.)
+ Opening the file twice has one unfortunate side
+ effect - it bumps the file revision by 2. That's
+ life. */
+ ((char *) r->nam.nam$l_rsa)[r->nam.nam$b_rsl] = EOS;
+ if ((test = fopen(r->filename, r->wildmode)) == NULL)
+ {
+ /* Couldn't open it; try for another. */
+ continue;
+ }
+ else
+ {
+ /* Close up the test channel first (to avoid
+ problems with sharing; then open the file. We
+ should normally be able to open the file. It
+ this fails, something is wrong inside the C
+ library. (More likely, a timing problem occured
+ - between our test and our actual open, someone
+ deleted the file, or between our close and
+ re-open, someone else opened it in an
+ incompatible mode.) In any case, we've lost our
+ file descriptor, and there is no good way to
+ recover; so we just return NULL and let the
+ caller think that's all there is. */
+ fclose(test);
+ fd = freopen(r->filename, r->wildmode, fd);
+ break;
+ }
+ }
+ else
+ if (errorcode == RMS$_PRV)
+ {
+ /* sys$search() found something, but we don't have
+ privileges to open it. Look for another. */
+ continue;
+ }
+ else
+ {
+ /* Can't find a file. This should be RMS$_NMF. */
+ fclose(fd);
+ fd = NULL;
+ break;
+ }
+ }
+ }
+ /* Cleanup if any errors */
+ if (fd == NULL)
+ {
+ cleanup(index);
+ }
+ return (fd);
+}
+
+static FILE *
+cleanup(index)
+register int index;
+/*
+ * Empty out any stored information
+ */
+{
+ register RMSSTUFF *r;
+
+ r = wilddata[index];
+ if (r != NULL)
+ {
+ if (r->wildmode != NULL)
+ {
+ free(r->wildmode);
+ }
+ free(r);
+ wilddata[index] = NULL;
+ }
+ return (NULL);
+}