[comp.binaries.ibm.pc] cr and cr/lf filters

W8SDZ@SIMTEL20.ARPA (Keith Petersen) (04/11/88)

Alex Woo <woo@pioneer.arc.nasa.gov> writes:
> I noticed that you put cr/lf's on the rz/sz posting.  Do you have some
> convenient filters running on PC's or UNIX with can switch between
> lf and cr/lf?  I prefer to compress my text files before transmittal
> but the UNIX end has trouble with cr/lf.  (Epsilon does the conversion]
> automatically for me.)

Yes, indeed!  Chuck Forsberg has an excellent Unix utility called
"undos" which converts to/from Unix, MSDOS, CP/M, and MAC text files.
It handles wild cards too!  For instance, if you extracted the
rzszzm12.arc files on your Unix host you can convert the whole package
to Unix end-of-lines by invoking:  tounix *   (be sure to move the arc
elsewhere before doing this and do it in a new directory that has only
the rz/sz files in it!).

Chuck's program, undos, senses the name you used to invoke it, so you
can use "ln" to link it to appear as the other programs.

Here is how to install it:

cc -O undos.c -o undos
ln undos tounix
ln undos todos
ln undos tocpm
ln undos unmac

Move undos, tounix, todos, tocpm, and unmac to your bin directory and
you're ready to go.

Keith Petersen
Maintainer of the MSDOS archives at SIMTEL20.ARPA

# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#         undos.1        undos.c
#
echo 'x - undos.1'
sed 's/^X//' <<'________This_Is_The_END________' >>undos.1
X.TH UNDOS 1 OMEN
X.SH NAME
Xundos,tounix,todos,tocpm,tomac,unmac \- Change
XASCII file format for target operating system
X.SH SYNOPSIS
X.B undos
X[
X.B -s
X]
Xfile ...
X.br
X.B tounix
X[
X.B -s
X]
Xfile ...
X.br
X.B todos
X[
X.B -s
X]
Xfile ...
X.br
X.B tocpm
X[
X.B -s
X]
Xfile ...
X.br
X.B unmac
X[
X.B -s
X]
Xfile ...
X.br
X.B tomac
X[
X.B -s
X]
Xfile ...
X.SH DESCRIPTION
X.B Undos
Xand
X.B tounix
Xconvert DOS or CP/M format source files to Unix format by deleting
Xcarriage returns preceding linefeeds and eliminating characters
Xstarting with CPMEOF (^Z).
X.PP
X.B Todos
Xconverts Unix format source files to DOS format by adding a carriage return
X(if not already present) before each linefeed,
Xand eliminates characters
Xstarting with CPMEOF (^Z).
X.B Tocpm
Xadditionally appends CPMEOF (^Z) characters to the resulting file
Xto make the file length a multiple of the 128 byte CP/M record length.
X
XAny combination of
X.B undos, todos,
Xor
X.B tocpm
X(without flags)
Xmay be applied to a proper ASCII
Xfile without destroying information.
XLone carriage returns used to force overprinting are not translated
Xto CR/LF pairs.
X
X.B Unmac
Xconverts files with lines terminated only by carriage return
Xto Unix format.
X.B Unmac
Xshould only be used to translate files whose lines are terminated
Xby lone carriage returns.
X
X.B Tomac
Xconverts Unix format files to Macintosh format
X(lines terminated by carriage return only).
X
XThe optional flag
X.B -s
XStrips the parity bit on all characters
Xand discards all resulting characters with values less than 7.
X
XThe access and modification times of the modified files are set
Xto those of the original files.
X.SH DIAGNOSTICS
XRefuses to translate files in which "binary" characters (less than 7
Xor greater than 127) are seen before CPMEOF.
XRefuses to translate files
Xwith ultra long lines.
XRefuses to translate special files.
X.SH NOTES
XShould be executed with the current directory in the same filesystem
Xas the target files for minimum disk i/o.
X.SH BUGS
XDoes not detect short files without linefeeds.
X.B Unmac
Xand
X.B tomac
Xcannot handle files with CR-only overprinting.
X(ASCII allows either LF or CR/LF to delimit lines, but not CR.)
X.SH SEE ALSO
Xlar(1), yam(1), sq(1), usq(1), rb(omen), sb(omen)
________This_Is_The_END________
echo 'x - undos.c'
sed 's/^X//' <<'________This_Is_The_END________' >>undos.c
X/*% cc -O -K % -o undos
X *
X * Undos - change DOS format files to Unix, etc.
X */
Xchar ID[] =
X "Undos Rev 12-07-85 (C)Copyright Omen Technology Inc All Rights Reserved\n";
X/*
X * This program and documentation may be copied, used, or modified
X *  by Professional-YAM and POWERCOMM licensees provided these notices are
X * not removed.  Others may use this program for non-profit purposes only.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#define LL 1024
X#define SUB 032
X
Xchar Lbuf[LL];
Xchar *Progname;
Xint Todos = 0;
Xint Tocpm = 0;
Xint Tomac = 0;
Xint Unmac = 0;
Xint Strip = 0;
X
Xmain(argc, argv)
Xchar **argv;
X{
X	Progname = *argv;
X	if (! strcmp(Progname, "tocpm"))
X		Todos = Tocpm = 1;
X	if (! strcmp(Progname, "todos"))
X		Todos = 1;
X	if (! strcmp(Progname, "unmac"))
X		Unmac = 1;
X	if (! strcmp(Progname, "tomac"))
X		Tomac = 1;
X
X	if (! strcmp(argv[1], "-s")) {
X		++Strip; --argc; ++argv;
X	}
X
X
X	if (argc<2 || *argv[1]== '-')
X		usage();
X	while (--argc >= 1)
X		chngfmt(*++argv);
X	exit(0);
X}
Xusage()
X{
X	fprintf(stderr, ID);
X	fprintf(stderr, "Usage: {undos|tounix|todos|tocpm|unmac} [-s] file ...\n");
X	fprintf(stderr, "	-s Strip parity bit, ignore bytes < 007\n");
X	exit(1);
X}
X
X
Xchngfmt(name)
Xchar *name;
X{
X	register c;
X	register char *p;
X	register n;
X	register long fpos;
X	struct stat st;
X	FILE *fin, *fout;
X	int linno = 0;
X	long ftell();
X	char *mktemp();
X	char outnam[64];
X
X	if (stat(name, &st)) {
X		xperror(name); return;
X	}
X	if ((st.st_mode & S_IFMT) != S_IFREG) {
X		fprintf(stderr, "%s: %s is not a regular file\n", Progname, name);
X		return;
X	}
X	if ((fin = fopen(name, "r")) == NULL) {
X		xperror(name); return;
X	}
X	strcpy(outnam, "undosXXXXXX");
X	mktemp(outnam);
X	if ((fout = fopen(outnam, "w")) == NULL) {
X		xperror(outnam); exit(1);
X	}
X
X	for (;;) {
X		++linno;
X		for (p=Lbuf, n=LL; --n>0; ) {
Xignore:
X			if ((c = getc(fin)) == EOF)
X				break;
X			if ( !c)
X				goto ignore;
X			if (c < '\7' || (c & 0200)) {
X				if (Strip) {
X					if ((c &= 0177) < 7)
X						goto ignore;
X				} else
X					goto thisbin; 
X			}
X			if (c == SUB)
X				break;
X			if (c == '\r' && Unmac)
X				c = '\n';
X			*p++ = c;
X			if (c == '\n')
X				break;
X		}
X		*p = '\0';
X
X		if (n == 0) {
X	thisbin:
X			if (n) {
X				fprintf(stderr, "%s: %s is a binary file", Progname, name);
X				fprintf(stderr, " line=%d char =%2X\n", linno, c);
X			} else
X				fprintf(stderr, "%s: %s has no linefeeds: try unmac?\n", Progname, name);
X			fclose(fout);
X			unlink(outnam);
X			return;
X		}
X
X		if (Todos) {
X			if (*--p == '\n' && p[-1] != '\r') {
X				*p++ = '\r'; *p++ = '\n'; *p = 0;
X			}
X		} else if (Tomac) {
X			if (*--p == '\n') {
X				if (p[-1] == '\r')
X					--p;
X				*p++ = '\r'; *p = 0;
X			}
X		} else {
X			if (*--p == '\n' && *--p == '\r') {
X				*p++ = '\n'; *p = 0;
X			}
X		}
X		if (fputs(Lbuf, fout) == EOF) {
X			xperror(outnam); exit(1);
X		}
X		switch (c) {
X		case EOF:
X			if (ferror(fin)) {
X				xperror(name); exit(0200);
X			}
X		case SUB:
X			if (Tocpm) {
X				fpos = ftell(fout);
X				do {
X					putc(SUB, fout);
X				} while (++fpos & 127);
X			}
X			fclose(fout); fclose(fin);
X			if (st.st_nlink > 1) 
X				sprintf(Lbuf, "cp %s %s", outnam, name);
X			else
X				sprintf(Lbuf, "mv %s %s", outnam, name);
X			system(Lbuf);
X			utime(name, (struct utimbuf *) &st.st_atime);
X			if (st.st_nlink > 1) 
X				unlink(outnam);
X			return;
X		}
X	}
X}
X
Xxperror(s)
Xchar *s;
X{
X	register char *p;
X	extern int sys_nerr;
X	extern char *sys_errlist[];
X	extern errno;
X
X	if (errno >= sys_nerr)
X		p = "Gloryovsky: a New Error!";
X	else
X		p = sys_errlist[errno];
X	fprintf(stderr, "%s: %s: %s\n", Progname, s, p);
X}
________This_Is_The_END________
exit