From 936602804643c00a39d2b0401b6b38d4955cc146 Mon Sep 17 00:00:00 2001 From: gdr Date: Tue, 13 Dec 1994 18:08:34 +0000 Subject: [PATCH] Released udl v1.13 --- usr.orca.bin/udl/Makefile.gs | 51 +++ usr.orca.bin/udl/Makefile.unx | 56 +++ usr.orca.bin/udl/README | 74 +++ usr.orca.bin/udl/common.c | 839 ++++++++++++++++++++++++++++++++++ usr.orca.bin/udl/common.h | 98 ++++ usr.orca.bin/udl/udl.1 | 85 ++++ usr.orca.bin/udl/udlgs.c | 402 ++++++++++++++++ usr.orca.bin/udl/udlunix.c | 206 +++++++++ usr.orca.bin/udl/udluse.c | 29 ++ 9 files changed, 1840 insertions(+) create mode 100644 usr.orca.bin/udl/Makefile.gs create mode 100644 usr.orca.bin/udl/Makefile.unx create mode 100644 usr.orca.bin/udl/README create mode 100644 usr.orca.bin/udl/common.c create mode 100644 usr.orca.bin/udl/common.h create mode 100644 usr.orca.bin/udl/udl.1 create mode 100644 usr.orca.bin/udl/udlgs.c create mode 100644 usr.orca.bin/udl/udlunix.c create mode 100644 usr.orca.bin/udl/udluse.c diff --git a/usr.orca.bin/udl/Makefile.gs b/usr.orca.bin/udl/Makefile.gs new file mode 100644 index 0000000..c171d24 --- /dev/null +++ b/usr.orca.bin/udl/Makefile.gs @@ -0,0 +1,51 @@ +# +# Makefile for udl +# Copyright (c) 1993-1994 Soenke Behrens +# For use with dmake +# +# $Id: Makefile.gs,v 1.1 1994/12/13 18:08:13 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. +# +# 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 -DCHECK_STACK +CFLAGS = $(DEFINES) -G25 -w -v +LDFLAGS = -v -l/usr/lib/stack -l/usr/lib/gnulib + +# +# You should not have to modify anything beyond this point +# + +udl: udl.o udluse.o udl.r common.o + $(CC) $(LDFLAGS) -o udl udl.o udluse.o common.o + copyfork udl.r udl + +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 + +clean: + $(RM) *.o udl + +dist: + @echo "Sorry, automatic packing not supported yet" + +common.o:: common.h diff --git a/usr.orca.bin/udl/Makefile.unx b/usr.orca.bin/udl/Makefile.unx new file mode 100644 index 0000000..a05fc51 --- /dev/null +++ b/usr.orca.bin/udl/Makefile.unx @@ -0,0 +1,56 @@ +# +# Makefile for udl +# (c) 1993-1994 Soenke Behrens +# +# $Id: Makefile.unx,v 1.1 1994/12/13 18:08:16 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. +# + +# 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 + +DEFINES = -DREADDIR_RETURNS_DOT=1 -DBROKEN_REALLOC=1 -D_POSIX_C_SOURCE \ + -D_POSIX_SOURCE +CFLAGS = $(DEFINES) -O +# You may need -lucb in LDFLAGS +LDFLAGS = + +# +# You should not have to modify anything beyond this point +# + +udl: udl.o udluse.o common.o + $(CC) $(LDFLAGS) -o udl udl.o udluse.o common.o + +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 + +clobber: clean + rm udl + +dist: + @echo 'Sorry, automatic packing not yet supported.' + +common.o::common.h diff --git a/usr.orca.bin/udl/README b/usr.orca.bin/udl/README new file mode 100644 index 0000000..bc96ed8 --- /dev/null +++ b/usr.orca.bin/udl/README @@ -0,0 +1,74 @@ +============================================================================= +udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF), + and Apple (CR). + + (c) 1993-1994 Soenke Behrens + + Version 1.13: $Id: README,v 1.1 1994/12/13 18:08:18 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. + +========= +Compiling: +========= + +There are two makefiles included: + Makefile.gs - for use on the Apple IIgs running Gno + Makefile.unix - for use with Unix systems. + +Although udl on the IIgs can be run from either Gno or Orca shells, +it cannot be built with the standard Orca installation due to a lack +of additional libraries. + +Before you type "make", have a look at the Makefile and edit the defines +to your liking. + +Also, udl.c assumes that getopt() is declared in and that +the function strdup() exists in . You might want to change +these includes if that's not the case. + +============================================================================= +Enjoy, + +Soenke +schaf@meadow.muc.de +December 1993 diff --git a/usr.orca.bin/udl/common.c b/usr.orca.bin/udl/common.c new file mode 100644 index 0000000..31a8f73 --- /dev/null +++ b/usr.orca.bin/udl/common.c @@ -0,0 +1,839 @@ +/* + * 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.1 1994/12/13 18:08:20 gdr Exp $ + * + * Copyright (c) 1993-1994 Soenke Behrens + */ + +#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; +} + +/* + * copy_file() ... copies a file to another, creates the destination file. + * + * Inputs: + * char *from Name of file to copy from + * char *to Name of file to create and copy to + * + * Output: + * None + */ + +void copy_file (char *from, char *to) { + FILE *fp1, *fp2; + unsigned char *buffer; + size_t length; + + if((buffer = malloc(BUFFERSIZE)) == NULL) { + fprintf(stderr,"%s: memory allocation failure\n",program_name); + exit (EXIT_FAILURE); + } + + fp1 = tryopen (from,"rb"); + fp2 = tryopen (to,"wb"); + + while (!feof (fp1)) { + length = fread(buffer,1,BUFFERSIZE,fp1); + if (ferror(fp1)) { + fprintf(stderr,"%s: Error while trying to read %s\n", + program_name, from); + free (buffer); + exit (EXIT_FAILURE); + } + + if (fwrite(buffer,1,length,fp2) != length) { + fprintf(stderr,"%s: Error while trying to write out " + "file %s\n",program_name,to); + free (buffer); + exit (EXIT_FAILURE); + } + } + + if (fclose (fp1) == EOF || fclose (fp2) == EOF) { + perror ("closing files"); + free (buffer); + exit (EXIT_FAILURE); + } +} + +/* + * 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); + 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 */ + extern char use2[]; + + 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; + + if (stat(file,&tstat)!=0) { + fprintf(stderr,"%s: Couldn't stat %s. File skipped\n",program_name,file); + 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); + + /* 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 */ + if (*(entry->d_name)!='.') build_file_list(entry->d_name,1); + } + + 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); + } + + 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; +} + +/* End Of File */ diff --git a/usr.orca.bin/udl/common.h b/usr.orca.bin/udl/common.h new file mode 100644 index 0000000..d33fb7e --- /dev/null +++ b/usr.orca.bin/udl/common.h @@ -0,0 +1,98 @@ +/* + * 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.1 1994/12/13 18:08:23 gdr Exp $ + * + * Copyright (c) 1993-1994 Soenke Behrens + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFFERSIZE 0x2000 +#define PATHLIST_QUANTUM 20 +#define UDL_VERSION "Version 1.13" + +#ifndef FALSE +# define FALSE 0 +# define TRUE !FALSE +#endif + +/* we use this macro for macro definitions/declarations */ +#ifdef MAIN +# define EXTERN +#else +# define EXTERN extern +#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 copy_file (char *from, char *to); +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 int needsgno(void); + +/* not strictly necessary, but it cuts down on warnings from gcc */ +#ifdef __GNUC__ +extern char *getwd(char *); +extern char getopt(int, char **, char *); +#endif diff --git a/usr.orca.bin/udl/udl.1 b/usr.orca.bin/udl/udl.1 new file mode 100644 index 0000000..d03b388 --- /dev/null +++ b/usr.orca.bin/udl/udl.1 @@ -0,0 +1,85 @@ +.\" Copyright (c) 1993-1994 Soenke Behrens +.\" $Id: udl.1,v 1.1 1994/12/13 18:08:26 gdr Exp $ +.TH UDL 1 "22 November 1994" "Version 1.13" "Commands and Applications" +.SH NAME +udl - convert text files between different architectures +.SH SYNOPSIS +.BR udl +.BR -u | m | g +[ +.B -Rv +] +.I file1 +[ +.IR file2 " ..." +] +.SH DESCRIPTION +.B udl +converts files between different computer systems by changing the EOL +(End-Of-Line) character. It does +.I not +do a plausability check, so the user has to make sure udl is not invoked +on object files or the like. +.PP +.B udl +creates a temporary file the size of the file it is currently working on +while it's doing its thing. +.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 (i.e., 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. +.PP +If +.B udl +is given a file that seems to be a binary file \(that is, no EOL is +found in the first part of the file\), the file will be skipped. No +notice is given of this unless the +.B -v +flag is used. +.SH BUGS +When compiling on some Solaris installations, files within subdirectories +do not get their names properly resolved. +This seems to be due to bad definitions in +.IR . +If you have access to SunOS 4.x, +.BR udl +can be compiled there and used under Solaris. +.LP +If you find any other bugs, please send a report to the address given below. +.SH AUTHOR +Soenke Behrens, soenke.behrens@conner.com +.br +Version 1.13 updated by Devin Reade, gdr@myrias.ab.ca +.SH VERSION +This is +.B udl +version 1.13. +.br +It's 1.5 times faster than 1.1 for Unix<->Apple conversions. diff --git a/usr.orca.bin/udl/udlgs.c b/usr.orca.bin/udl/udlgs.c new file mode 100644 index 0000000..aa584b1 --- /dev/null +++ b/usr.orca.bin/udl/udlgs.c @@ -0,0 +1,402 @@ +/* + * udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF), + * and Apple (CR). + * + * Apple IIgs specific routines. + * + * $Id: udlgs.c,v 1.1 1994/12/13 18:08:29 gdr Exp $ + * + * Copyright (c) 1993-1994 Soenke Behrens + */ + +#include +#include +#include +#include + +#define MAIN 1 +#include "common.h" + +#define QUITFLAG 0x4000 /* udl is restartable */ + +/* + * 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'; + +#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; + InitWild.flags = 0x8000 | 0x2000 | 0x1000; + + /* 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