--- /dev/null
+/*****************************************************************************
+
+NAME
+ mstrans.c -- translate MS-DOS and Wordstar text files into pure ASCII
+
+SYNOPSIS
+ mstrans [-vwcr] [file...]
+
+DESCRIPTION
+ This program may be used to filter MS-DOS text files for UNIX and/or
+ASCII-ize WordStar document files
+ MS-DOS text files use an <CR><LF> terminator rather than UNIX's <LF>.
+They end with control-Z characters (hex 1A) filling out their last 128
+bytes. This filter squeezes out control-Z characters. The UNIX version of
+this program strips CRs by default; the MS-DOS version doesn't. The -c
+inverts the default.
+ WordStar text files use the meta bits of characters as formatting
+information; the -w option strips those off. It also turns WordStar hyphens
+into ASCII hyphens and discards the invisible hyphen-break marks left when
+hyphenation changes. These WordStar translations should be harmless to
+ordinary text and program files.
+ If called with no arguments, this tool will filter standard input to
+standard output. If given arguments, it assumes they are all-caps MS-DOS
+filenames and translates each into a UNIX equivalent in all small letters.
+It will not translate a file with a name that is already all smalls, and
+the UNIX version will not attempt to translate directory files. Thus, invoking
+
+ mstrans *
+
+in a directory containing MS-DOS files with all-caps names will do the
+right thing.
+ The -r option reverses these transformations, turning <LF> into <LF><CR>.
+
+NOTE
+ On UNIX, compile with -DUNIX as an option. This will enable the skipping
+of directory files and make CR-stripping the default. On MS-DOS or CP/M,
+compile without this option to make no CR stripping the default.
+
+HISTORY
+ Eric S. Raymond created 18 Oct 85
+
+****************************************************************************/
+
+#define UNIX
+
+#include <stdio.h>
+
+#ifdef UNIX
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
+#define PATHLEN 64
+#define TRUE 1
+#define FALSE 0
+
+/* characters to treat specially */
+#define LF '\012' /* ASCII line feed */
+#define CR '\015' /* ASCII carriage return */
+#define CTRLZ '\032' /* MS-DOS uses this to end text files */
+#define SOFTH '\037' /* WordStar visible soft hyphen */
+#define HMARK '\036' /* WordStar invisible hyphen break mark */
+
+/* option flags */
+int verbose = FALSE; /* be chatty about skipped files */
+int wordstar = FALSE; /* do WordStar translations */
+int reverse = FALSE; /* reverse translation, UNIX to MS-DOS */
+#ifdef UNIX
+int stripcr = TRUE; /* by default, strip carriage returns on UNIX */
+#else
+int stripcr = FALSE; /* MS-DOS, CP/M etc use <CR><LF>; keep CRs */
+#endif /* UNIX */
+
+mstrans()
+{
+ register int c;
+
+ while ((c = getchar()) != EOF)
+ {
+ /* do to-MSDOS translations if enabled */
+ if (reverse && c == LF)
+ {
+ putchar(CR);
+ putchar(LF);
+ continue;
+ }
+
+ /* strip out MS-DOS end-of-file marks */
+ else if (c == CTRLZ || (c == CR && stripcr))
+ continue;
+
+ /* do WordStar translations if enabled */
+ if (wordstar)
+ {
+ c &= 0x7F; /* strip off WordStar meta bits */
+ if (c == SOFTH)
+ c = '-'; /* change soft hyphens to real ones */
+ else if (c == HMARK)
+ continue; /* discard hyphen break marks */
+ }
+
+ putchar(c);
+ }
+}
+
+main(argc, argv)
+/* process filename arguments */
+int argc;
+char *argv[];
+{
+ char c, dst[PATHLEN];
+ register char *sp, *tp;
+ extern int optind;
+#ifdef UNIX
+ struct stat fs;
+#endif
+
+ while ((c = getopt(argc, argv, "vcwr")) != EOF)
+ if (c == 'v')
+ verbose = TRUE;
+ else if (c == 'w')
+ wordstar = TRUE;
+ else if (c == 'r')
+ reverse = TRUE;
+ else if (c == 'c')
+ stripcr = !stripcr;
+
+ if (optind == argc)
+ mstrans();
+ else
+ for (; optind < argc; optind++)
+ {
+#ifdef UNIX
+ /* if the name is of anything but a file, skip it */
+ if (stat(argv[optind], &fs) || (fs.st_mode & S_IFMT) != S_IFREG)
+ {
+ if (verbose)
+ fprintf(stderr,
+ "mstrans: %s is a directory or special file\n",
+ argv[optind]);
+ continue;
+ }
+#endif /* UNIX */
+
+ /* generate an all-smalls version of the all-caps MS-DOS name */
+ tp = dst;
+ for (sp = argv[optind]; *sp; sp++)
+ if (reverse)
+ *tp++ = toupper(*sp);
+ else
+ *tp++ = tolower(*sp);
+ *tp = 0;
+
+ /* if the name is already all-smalls, forget it */
+ if (strcmp(argv[optind], dst) == 0)
+ {
+ if (verbose)
+ fprintf(stderr,
+ "mstrans: skipping %s\n",
+ argv[optind]);
+ continue;
+ }
+
+ /* if we can open both source and destination file, translate */
+ if (freopen(argv[optind], "r", stdin) && freopen(dst, "w",stdout))
+ {
+ if (verbose)
+ fprintf(stderr,
+ "mstrans: translating %s to %s\n",
+ argv[optind], dst);
+ mstrans();
+ }
+ }
+}
+
+/* mstrans.c ends here */