Submitted-By: Soenke Behrens (sbeh...@contech.demon.co.uk)
Posting-number: Volume 1, Source 101
Archive-Name: gno/util/udl.01
Architecture: 2gs,UNIX
Version-Number: 1.14
Udl converts text files between the various end-of-line conventions, i.e.
CR, LF, and CR/LF, used by the Apple IIgs, MS-DOS, Amiga, and Unix.
After conversion, the original file is replaced with the converted file.
Udl is known to run with ORCA/Shell 2.x, GNO/ME 2.x, and Unix. Udl is
faster and simpler than tr(1).
Enjoy.
********************************************************************************
=Manifest
-History
-Makefile.gs
-Makefile.unix
-Manifest
-README
-common.c
-common.h
-globals.c
-udl.1
-udl.DESCRIBE
-udl.gs.c
-udl.online
-udl.rez
-udl.unix.c
-udluse.c
=README
-
-udl
-
-Udl converts text files between the various end-of-line conventions, i.e.
-CR, LF, and CR/LF, used by the Apple IIgs, MS-DOS, Amiga, and Unix.
-After conversion, the original file is replaced with the converted file.
-Udl is known to run with ORCA/Shell 2.x, GNO/ME 2.x, and Unix.
-
-Not only is udl faster and simpler than tr(1), but it saves a setp in
-the conversion process by automatically replacing the original file
-after the conversion completes. Thus:
- udl file
-replaces the longer sequence of
- tr '\012' '\015' < file > file.temp
- mv file.temp file
-Because it replaces the original file, udl makes every effort to ensure
-that the conversion process cannot corrupt the original. The translation
-process uses a temporary file and replacing the original only after the
-translation has completed. In case of a machine crash or power-down, the
-original file remains intact, unless the machine dies at precisely the
-instant the update occurs. This problem exists for a manual file
-replacement, as in:
- mv file.temp file
-so the risk is no greater.
-
-=========
-Compiling:
-=========
-
-Two makefiles are included:
- Makefile.gs For use on the Apple IIgs running GNO
- Makefile.unix For use with Unix systems
-
-The IIgs version of udl cannot be built with the standard ORCA installation
-because it requires libraries only available under GNO or Unix. Once
-built, however, udl can be run from either the GNO or ORCA shells.
-
-Before building udl, you will need to customize the Makefile based on
-the operating system you are building under.
-
-The available compile time customization is shown below:
-
- BROKEN_DIRENT_STRUCT
- Used to get round a bug in Solaris, the declaration
- of dirent in sys/stat.h does not coincide with the
- actual implementation of stat(3).
-
- BROKEN_REALLOC
- Use this if your realloc(3) does not behave like
- malloc(3) when being passed a NULL pointer.
-
- CHECK_STACK
- udl maintains some internal sanity checks to help prevent
- endless looping from consuming all of memory. Using this
- define will slow execution down negligibly.
-
- GNO
- Used when building the Apple IIgs version under the
- GNO/ME operating system.
-
- HAS_ATEXIT
- Use if your library contains atexit(3).
-
- OVERFLOW_CHECK
- Check for system stack overflow in the Apple IIgs
- version. Invokes calls to the freeware "stack"
- library to show used stack space after each run.
-
- READDIR_RETURNS_DOT
- Use if readdir(3) returns the entries "." and ".."
- in addition to the files in the current directory.
-
- _POSIX_C_SOURCE
- _POSIX_SOURCE
- Use these defines if your compiler is POSIX compliant
- (these defines are used only by system header files).
-
-Defines that are known to work for various Unix systems are listed below:
-
- SunOS 4.x (tested with gcc)
- -DREADDIR_RETURNS_DOT -DBROKEN_REALLOC
- -D_POSIX_C_SOURCE -D_POSIX_SOURCE
-
- SunOS 5.x (aka Solaris) (tested with SUNWspro cc)
- -DREADDIR_RETURNS_DOT -DBROKEN_DIRENT_STRUCT
- -D_POSIX_C_SOURCE -D_POSIX_SOURCE
-
- AIX 3.2 (tested with xlc)
- -DBROKEN_REALLOC -D_POSIX_C_SOURCE -D_POSIX_SOURCE
-
-udl.unix.c assumes that getopt() is declared in <unistd.h> and that the
-function strdup() exists in <string.h>. These includes will need
-to be changed if your header files declare them elsewhere.
-
-The IIgs version relies on the use of the GNU getopt() function,
-declared in <getopt.h> and contained in /usr/lib/gnulib. It also
-assumes strdup() to be declared in <string.h> and contained in libc.
-
-=====
-Files
-=====
-
-The following files are present in the udl package:
- README This file
- History Revision history
- Makefile.gs make(1) script for GNO
- Makefile.unix make(1) script for Unix
- common.c Routines common to GNO and Unix versions
- common.h Header file for common.c
- globals.c Global variable definitions
- udl.1 Man page for udl command
- udl.DESCRIBE short description of udl, FTP info
- udl.gs.c Apple IIgs specific routines
- udl.online Formatted version of udl.1
- udl.rez Apple IIgs REZ source for resource fork
- udl.unix.c Unix specific routines
- udluse.c Strings for invocation information
-
-=====
-Notes
-=====
-
-If the machine crashes before udl has replaced the original file with
-the converted file, the temporary file needs to be manually deleted.
-The temporary file resides in the same directory as the source file
-and has a name of the form:
- UDLTMPXX
-where XX is replaced by AA, AB and so on.
-
-=========
-Copyright
-=========
-
-COPYRIGHT 1993-1995 by Soenke Behrens and Devin Reade
-ALL RIGHTS RESERVED
-
-This package may be redistributed so long as no fee is charged, the
-authors' names remain, and all modifications are clearly marked as
-such and the unmodified source is included.
-
-This program contains material from the Orca/C Run-Time Libraries,
-Copyright 1987-1995 by Byte Works, Inc. Used with permission.
-
-=======
-Authors
-=======
-
-Original code by Soenke Behrens <sbeh...@contech.demon.co.uk>
-with modifications and version-merging by Devin Reade <g...@myrias.ab.ca>.
-
-Soenke Behrens
-sbeh...@contech.demon.co.uk
-
-Devin Reade
-g...@myrias.ab.ca
-
-March 1995
-Version 1.14: $Id: README,v 1.6 1995/02/08 06:12:31 gdr Exp $
-
=History
-
-=============================================================================
-udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
- and Apple (CR).
-
- (c) 1993-1995 Soenke Behrens, Devin Reade
-
- Version 1.14: $Id: README,v 1.6 1995/02/08 06:12:31 gdr Exp $
-=============================================================================
-
-Udl converts text files between CR, LF and CR/LF (Apple, Unix and MS-DOS).
-It is a very fast utility that ensures that the integrity of the file
-cannot be compromised during the translation. It is also much easier
-to use than tr(1).
-
-================
-Revision History:
-================
-
-v1.01
- Tabs are left alone now. Also recognizes CR/LF (MeSsy-DOS).
-
-v1.02
- Does no longer read in the complete file, instead creates a temp
- file in prefix 3/.
-
-v1.03
- Fixed a bug, allocated not enough mem for strncpy.
-
-v1.1
- Changed to use static GS/OS strings again. Made faster by factor
- 5.8.
-
-v1.11
- Cleaned the code up a bit, wrote a Makefile, all output by udl is
- prefixed with the name it was invoked with.
-
-v1.12
- Sped up Apple <-> Unix conversion further (factor 1.5).
-
-v1.12 (Unix)
- (December 1993)
- Modified source to produce a Unix version
-
-v1.13
- (Updated by Devin Reade, November 1994)
- Added ability to recurse through directories (-R flag).
- Changed behavior to ignore binary files rather than exiting.
- Merged Unix and Apple IIgs versions.
- No message is printed out when a binary file (or, in the IIgs
- implementation, a non-TXT or non-SRC file) is encountered
- unless the -v option is specified.
-
-v1.14
- (Soenke Behrens, Devin Reade, February 1995)
- udl creates a temporary file in the directory of the
- source file, not in /tmp. This reduces the likelihood of
- data loss in the event of a system crash or powerdown.
- udl now accepts something like "udl -R directory/" without
- affixing an extra '/' to "directory/".
- Fixed bug (via the BROKEN_DIRENT_STRUCT macro) that was causing
- filename-munging on Solaris. It seems that the sys/stat.h header
- file doesn't agree with the stat implementation.
- Modified Makefile.gs to properly write the new executable over
- the old resource fork for udl. The resource fork originates with
- the file udl.r.
- Added suggested defines to the README for various Unix platforms.
- Man page changes, including grammar and the deletion of a bug that
- no longer exists.
- Fixed bug where invoking 'udl -u directory' would attempt to
- deref a NULL pointer, causing either memory tromping (IIgs) or
- a core dump (Unix).
- Tested under SunOS 4.x, SunOS 5.x (Solaris), and AIX.
=Makefile.gs
-#
-# Makefile for udl
-# Copyright (c) 1993-1994 Soenke Behrens
-# For use with dmake
-#
-# $Id: Makefile.gs,v 1.6 1995/02/08 06:12:27 gdr Exp $
-#
-# Define the following as necessary:
-#
-# HAS_ATEXIT if your system has atexit()
-#
-# _POSIX_C_SOURCE and _POSIX_SOURCE if your compiler is Posix compliant
-#
-# READDIR_RETURNS_DOT if your direct readdir() function will return
-# entries for "." and "..". SunOS4 is known to do this.
-#
-# BROKEN_REALLOC if your realloc() doesn't behave like malloc() when
-# passed a NULL pointer as the first argument.
-#
-# GNO if you are compiling on the IIgs. This will allow for both
-# ':' and '/' as pathname separators.
-#
-# OVERFLOW_CHECK Udl uses one recursive subroutine. Define this if
-# you want to check for stack overflows for this routine (independent
-# of any compiler flags). Strongly recommended.
-#
-# CHECK_STACK if you want stack usage to be displayed (IIgs only).
-# You will also have to specify -l/usr/lib/stack in LDFLAGS.
-
-DEFINES = -DGNO -D_POSIX_C_SOURCE -D_POSIX_SOURCE -DHAS_ATEXIT \
- -DOVERFLOW_CHECK
-#CFLAGS = $(DEFINES) -O -w -v -s2048
-#LDFLAGS = -v -l/usr/lib/gnulib -s2048
-CFLAGS = $(DEFINES) -O -v -s2048
-LDFLAGS = -v -s2048
-
-#
-# You should not have to modify anything beyond this point
-#
-
-udl: udl.o udluse.o udl.r common.o globals.o
- -$(RM) udl
- cp udl.r udl
- chtyp -texe udl
- $(CC) $(LDFLAGS) -o udl udl.o udluse.o common.o globals.o
-
-udl.o: udl.gs.c common.h
- $(CC) -c $(CFLAGS) -o udl.o udl.gs.c
-
-install:
- cp -f udl /usr/local/bin
- cp -f udl.1 /usr/man/man1
-
-docs: udl.1
- nroff -man udl.1 >help/udl
-
-clean:
- $(RM) *.o udl
-
-dist:
- @echo "Sorry, automatic packing not supported yet"
-
-common.o:: common.h
-globals.o:: common.h
=Makefile.unix
-#
-# Makefile for udl
-# (c) 1993-1994 Soenke Behrens
-#
-# $Id: Makefile.unix,v 1.6 1995/02/08 06:12:29 gdr Exp $
-#
-# Define the following as necessary:
-#
-# HAS_ATEXIT if your system has atexit()
-#
-# _POSIX_C_SOURCE and _POSIX_SOURCE if your compiler is Posix compliant
-#
-# READDIR_RETURNS_DOT if your direct readdir() function will return
-# entries for "." and "..". SunOS 4.x and 5.x (Solaris) are known to
-# do this.
-#
-# BROKEN_REALLOC if your realloc() doesn't behave like malloc() when
-# passed a NULL pointer as the first argument.
-#
-# BROKEN_DIRENT_STRUCT if you find that the first two letters of
-# filenames obtained during directory recursion (as shown when the
-# "-v" flag is used) seem to be missing. Some installations of
-# Solaris are known to do this.
-#
-
-# If you're on SunOS 4.x systems, use gcc instead; this is ANSI code.
-CC = cc
-DESTDIR = /usr/local/
-BINDIR = bin
-MANDIR = man/man1
-INSTALL = cp -f
-
-# Tried and tested combinations for SunOS and AIX
-SUNOS_4_DEFINES = -DREADDIR_RETURNS_DOT -DBROKEN_REALLOC \
- -D_POSIX_C_SOURCE -D_POSIX_SOURCE
-SUNOS_5_DEFINES = -DREADDIR_RETURNS_DOT -DBROKEN_DIRENT_STRUCT \
- -D_POSIX_C_SOURCE -D_POSIX_SOURCE
-AIX_DEFINES = -DBROKEN_REALLOC -D_POSIX_C_SOURCE -D_POSIX_SOURCE
-
-# Change the next line depending on which OS you have
-DEFINES = SUNOS_4_DEFINES
-
-CFLAGS = $(DEFINES) -O
-LDFLAGS =
-# You may need -lucb in LDLIBS
-LDLIBS = -lucb
-OBJS = udl.o udluse.o common.o globals.o
-
-#
-# You should not have to modify anything beyond this point
-#
-
-udl: $(OBJS)
- $(CC) $(LDFLAGS) -o udl $(OBJS) $(LDLIBS)
-
-udl.o: udl.unix.c common.h
- $(CC) -c $(CFLAGS) -o udl.o udl.unix.c
-
-install:
- $(INSTALL) udl $(DESTDIR)$(BINDIR)
- $(INSTALL) udl.1 $(DESTDIR)$(MANDIR)
-
-clean:
- -rm *.o *~ core
-
-clobber: clean
- -rm udl
-
-dist:
- @echo 'Sorry, automatic packing not yet supported.'
-
-udluse.o common.o globals.o:: common.h
=common.c
-/*
- * udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
- * and Apple (CR).
- *
- * Routines common to both the Unix and Apple IIgs versions.
- *
- * $Id: common.c,v 1.6 1995/02/08 06:12:33 gdr Exp $
- *
- * Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
- */
-
-#ifdef GNO
-#pragma noroot
-#endif
-
-#include "common.h"
-extern char *strdup(const char *);
-
-/*
- * convert_gs() ... convert files to use CR as EOL
- *
- * Inputs:
- * FILE *infile File to read from
- * FILE *outfile File to write to
- *
- * Outputs:
- * None
- */
-
-void convert_gs(FILE *infile, FILE *outfile) {
- unsigned char a;
- unsigned char *in_bufpos;
- unsigned char *out_bufpos;
- unsigned char *in_bufend;
- unsigned char *out_bufend;
- size_t file_remain;
-
- in_bufpos = in_buffer;
- out_bufpos = out_buffer;
-
- (void) fseek(infile,0L,SEEK_END);
- file_remain = ftell(infile);
- rewind(infile);
-
- in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
- out_bufend = out_buffer + BUFFERSIZE;
-
- while (file_remain != 0) {
- a = *in_bufpos;
- in_bufpos++;
-
- if (in_bufpos >= in_bufend) {
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
- in_bufpos = in_buffer;
- }
- /* a = fgetc (infile); */
-
- if(a == '\n') {
- *out_bufpos = '\r';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\r',outfile); */
- } else if(a == '\r') {
- *out_bufpos = '\r';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\r',outfile); */
-
- if (*in_bufpos == '\n' && file_remain != 0) {
- in_bufpos++;
-
- if (in_bufpos >= in_bufend) {
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- in_bufpos = in_buffer;
- }
- }
- /* if ((a = fgetc (infile)) != '\n')
- ungetc (a,infile); */
- } else {
- *out_bufpos = a;
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc(a,outfile); */
- }
- }
- /* Check for remainder in output buffer */
- if (out_bufpos != out_buffer)
- my_fwrite(out_buffer,outfile,out_bufpos - out_buffer);
-}
-
-/*
- * convert_messy() ... convert files to use CR/LF as EOL
- *
- * Inputs:
- * FILE *infile File to read from
- * FILE *outfile File to write to
- *
- * Outputs:
- * None
- */
-
-void convert_messy (FILE *infile, FILE *outfile) {
- unsigned char a;
- unsigned char *in_bufpos;
- unsigned char *out_bufpos;
- unsigned char *in_bufend;
- unsigned char *out_bufend;
- size_t file_remain;
-
- in_bufpos = in_buffer;
- out_bufpos = out_buffer;
-
- (void) fseek(infile,0L,SEEK_END);
- file_remain = ftell(infile);
- rewind(infile);
-
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- out_bufend = out_buffer + BUFFERSIZE;
-
- while (file_remain != 0) {
- a = *in_bufpos;
- in_bufpos++;
-
- if (in_bufpos >= in_bufend) {
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- in_bufpos = in_buffer;
- }
- /* a = fgetc (infile); */
-
- if(a == '\n') {
- *out_bufpos = '\r';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\r',outfile); */
-
- *out_bufpos = '\n';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\n',outfile); */
- } else if(a == '\r') {
- *out_bufpos = '\r';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\r',outfile); */
-
- *out_bufpos = '\n';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\n',outfile); */
-
- if (*in_bufpos == '\n' && file_remain != 0) {
- in_bufpos++;
-
- if (in_bufpos >= in_bufend) {
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- in_bufpos = in_buffer;
- }
- }
- /* if ((a = fgetc (infile)) != '\n')
- ungetc (a,infile); */
- } else {
- *out_bufpos = a;
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc(a,outfile); */
- }
- }
- /* Check for remained in output buffer */
- if (out_bufpos != out_buffer)
- my_fwrite(out_buffer,outfile,out_bufpos - out_buffer);
-}
-
-/*
- * convert_tunix() ... convert files to use LF as EOL
- *
- * Inputs:
- * FILE *infile File to read from
- * FILE *outfile File to write to
- *
- * Outputs:
- * None
- */
-
-void convert_tunix (FILE *infile, FILE *outfile) {
- unsigned char a;
- unsigned char *in_bufpos;
- unsigned char *out_bufpos;
- unsigned char *in_bufend;
- unsigned char *out_bufend;
- size_t file_remain;
-
- in_bufpos = in_buffer;
- out_bufpos = out_buffer;
-
- (void) fseek(infile,0L,SEEK_END);
- file_remain = ftell(infile);
- rewind(infile);
-
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- out_bufend = out_buffer + BUFFERSIZE;
-
- while (file_remain != 0) {
- a = *in_bufpos;
- in_bufpos++;
-
- if (in_bufpos >= in_bufend) {
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- in_bufpos = in_buffer;
- }
- /* a = fgetc (infile); */
-
- if(a == '\r') {
- *out_bufpos = '\n';
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc('\n',outfile); */
-
- if (*in_bufpos == '\n' && file_remain != 0) {
- in_bufpos++;
-
- if (in_bufpos >= in_bufend) {
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- in_bufpos = in_buffer;
- }
- }
- /* if ((a = fgetc (infile)) != '\n')
- ungetc (a,infile); */
- } else {
- *out_bufpos = a;
- out_bufpos++;
- if (out_bufpos == out_bufend) {
- my_fwrite(out_buffer,outfile,BUFFERSIZE);
- out_bufpos = out_buffer;
- }
- /* fputc(a,outfile); */
- }
- }
- /* Check for remainder in output buffer */
- if (out_bufpos != out_buffer)
- my_fwrite(out_buffer,outfile,out_bufpos - out_buffer);
-}
-
-/*
- * convert_fast_gs() ... convert files to use CR as EOL
- * Do not care about differing EOL chars in the same file,
- * do not allow '\0' bytes, and replace in-vitro if possible.
- *
- * Inputs:
- * FILE *infile File to read from
- * FILE *outfile File to write to
- *
- * Outputs:
- * int FALSE if no conversion took place, TRUE otherwise
- */
-
-int convert_fast_gs(FILE *infile, FILE *outfile) {
- unsigned char a;
- unsigned char *in_bufpos;
- unsigned char *out_bufpos;
- unsigned char *in_bufend;
- unsigned char *out_bufend;
- size_t file_remain;
- enum file_format infile_type;
-
- in_bufpos = in_buffer;
- out_bufpos = out_buffer;
-
- (void) fseek(infile,0L,SEEK_END);
- file_remain = ftell(infile);
- rewind(infile);
-
- in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
- out_bufend = out_buffer + BUFFERSIZE;
- *in_bufend = '\0';
-
- infile_type = get_file_format (in_buffer);
-
- switch (infile_type) {
- case apple:
- if (verbose)
- printf("%s: %s is already in Apple format, skipping.\n",
- program_name,current_file);
- return (FALSE);
- break;
-
- case tunix:
- /* Replace "in-vitro", so out_buffer isn't used */
- while (file_remain != 0) {
- a = *in_bufpos;
- if (a == '\n')
- *in_bufpos++ = '\r';
- else if (a == '\0') { /* End of buffer reached */
-
- /* Write changed buffer out */
- my_fwrite(in_buffer,outfile,in_bufend - in_buffer);
-
- /* And reload it */
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- *in_bufend = '\0';
- in_bufpos = in_buffer;
- } else in_bufpos++;
- }
- return (TRUE);
- break;
-
- case dos:
- /* This I couldn't speed up, so use the existing thing */
- convert_gs (infile, outfile);
- return (TRUE);
- break;
-
- case binary:
- return (FALSE);
- break;
-
- default:
- fprintf(stderr,"%s: Fatal internal error\n",program_name);
- exit (EXIT_FAILURE);
- break;
- } /* switch */
-}
-
-/*
- * convert_fast_messy() ... convert files to use CR/LF as EOL
- * Just check if it's already in DOS format.
- *
- * Inputs:
- * FILE *infile File to read from
- * FILE *outfile File to write to
- *
- * Outputs:
- * int FALSE if no conversion took place, TRUE otherwise
- */
-
-int convert_fast_messy (FILE *infile, FILE *outfile) {
- unsigned char *in_bufpos;
- unsigned char *out_bufpos;
- unsigned char *in_bufend;
- unsigned char *out_bufend;
- size_t file_remain;
- enum file_format infile_type;
-
- in_bufpos = in_buffer;
- out_bufpos = out_buffer;
-
- (void) fseek(infile,0L,SEEK_END);
- file_remain = ftell(infile);
- rewind(infile);
-
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- out_bufend = out_buffer + BUFFERSIZE;
- *in_bufend = '\0';
-
- infile_type = get_file_format (in_buffer);
-
- switch (infile_type) {
- case dos:
- if (verbose)
- printf("%s: %s is already in MS-DOS format, skipping.\n",
- program_name,current_file);
- return (FALSE);
- break;
-
- case tunix: /* drop through */
- case apple:
- /* Wasn't able to speed this up, call old routine */
- convert_messy (infile, outfile);
- return (TRUE);
- break;
-
- case binary:
- return (FALSE);
- break;
-
- default:
- fprintf(stderr,"%s: Fatal internal error\n",program_name);
- exit (EXIT_FAILURE);
- break;
- } /* switch */
-}
-
-/*
- * convert_fast_tunix() ... convert files to use LF as EOL
- * Do not care about differing EOL chars in the same file,
- * do not allow '\0' bytes, and replace in-vitro if possible.
- *
- * Inputs:
- * FILE *infile File to read from
- * FILE *outfile File to write to
- *
- * Outputs:
- * int FALSE if no conversion took place, TRUE otherwise
- */
-
-int convert_fast_tunix (FILE *infile, FILE *outfile) {
- unsigned char a;
- unsigned char *in_bufpos;
- unsigned char *out_bufpos;
- unsigned char *in_bufend;
- unsigned char *out_bufend;
- size_t file_remain;
- enum file_format infile_type;
-
- in_bufpos = in_buffer;
- out_bufpos = out_buffer;
-
- (void) fseek(infile,0L,SEEK_END);
- file_remain = ftell(infile);
- rewind(infile);
-
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- out_bufend = out_buffer + BUFFERSIZE;
- *in_bufend = '\0';
-
- infile_type = get_file_format (in_buffer);
-
- switch (infile_type) {
- case tunix:
- if (verbose)
- printf("%s: %s is already in Unix format, skipping.\n",
- program_name,current_file);
- return (FALSE);
- break;
-
- case apple:
- /* Replace "in-vitro", so out_buffer isn't used */
- while (file_remain != 0) {
- a = *in_bufpos;
- if (a == '\r')
- *in_bufpos++ = '\n';
- else if (a == '\0'){ /* End of buffer reached */
-
- /* Write changed buffer out */
- my_fwrite(in_buffer,outfile,in_bufend - in_buffer);
-
- /* And reload */
- file_remain -= in_bufend - in_buffer;
- in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
- *in_bufend = '\0';
- in_bufpos = in_buffer;
- } else in_bufpos++;
- }
- return (TRUE);
- break;
-
- case dos:
- /* Couldn't speed it up, so use old routine */
- convert_tunix (infile, outfile);
- return (TRUE);
- break;
-
- case binary:
- return (FALSE);
- break;
-
- default:
- fprintf(stderr,"%s: Fatal internal error\n", program_name);
- exit (EXIT_FAILURE);
- break;
- } /* switch */
-}
-
-/*
- * get_file_format() ... look at a buffer and find out what the EOL
- * character is. If no EOL character is found, print an error message
- * and exit.
- *
- * Inputs:
- * unsigned char *buffer Buffer to search through, terminated
- * by '\0'.
- *
- * Output:
- * enum file_format tunix, dos, apple, or binary
- */
-
-enum file_format get_file_format (unsigned char *buffer) {
- unsigned char c;
- enum file_format result = 0;
-
- while ((c = *buffer++) != '\0') {
- if (c == '\n') {
- result = tunix;
- break;
- } else if (c == '\r') {
- if (*buffer == '\n')
- result = dos;
- else
- result = apple;
- break;
- }
- }
-
- if (result == 0) {
- if (verbose)
- printf("%s: No EOL found on the first %d bytes "
- "of %s. Might be a binary file. File skipped\n",
- program_name,BUFFERSIZE, current_file);
- result = binary;
- }
-
- return (result);
-}
-
-/*
- * tryopen() ... try to open a file, exit if unsuccesful
- *
- * Inputs:
- * char *name Name of file to be opened
- * char *mode Mode string for fopen() call
- *
- * Output:
- * FILE * File identifier of successful fopen()
- */
-
-FILE *tryopen (char *name, char *mode) {
- FILE *tmp;
-
- if ((tmp = fopen(name,mode)) == NULL) {
- fprintf(stderr,"%s: Unable to open file %s\n",program_name, name);
- exit (EXIT_FAILURE);
- } else
- return (tmp);
-}
-
-/*
- * my_fread() ... read data into global buffer and exit if I fail
- *
- * Inputs:
- * FILE *infile File to read from
- * int howmuch Number of bytes to read
- *
- * Output:
- * int Number of bytes actually read
- */
-
-int my_fread(FILE *infile, int howmuch) {
- int result;
-
- result = fread(in_buffer, 1, howmuch, infile);
- if (ferror(infile)) {
- fprintf(stderr,"%s: Error while reading data\n",program_name);
- exit (EXIT_FAILURE);
- }
-
- return (result);
-}
-
-/*
- * my_fwrite() ... write data from global buffer to file
- *
- * Inputs:
- * unsigned char *buffer Buffer to write out
- * FILE *outfile File to write to
- * int howmuch Number of bytes to write
- *
- * Output:
- * None
- */
-
-void my_fwrite (unsigned char *buffer, FILE *outfile, int howmuch) {
- fwrite(buffer, 1, howmuch, outfile);
- if (ferror(outfile)) {
- fprintf(stderr,"%s: Error while writing data\n",program_name);
- exit (EXIT_FAILURE);
- }
-
- return;
-}
-
-/*
- * cleanup() ... called in case of an exit(). Frees memory I allocated.
- *
- * Inputs:
- * None
- *
- * Output:
- * None
- */
-
-void cleanup (void) {
- char **p;
-
- free (program_name);
- free (current_file);
- free (in_buffer);
- free (out_buffer);
- free (tempfile);
- if (pathList) {
- p = pathList;
- while(*p) free(*p++);
- free (pathList);
- }
-
- if (tempfile)
- remove (tempfile);
-}
-
-/*
- * usage() ... print out a usage string gotten from udluse.c
- *
- * Inputs:
- * None
- *
- * Outputs:
- * None
- */
-
-void usage (void) {
- extern char use1[]; /* from udluse.c */
-#ifdef GNO
- extern char use2[];
-#endif
-
- fprintf(stderr,"%s",use1);
-#ifdef GNO
- if(!needsgno())
- fprintf(stderr,"%s",use2);
-#endif
-
- return;
-}
-
-/*
- * build_file_list() build the list of files to process
- *
- * Precondition:
- * file is the file name to be added to the pathList
- * recurse if non-zero, directories will be recursed
- *
- * Postcondition:
- * pathList will be a NULL-terminated array of strings. Each
- * string is a partial pathname (relative to rootdir) of a file
- * to convert.
- *
- * Note: This is a recursive routine that uses up (3 * sizeof(char *))
- * bytes of stack with each level of subdirectories.
- */
-
-
-void build_file_list(char *file, short recurse) {
- char *thisdir;
- DIR *dir;
- struct dirent *entry;
-
- /* check for stack overflow */
- recursionDepth++;
-#ifdef OVERFLOW_CHECK
- if ((recursionDepth * BYTES_PER_DEPTH + BASESIZE) > STACKSIZE) {
- fprintf(stderr,"%s: Exceeded permitted nesting depth (%d levels)\n"
- "Aborted.\n",program_name,recursionDepth);
- exit(EXIT_FAILURE);
- }
-#endif
-
- if (stat(file,&tstat)!=0) {
- fprintf(stderr,"%s: Couldn't stat %s. File skipped\n",program_name,file);
- --recursionDepth;
- return;
- }
-
- if (recurse && S_ISDIR(tstat.st_mode)) {
- char tstr[2];
-
- /*
- * It is a directory. recurse through it.
- */
-
- /* save our state */
- tstr[0] = dirbrk;
- tstr[1] = '\0';
- if (*currentDirectory) {
- thisdir = strdup(currentDirectory);
- } else {
- thisdir = malloc(1);
- if (thisdir != NULL) *thisdir='\0';
- }
- if (thisdir == NULL) {
- perror("Couldn't duplicate current directory");
- exit (EXIT_FAILURE);
- }
-
- if (*currentDirectory) strcat(currentDirectory,tstr);
- strcat(currentDirectory,file);
- if (currentDirectory[strlen(currentDirectory)-1] == dirbrk)
- currentDirectory[strlen(currentDirectory)-1] = '\0';
-
- /* recurse */
- if ((dir = opendir(file)) == NULL) {
- fprintf(stderr,"%s: Couldn't open %s. Directory skipped.\n",
- program_name,currentDirectory);
- } else {
- if (chdir(file) !=0) {
- fprintf(stderr,"couldn't cd to %s\n",currentDirectory);
- exit (EXIT_FAILURE);
- }
-
-#ifdef READDIR_RETURNS_DOT
- entry = readdir(dir); /* for "." */
- entry = readdir(dir); /* for ".." */
-#endif
-
- while ((entry = readdir(dir))!=NULL) {
- /* ignore hidden files */
-#ifdef BROKEN_DIRENT_STRUCT
- if (*(entry->d_name)!='.') build_file_list((entry->d_name)-2,1);
-#else
- if (*(entry->d_name)!='.') build_file_list(entry->d_name,1);
-#endif
- }
-
- if (*thisdir) {
- if ((chdir(rootdir)!=0) || (chdir(thisdir)!=0)) {
- fprintf(stderr,"couldn't cd to %s\n",thisdir);
- exit (EXIT_FAILURE);
- }
- } else {
- if (chdir(rootdir)!=0) {
- fprintf(stderr,"couldn't cd to calling directory\n");
- exit (EXIT_FAILURE);
- }
- }
-
- }
-
- /* restore our state */
- strcpy(currentDirectory,thisdir);
- free(thisdir);
-
- } else if (S_ISREG(tstat.st_mode)) {
-
- /* It is a normal file. Add it to the pathList */
- add_to_pathList(currentDirectory, file);
- }
-
- --recursionDepth;
- return;
-}
-
-void add_to_pathList(char *thisdir, char *file) {
- char **p;
-
- /* expand the pathList if necessary */
- if (pathSlotsUsed >= pathSlots) {
- pathSlots += PATHLIST_QUANTUM;
-#if BROKEN_REALLOC
- if ((pathList==NULL) &&
- ((pathList = malloc((pathSlots+1) * sizeof(char *)))==NULL)) {
- fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
- exit (EXIT_FAILURE);
- } else {
- if ((p = realloc(pathList, (pathSlots+1) * sizeof(char *)))==NULL) {
- fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
- exit (EXIT_FAILURE);
- }
- pathList = p;
- }
-#else
- if ((p = realloc(pathList,(pathSlots+1) * sizeof(char *)))==NULL) {
- fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
- exit (EXIT_FAILURE);
- } else pathList = p;
-#endif
- }
-
- /* add in the current directory and filename to the pathList */
- pathList[pathSlotsUsed] = malloc(strlen(thisdir)+strlen(file)+2);
- if (pathList[pathSlotsUsed] == NULL) {
- fprintf(stderr,"%s: Couldn't duplicate filename %s%c%s\n",program_name,
- thisdir,dirbrk,file);
- exit (EXIT_FAILURE);
- }
- if (*thisdir) {
- sprintf(pathList[pathSlotsUsed],"%s%c%s",thisdir,dirbrk,file);
- } else {
- strcpy(pathList[pathSlotsUsed],file);
- }
- pathSlotsUsed++;
- pathList[pathSlotsUsed] = NULL;
- return;
-}
-
-/* mktemp() construct a unique file name
- *
- * Inputs:
- * base Template to construct the name upon. It should
- * be in the format "nameXXXXXX" where all "X" are replaced
- * in such a way that the resulting name is unique. There
- * should be at least one, at most 15 "X" in the base name.
- * base may contain a full or partial path.
- *
- * Outputs:
- * mktemp() returns a pointer to a dynamically allocated string
- * containing a unique file name.
- *
- */
-
-char *mktemp(const char *base)
-{
- static char id[16] = "AAAAAAAAAAAAAAA";
- char *p1,*p2,*st;
-
- if ((st = malloc(strlen(base) + 1)) == NULL)
- {
- fprintf(stderr,"%s: memory allocation failure\n", program_name);
- exit (EXIT_FAILURE);
- }
- st = strcpy(st,base);
-
- if (*st == '\0')
- {
- free (st);
- if ((st = strdup("TXXXXXXX")) == NULL)
- {
- fprintf(stderr,"%s: memory allocation failure\n", program_name);
- exit (EXIT_FAILURE);
- }
- }
-
- /* Replace all "X" with part of ID string */
- for(p1 = st + strlen(st) - 1,p2 = &id[14];
- p1 >= st && p2 >= id && *p1 == 'X';
- p1--,p2--)
- *p1 = *p2;
-
- /* Update ID string to "count" one further */
- for(p1 = &id[14];p1 >= id;)
- if(*p1 == 'Z')
- {
- *p1 = 'A';
- p1--;
- } else {
- *p1 += 1;
- break;
- }
-
- /* Make sure the file name does not already exist */
-#ifdef GNO
- if (needsgno() == TRUE) {
-#endif
- if (stat(st,&tstat) == 0)
- {
- free (st);
- st = mktemp (base);
- }
-#ifdef GNO
- } else { /* ORCA/Shell doesn't like stat one little bit */
- FILE *fp;
- if ((fp = fopen(st,"r")) != NULL)
- {
- fclose(fp);
- free (st);
- st = mktemp (base);
- } else if ((fp = fopen(st,"a")) == NULL) {
- free(st);
- st = mktemp (base);
- } else {
- fclose(fp);
- }
- }
-#endif
-
- return st;
-}
-
-/* get_path() ... extract path from filename
- *
- * Inputs:
- * name A file name containing a full, partial or no path.
- *
- * Outputs:
- * Pointer to a string in static memory containing the path
- * to the given file, or an empty string if "name" contained
- * no path. The string can hold MAXPATHLEN characters.
- */
-
-char *get_path (const char *name)
-{
- int i;
-
- strcpy(filebuffer, name);
-
- for (i = strlen(filebuffer) - 1; i > 0 && filebuffer[i] != dirbrk; i--)
- ; /* empty loop to find end of path in name */
-
- if (i != 0)
- ++i;
- filebuffer[i] = '\0';
- return filebuffer;
-}
-
-/* End Of File */
=common.h
-/*
- * udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
- * and Apple (CR).
- *
- * Header file for routines common to both the Unix and Apple IIgs versions.
- *
- * $Id: common.h,v 1.6 1995/02/08 06:12:36 gdr Exp $
- *
- * Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <dirent.h>
-
-#define BUFFERSIZE 0x2000
-#define PATHLIST_QUANTUM 20
-#define UDL_VERSION "Version 1.14"
-#define STACKSIZE 2048
-#define BYTES_PER_DEPTH 40
-#define BASESIZE 700
-
-#ifndef FALSE
-# define FALSE 0
-# define TRUE !FALSE
-#endif
-
-#ifndef EXIT_FAILURE
-# define EXIT_FAILURE 1
-# define EXIT_SUCCESS 0
-#endif
-
-#ifdef HAS_ATEXIT
-# define EXIT(a) exit(a)
-#else
-# define EXIT(a) { cleanup(); exit(a); }
-#endif
-
-enum file_format { tunix = 1, dos, apple, binary };
-
-/* Since udl is so small, I dare to use some globals :) */
-extern char *program_name; /* How was udl invoked? */
-extern char *current_file; /* Name of current file */
-extern char *tempfile; /* Name of temporary file */
-extern unsigned char *in_buffer; /* My own buffering scheme instead of */
-extern unsigned char *out_buffer; /* setvbuf() */
-extern int verbose;
-extern char filebuffer[MAXPATHLEN]; /* a scratch buffer for file names */
-extern char currentDirectory[MAXPATHLEN];
-extern char rootdir[MAXPATHLEN]; /* the initial directory */
-extern struct stat tstat; /* temporary variable used to stat files */
-extern int pathSlotsUsed; /* number of used and available slots in pathList,*/
-extern int pathSlots; /* respectively. Both are initially zero. */
-extern char **pathList; /* the list of files to process, given relative */
- /* to the initial directory. Initially NULL, */
- /* and NULL terminated. */
-extern char dirbrk; /* the character used to separate parts of a path name */
-extern int recursionDepth; /* levels of subdirectories that we've traversed */
-extern int optind; /* part of getopt library */
-extern int opterr;
-
-/* Prototypes of functions in common.c */
-
-extern void convert_gs (FILE *infile, FILE *outfile);
-extern void convert_messy (FILE *infile, FILE *outfile);
-extern void convert_tunix (FILE *infile, FILE *outfile);
-extern int convert_fast_gs (FILE *infile, FILE *outfile);
-extern int convert_fast_messy (FILE *infile, FILE *outfile);
-extern int convert_fast_tunix (FILE *infile, FILE *outfile);
-extern enum file_format get_file_format (unsigned char *buffer);
-extern FILE *tryopen (char *file, char *mode);
-extern int my_fread (FILE *infile, int howmuch);
-extern void my_fwrite (unsigned char *buffer, FILE *outfile, int howmuch);
-extern void cleanup (void);
-extern void usage (void);
-extern void build_file_list(char *file, short recurse);
-extern void add_to_pathList(char *thisdir, char *file);
-extern char *mktemp(const char *base);
-extern char *get_path(const char *name);
-
-extern int needsgno(void);
-
-/* not strictly necessary, but it cuts down on warnings from gcc */
-#if defined(__GNUC__) || defined(_AIX)
-extern char *getwd(char *);
-#endif
-
-#ifdef __GNUC__
-extern char getopt(int, char **, char *);
-#endif
-
-/* End Of File */
=globals.c
-/*
- * udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
- * and Apple (CR).
- *
- * Contains definitions of global variables declared in common.h
- *
- * $Id: globals.c,v 1.3 1995/02/08 06:12:38 gdr Exp $
- *
- * Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
- */
-
-#ifdef GNO
-#pragma noroot
-#endif
-
-#include "common.h"
-
-char *program_name; /* How was udl invoked? */
-char *current_file; /* Name of current file */
-char *tempfile; /* Name of temporary file */
-unsigned char *in_buffer; /* My own buffering scheme instead of */
-unsigned char *out_buffer; /* setvbuf() */
-int verbose;
-char filebuffer[MAXPATHLEN]; /* a scratch buffer for file names */
-char currentDirectory[MAXPATHLEN];
-char rootdir[MAXPATHLEN]; /* the initial directory */
-struct stat tstat; /* temporary variable used to stat files */
-int pathSlotsUsed; /* number of used and available slots in pathList,*/
-int pathSlots; /* respectively. Both are initially zero. */
-char **pathList; /* the list of files to process, given relative */
- /* to the initial directory. Initially NULL, */
- /* and NULL terminated. */
-char dirbrk; /* the character used to separate parts of a path name */
-int recursionDepth; /* levels of subdirectories that we've traversed */
-
-/* End Of File */
=udl.1
-.\" Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
-.\" $Id: udl.1,v 1.6 1995/02/08 06:12:40 gdr Exp $
-.\"
-.TH UDL 1 "Commands and Applications" "7 February 1995" "Version 1.14"
-.SH NAME
-udl - convert text files between different architectures
-.SH SYNOPSIS
-.BR udl
-.BR -u | m | g
-[
-.B -Rvp
-]
-.I file1
-[
-.IR file2 " ..."
-]
-.SH DESCRIPTION
-.B udl
-converts files between different computer systems by changing the EOL
-(End-Of-Line) character.
-.PP
-On the Apple IIgs,
-.B udl
-will skip any file that is not of type TXT or SRC.
-No notice is given of this unless the
-.B -v
-flag is used.
-Since Unix file systems do not have file types
-.BR udl
-is limited in the types of checks which it can carry out,
-so the user must take care that
-it is not invoked on object files or the like. On both platforms, if
-.I file
-appears to be a binary file (that is, no EOL is
-found in the first part of the file) then
-.I file
-will be skipped.
-Again, no notice is given of this unless the
-.B -v
-flag is used.
-.PP
-During file conversion
-.B udl
-creates a temporary file in the same directory as the original file.
-The temporary file is close to or exactly the same size as the original
-file.
-.PP
-When running under Byteworks' ORCA shell, the Orca shell wildcards
-.BR =
-and
-.BR ?
-are properly expanded in file names.
-.SH OPTIONS
-.IP \fB\-u\fP
-Convert to use LF as EOL (Unix/Amiga).
-.IP \fB\-m\fP
-Convert to use CR/LF as EOL (MS-DOS).
-.IP \fB\-g\fP
-Convert to use CR as EOL (Apple).
-.IP \fB\-p\fP
-Be pedantic, only affects Unix<->Apple conversions, see below.
-.IP \fB\-R\fP
-Recurse through subdirectories.
-.IP \fB\-v\fP
-Be verbose, show the file udl is currently working on.
-.PP
-If you specify the
-.B -p
-switch,
-.B udl
-is pedantic while doing the conversion. This means: The input file may
-contain bytes with a value of zero (0), and the input file may contain
-different EOL characters (ie: MS-DOS and Unix style might be mixed in
-one file). For conversions to or from MS-DOS
-.B udl
-is always pedantic, so this only affects conversions from Unix to Apple
-or vice versa. Being pedantic slows udl down by a factor of 1.5.
-.SH LIMITATIONS
-When running under Gno on the Apple IIgs, there is a limit to the nesting
-depth when recusing on subdirectories. This is because the routine that
-is responsible for this behavior is itself recursive. The default 2k
-stack size will allow about 33 levels of nested directories, so this limit
-should not normally be a problem. If the limit is exceeded,
-.BR udl
-will exit with an error message before any files are changed, and before
-the stack actually overflows.
-.SH BUGS
-Bug reports should be directed to one of the two addresses below.
-.SH AUTHOR
-Soenke Behrens <sbeh...@contech.demon.co.uk> with contributions by
-Devin Reade <g...@myrias.ab.ca>.
-.\" .br
-.\" Version 1.13 updated by Devin Reade, g...@myrias.ab.ca
-.SH VERSION
-This is
-.B udl
-version 1.14.
=udl.DESCRIBE
-Name: udl
-Version: 1.14
-Author: Soenke Behrens, Devin Reade
-Contact: sbeh...@contech.demon.co.uk, g...@myrias.ab.ca
-Where: /usr/local/bin
-FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
-
- Converts text between the CR, LF and CR/LF forms. Also available for Unix
-machines, reasonably fast yet secure.
=udl.gs.c
-/*
- * udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
- * and Apple (CR).
- *
- * Apple IIgs specific routines.
- *
- * $Id: udl.gs.c,v 1.6 1995/02/08 06:12:44 gdr Exp $
- *
- * Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
- */
-
-#include <orca.h>
-#include <shell.h>
-#include <gsos.h>
-#include <getopt.h>
-
-#include "common.h"
-
-#define QUITFLAG 0x4000 /* udl is restartable */
-#define DIRECTORY 0x0F
-
-/*
- * Globals
- */
-
-int theType, theAuxType; /* Hold type of current file */
-Next_WildcardGSPB NextWild; /* for handling ORCA/Shell style wildcards */
-Init_WildcardGSPB InitWild;
-
-extern pascal void SystemQuitFlags (unsigned);
-extern pascal void SystemQuitPath (GSString255Ptr);
-extern int needsgno(void);
-extern void begin_stack_check(void);
-extern int end_stack_check(void);
-
-/*
- * Prototypes of functions in this file
- */
-
-extern int CheckGSOSType (char *name);
-extern void SetGSOSType (char *name, int type, int auxtype);
-extern int right_shell_version (void);
-
-int main(int argc,char *argv[]) {
- FILE *infile, *outfile;
- int Tunix = FALSE;
- int Messy = FALSE;
- int GS = FALSE;
- int careful = FALSE;
- int converted;
- int c;
- static GSString255 gsp;
- static ResultBuf255 rsp;
- int R_flag = FALSE;
- char **p;
-
- verbose = FALSE;
- recursionDepth = 0;
- program_name = NULL;
- tempfile = NULL;
- current_file = NULL;
- NextWild.pathName = NULL;
- in_buffer = out_buffer = NULL;
- pathSlotsUsed = 0;
- pathSlots = 0;
- pathList = NULL;
- *currentDirectory = '\0';
- recursionDepth=0;
-
-#ifdef CHECK_STACK
- begin_stack_check();
-#endif
-
- /* In case of exit(), free the mem I allocated */
- atexit (cleanup);
-
- /* Make udl restartable */
- SystemQuitFlags (QUITFLAG);
- SystemQuitPath (NULL);
-
- if (right_shell_version() == FALSE) {
- fprintf(stderr,"%s requires at least ORCA/Shell 2.0"
- " or GNO/ME 1.0\n", argv[0]);
- exit (EXIT_FAILURE);
- }
-
- if ((program_name = strdup (argv[0])) == NULL) {
- fprintf(stderr,"%s: memory allocation failure\n",argv[0]);
- exit (EXIT_FAILURE);
- }
-
- if (argc < 3) {
- usage();
- exit (EXIT_FAILURE);
- }
-
- /* Get and process arguments */
-
- optind = 0;
- opterr = 1;
- while ((c = getopt (argc, argv, "pvugmR")) != EOF) {
- switch (c) {
- case 'v':
- verbose = TRUE;
- break;
-
- case 'p':
- careful = TRUE;
- break;
-
- case 'u':
- if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
- fprintf(stderr, "%s: You may not "
- "specify more than one conversion option\n",program_name);
- exit (EXIT_FAILURE);
- }
- Tunix = TRUE;
- break;
-
- case 'm':
- if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
- fprintf(stderr, "%s: You may not "
- "specify more than one conversion option\n",program_name);
- exit (EXIT_FAILURE);
- }
- Messy = TRUE;
- break;
-
- case 'g':
- if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
- fprintf(stderr, "%s: You may not "
- "specify more than one conversion option\n",program_name);
- exit (EXIT_FAILURE);
- }
- GS = TRUE;
- break;
-
- case 'R':
- R_flag++;
- break;
-
- case '?':
- usage();
- exit (EXIT_FAILURE);
-
- default:
- fprintf (stderr, "%s: Internal getopt error\n", program_name);
- exit (EXIT_FAILURE);
- break;
- }
- }
-
- if (optind == argc) { /* no files specified */
- usage();
- exit (EXIT_FAILURE);
- }
-
- if (Tunix == FALSE && GS == FALSE && Messy == FALSE) {
- fprintf(stderr,"%s: You have to specify a destination "
- "format.\n",program_name);
- exit (EXIT_FAILURE);
- }
-
- if (verbose == TRUE) {
- printf ("%s version %s\n",program_name,UDL_VERSION);
- }
-
- if ((in_buffer = malloc(BUFFERSIZE+1)) == NULL ||
- (out_buffer = malloc(BUFFERSIZE+1)) == NULL) {
- fprintf(stderr,"%s: Unable to buffer files\n",program_name);
- exit (EXIT_FAILURE);
- }
-
- /* Orca Shell: expand wildcards */
- if (!needsgno()) {
- NextWild.pCount = 1;
- InitWild.pCount = 2;
- rsp.bufSize = 259;
- NextWild.pathName = &rsp;
- InitWild.wFile = &gsp;
- if (R_flag) {
- InitWild.flags = 0x2000 | 0x1000;
- } else {
- InitWild.flags = 0;
- }
-
- dirbrk = ':'; /* enforced by NextWildcardGS */
-
- /* loop through all command line args */
- for (; optind < argc; optind++) {
- size_t i;
- int num_of_files;
-
- i = strlen(argv[optind]);
- strncpy (gsp.text,argv[optind],i);
- gsp.length = i;
- InitWildcardGS (&InitWild);
- num_of_files = 0;
-
- /* loop through all matches of wildcards */
- for (;;) {
- NextWildcardGS (&NextWild);
- if (toolerror()) {
- fprintf(stderr,"%s: Fatal internal error, "
- "exiting\n", program_name);
- exit (EXIT_FAILURE);
- }
-
- /* No further file found by NextWildcardGS */
- if(!rsp.bufString.length)
- break;
-
- num_of_files++;
-
- if((current_file = calloc(1,rsp.bufString.length + 1)) == NULL) {
- fprintf(stderr,"%s: memory allocation failure\n",program_name);
- exit (EXIT_FAILURE);
- }
- strncpy(current_file, rsp.bufString.text,rsp.bufString.length);
-
- add_to_pathList("",current_file);
- free(current_file);
- current_file = NULL;
- } /* for (;;) */
-
- if (num_of_files == 0)
- fprintf(stderr,"%s: No files found that match %s\n",
- program_name,argv[optind]);
- } /* for (; optind < argc; optind++) */
- }
- /* gsh or other Gno shell */
- else {
-
- /* save the directory we're in */
- if (getwd(rootdir)==NULL) {
- fprintf(stderr,"%s: Couldn't stat .\n",program_name);
- exit (EXIT_FAILURE);
- }
-
- for (; optind<argc; optind++) {
- /* set the directory separator character. */
- dirbrk = (strchr(argv[optind],':')!=NULL) ? ':' : '/';
- build_file_list(argv[optind],R_flag);
- chdir(rootdir);
- *currentDirectory = '\0';
- }
- }
-
- /* files were all directories and no -R flag given */
- if (!pathList) {
- if (verbose) printf("%s: no files to process\n",program_name);
- exit(EXIT_SUCCESS);
- }
-
- p = pathList;
- while(*p) {
- current_file = *p;
-
- if (CheckGSOSType (current_file) == FALSE) {
- p++;
- continue;
- }
- if (verbose == TRUE) {
- printf("%s: Working on %s\n",program_name,current_file);
- }
-
- infile = tryopen(current_file,"rwb");
- tempfile = mktemp(strcat(get_path(current_file), "udltmpXX"));
- outfile = tryopen(tempfile,"wb");
-
- if (careful) {
- converted = TRUE; /* always */
-
- if (GS)
- convert_gs(infile,outfile);
- else if (Tunix)
- convert_tunix(infile,outfile);
- else
- convert_messy(infile,outfile);
- } else {
- if (GS)
- converted = convert_fast_gs(infile,outfile);
- else if (Tunix)
- converted = convert_fast_tunix(infile,outfile);
- else
- converted = convert_fast_messy(infile,outfile);
- }
-
- if (fclose (infile) == EOF || fclose (outfile) == EOF) {
- perror ("closing files");
- exit (EXIT_FAILURE);
- }
-
- if (converted) { /* Temp file contains converted data */
- if (remove (current_file) != 0) {
- perror ("removing original file");
- exit (EXIT_FAILURE);
- }
-
- if (rename (tempfile,current_file) != 0) {
- perror ("cannot rename temporary file");
- exit (EXIT_FAILURE);
- }
- } else
- remove (tempfile);
-
- free (tempfile); tempfile = NULL;
- SetGSOSType (current_file, theType, theAuxType);
- p++;
- } /* end while */
-
-#ifdef CHECK_STACK
- fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
-#endif
-
- return (EXIT_SUCCESS);
-}
-
-/*
- * CheckGSOSType() ... check if a file is of type TXT or SRC
- *
- * Inputs:
- * char *name Name of file to check
- *
- * Outputs:
- * int Boolean, TRUE if file type is TXT or SRC, FALSE otherwise
- */
-
-int CheckGSOSType(char *name) {
-#define TXT 0x04
-#define SRC 0xB0
-
- static GSString255 gst;
- static FileInfoRecGS fir = {5};
- size_t i;
-
- i = strlen (name);
- gst.length = i;
- strncpy(gst.text,name,i);
- fir.pathname = &gst;
-
- GetFileInfoGS(&fir);
-
- if (toolerror()) {
- fprintf (stderr,"%s: GS/OS error on %s: 0x%04X\n",
- program_name,name,toolerror());
- exit (EXIT_FAILURE);
- }
-
- if ((fir.fileType != TXT) && (fir.fileType != SRC)) {
- if (verbose && (fir.fileType != DIRECTORY))
- fprintf(stderr,"%s: %s is not of type TXT or "
- "SRC ... skipping\n",program_name,current_file);
- return (FALSE);
- } else {
- theType = fir.fileType;
- theAuxType = fir.auxType;
- return (TRUE);
- }
-}
-
-/*
- * SetGSOSType() ... set file and auxtype of a file.
- *
- * Inputs:
- * char *name Name of file to be affected
- * int type File type it should be set to
- * int auxtype Auxiliary type it should be set to
- *
- * Outputs:
- * None
- */
-
-void SetGSOSType (char *name, int type, int auxtype) {
- static GSString255 gst;
- static FileInfoRecGS fir = {4, NULL, 0xE3};
- size_t i;
-
- i = strlen (name);
- gst.length = i;
- strncpy(gst.text,name,i);
- fir.pathname = &gst;
- fir.fileType = type;
- fir.auxType = auxtype;
-
- SetFileInfoGS(&fir);
-
- if (toolerror()) {
- fprintf (stderr,"%s: GS/OS error on %s: 0x%04X\n",
- program_name,name,toolerror());
- exit (EXIT_FAILURE);
- }
-}
-
-/*
- * right_shell_version() ... check if at least ORCA/Shell 2.0 or
- * GNO/ME 1.0 is active.
- *
- * Inputs:
- * None
- *
- * Output:
- * int Boolean, TRUE if shell is satisfactory, FALSE otherwise
- */
-
-int right_shell_version (void) {
- static VersionPB vpb;
-
- VERSION(&vpb);
-
- if (vpb.version[0] < '2' || strcmp (shellid(),"BYTEWRKS") != 0)
- return FALSE;
- else
- return TRUE;
-}
-
-/* End Of File */
+ END OF ARCHIVE