dan@rna.UUCP (Dan Ts'o) (09/20/88)
Posting-number: Volume 4, Issue 82 Submitted-by: "Dan Ts'o" <dan@rna.UUCP> Archive-name: tenex I had just spent a few hours uploading MSDOS stuff from SIMTEL20. Back on my PC, I realized that while I had remembered to transfer everything in binary mode (in FTP), that I had neglected to account for (is it called ?) TENEX mode (since SIMTEL20 is a 36-bit machine). I decided it would be faster to write a C program to convert the 36-bit data into good ol' 8-bit bytes, than re-upload every. So here is the program. I used MSC 5.0. The program will convert both binary (-b, default, from each 36-bit word, generate 4x8-bit bytes and discard the remaining 4bits) and text (-t, from each 36-bit word, generate 5x7bit (with zero parity bit) ASCII bytes and discard the last bit). The program has been tested on both MSDOS 3.1 and 4.3BSD UNIX. If anyone needs a binary copy for MSDOS, I'll mail them one. I hope this wheel hasn't been reinvented too many times... Cheers, Dan Ts'o tso@rockefeller.edu dan@rna.rockefeller.edu ...cmcl2!rna!dan 212-570-7671 Dept Neurbiology The Rockefeller University 1230 York Ave. NY, NY 10021 wc tenex.c: 266 752 4787 sum tenex.c: (VAX) 32982 5 tenex.c: /* * TENEX convert - convert tenex 36-bit files into standard 8-bit * byte stream by discarding every 9th nibble (hopefully its zero). * Also convert TENEX 7-bit ASCII to standard 8-bit byte ASCII by * discarding every 36th bit. * * Written by Daniel Ts'o, dan@rna.rockefeller.edu, 9/7/88 * * Usage: tenex [-[t|b]] [-[v|q]] [files...] * * -t Convert 5x7bit ASCII (35+1bit packing) into 8-bit byte stream * -b Convert 4*8bit binary (32+4bit packing) into 8-bit byte stream (Default is -b) * -v Print progress on stderr * -q Quietly delete nonzero bits * * If file arguments are given, they are converted "in place", using * temporary file "tenex.tmp". * If file arguments are missing, convert stdin to stdout (filter mode). * * Compile with MSC 5.0 on MSDOS: * * cl tenex.c \lib\setargv.obj /link /NOE * * to permit wildcard expansion. */ #include <stdio.h> #define TEMPFILE "tenex.tmp" /*#define RENAME /* Some UNIX's don't have rename() */ #ifdef MSDOS #define READMODE "rb" #define WRITEMODE "wb" #include <fcntl.h> #include <io.h> #else #define READMODE "r" #define WRITEMODE "w" #endif char *nodename; int vflag = 0; int qflag = 0; int tflag = 0; main(c,v) char **v; { register int i,f; FILE *ifd, *ofd; char ibuf[BUFSIZ]; char obuf[BUFSIZ]; f = 0; nodename = *v; setbuf(stdin, ibuf); setbuf(stdout, obuf); while (c > 1 && v[1][0] == '-') { c--; v++; switch (v[0][1]) { case 'v': vflag++; break; case 'q': qflag++; break; case 't': tflag++; break; case 'b': tflag = 0; break; default: fprintf(stderr, "%s:%s: Bad option\n", nodename, *v); exit(-1); } } #ifdef MSDOS if (setmode(fileno(stdin), O_BINARY) == -1 || setmode(fileno(stdout), O_BINARY) == -1) { fprintf(stderr, "%s: Cannot setmode on stdio\n", nodename); exit(1); } #endif if (--c <= 0) exit(xfer(stdin, stdout, "(stdin)")); else { while (c--) { v++; if (**v == '-' && v[0][1] == 0) { xfer(stdin, stdout, "(stdin)"); clearerr(stdin); } else { unlink(TEMPFILE); if ((ifd = fopen(*v, READMODE)) == NULL) { fprintf(stderr, "%s: %s: Can't open\n", nodename, *v); f++; break; } else if ((ofd = fopen(TEMPFILE, WRITEMODE)) == NULL) { fprintf(stderr, "%s: %s: Can't open\n", nodename, TEMPFILE); f++; break; } else if (xfer(ifd, ofd, *v) == 0) { fclose(ifd); fclose(ofd); if (unlink(*v)) { fprintf(stderr, "%s: %s: Can't unlink\n", nodename, *v); f++; break; } if (rename(TEMPFILE, *v)) { fprintf(stderr, "%s: %s: Can't rename\n", nodename, *v); f++; break; } } } } } exit(f ? -1 : 0); } xfer(ifd, ofd, name) FILE *ifd; FILE *ofd; char *name; { if (vflag) { fprintf(stderr, "%s: %s", nodename, name); if (tflag) fprintf(stderr, " (text mode)\n"); else fprintf(stderr, " (binary mode)\n"); } if (tflag) return txfer(ifd, ofd, name); else return bxfer(ifd, ofd, name); } bxfer(ifd, ofd, name) FILE *ifd; FILE *ofd; char *name; { register int icnt, ocnt, ncnt, ci, co, c; icnt = 0; ocnt = 0; ncnt = 0; co = ci = c = 0; for (;;) { if (icnt <= 0) { if ((ci = getc(ifd)) == EOF) { if (ocnt > 0) { fprintf(stderr, "%s: 0x%x: Warning, unpaired ending nibble in file %s\n", nodename, co, name); putc(co, ofd); } break; } else { icnt = 1; c = ci>>4; } } else { icnt = 0; c = ci&017; } if (++ncnt >= 9) { ncnt = 0; if (c != 0 && !qflag) fprintf(stderr, "%s: 0x%x: Warning, nonzero nibble discarded from file %s\n", nodename, c, name); continue; } if (++ocnt >= 2) { co |= c; putc(co, ofd); if (ferror(ofd)) break; co = 0; ocnt = 0; } else co |= c<<4; } fflush(ofd); } txfer(ifd, ofd, name) FILE *ifd; FILE *ofd; char *name; { register int icnt, ocnt, ncnt, ci, co, c; icnt = 0; ocnt = 0; ncnt = 0; co = ci = c = 0; for (;;) { if (icnt <= 0) { if ((ci = getc(ifd)) == EOF) { if (ocnt > 0) { fprintf(stderr, "%s: 0x%x: Warning, incomplete ending byte in file %s\n", nodename, co, name); putc(co, ofd); } break; } else { ci &= 0377; icnt = 7; c = ci>>7; } } else { icnt--; c = (ci>>icnt)&1; } if (++ncnt >= 36) { ncnt = 0; if (c != 0 && !qflag) fprintf(stderr, "%s: Warning, nonzero bit discarded from file %s\n", nodename, name); continue; } if (++ocnt >= 7) { co |= c; putc(co, ofd); if (ferror(ofd)) break; co = 0; ocnt = 0; } else co |= c<<(7-ocnt); } fflush(ofd); } #ifdef RENAME rename(a, b) char *a, *b; { register int f; if (f = link(a, b)) return f; return unlink(a); } #endif