dhesi@bsu-cs.bsu.edu (Rahul Dhesi) (06/20/89)
#! /bin/sh # This program does newline conversions between UNIX and MS-DOS formats. # It tries to leave behind no garbage or corrupted files if it is # interrupted. It is written in fairly portable C, and believed to # compile and execute correctly under System V Release 2, 4.3BSD, # and MS-DOS/Turbo C 2.0. This is a beta release of Flip 0.5. # # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # Checksums # Install # flip.c # flip.doc # flip.h # flip.prj # getopt.c # makefile.nix # makefile.tcc # turboc.c # turboc.cfg # This archive created: Tue Jun 20 01:04:05 1989 export PATH; PATH=/bin:/usr/bin:$PATH echo shar: "extracting 'Checksums'" '(380 characters)' if test -f 'Checksums' then echo shar: "will not over-write existing file 'Checksums'" else sed 's/^X//' << \SHAR_EOF > 'Checksums' X# Whole file CRCs generated by Brik v1.0. Use "brik -C" to verify them. X X# CRC-32 filename X# ------ -------- X X3813849291 Install X2867397402 flip.c X4230879772 flip.doc X1463409918 flip.h X3390294771 flip.prj X4276217585 getopt.c X3952651514 makefile.nix X 50376736 makefile.tcc X1336713629 turboc.c X3904539313 turboc.cfg SHAR_EOF fi echo shar: "extracting 'Install'" '(2402 characters)' if test -f 'Install' then echo shar: "will not over-write existing file 'Install'" else sed 's/^X//' << \SHAR_EOF > 'Install' X Installing Flip 0.5 beta X X XInstallation instructions are provided for System V Release 2, 4.3BSD, XMicroport System V/AT, and MS-DOS/Turbo C. To install under other similar Xenvironments look carefully in flip.h and make changes as needed. X XA list of all files in this package is at the end of this document. X X XMS-DOS/TURBO C X XThe files supplied are suitable for compilation with Borland's Turbo C 2.0 Xfor MS-DOS. X XA makefile "makefile.tcc" is supplied. Use the command line compiler X"tcc.exe". You will need a good make program, such as NDMAKE. Edit X"turboc.cfg" so it correctly reflects the include directories on your Xsystem. Then type "make -f makefile.tcc". X XYou can also use the intergrated environment "tc.exe". Convert "turboc.cfg" Xto "tcconfig.tc" using Borland's "cnvtcfg.exe" program. Invoke tc.exe and Xload the configuration file "tcconfig.tc". Then select Options/Compiler/ XDefines and define the symbols TURBOC, NDEBUG, and LINT. A project file X"flip.prj" is supplied. Compile as usual. X X XSYSTEM V RELEASE 2, 4.3BSD, OR MICROPORT SYSTEM V/AT X XRename the provided file "makefile.nix" to "makefile. X XDepending on the system, type: X X make sys_v for System V Release 2 X make bsd for 4.3BSD X make uport for Microport System V/AT (large model) X XIt may work to do "make sys_v" for Microport System V/AT, but I'm not sure, Xas I haven't yet restored my small model libraries which vanished from my Xdisk one day without warning. X XUnder any flavor of **IX you can link "flip" to "toix" and "toms". X X XFILES IN THIS PACKAGE X X X size, X name bytes description X ---- ----- ----------- X X Checksums 454 text checksums -- verify with brik 1.0 X Install 2,402 installation instructions X flip.doc 3,769 user documentation X X flip.c 13,234 the main program X flip.h 6,945 a header file (change as needed) X X makefile.nix 1,635 makefile for **IX X X getopt.c 2,801 getopt function if your system doesn't have it X X makefile.tcc 491 Turbo C 2.0 makefile X turboc.c 10,224 Turbo C 2.0 special functions X turboc.cfg 108 Turbo C 2.0 configuration file for compiler X flip.prj 56 Turbo C 2.0 file for project make X X -- Rahul Dhesi 1989/06/19 SHAR_EOF fi echo shar: "extracting 'flip.c'" '(13234 characters)' if test -f 'flip.c' then echo shar: "will not over-write existing file 'flip.c'" else sed 's/^X//' << \SHAR_EOF > 'flip.c' X/* ::[[ @(#) flip.c 1.15 89/06/19 21:48:31 ]]:: */ X#ifndef LINT Xstatic char sccsid[]="::[[ @(#) flip.c 1.15 89/06/19 21:48:31 ]]::"; X#endif X X/* XCopyright 1989 Rahul Dhesi, All rights reserved. X XChecksum: 2515109944 (check or update with "brik") X*/ X X/* XDoes newline conversions between **IX and MS-DOS conventions. Uses a state Xmachine, so repeated conversions on the same file will do no harm. XAssumes the US ASCII character set in some places (search for 'ASCII'). X*/ X X/* change contents of flip.h as needed */ X#include "flip.h" X Xenum choices { MSTOIX, IXTOMS, NEITHER }; /* conversion choices */ Xenum state { NONE, SAWCR, SAWLF, SAWCRLF, SAWCTRLZ }; X Xvoid usage PARMS ((void)); Xvoid give_help PARMS ((void)); Xvoid flip_exit PARMS ((int)); Xint getopt PARMS ((int argc, char **argv, char *options)); Xvoid doarg PARMS ((char *, enum choices)); Xint dofile PARMS ((char *, enum choices)); Xchar *nextfile PARMS ((int, char *, int)); Xint ixtoms PARMS ((FILE *, FILE *)); Xint mstoix PARMS ((FILE *, FILE *)); Xvoid error PARMS ((char *, char *)); Xvoid setup_sigs PARMS ((void)); Xvoid cleanup PARMS ((int)); Xchar *mktemp PARMS ((char *)); X X#ifdef STDINCLUDE X# include <stdlib.h> X# include <string.h> X#else Xvoid exit PARMS ((int)); Xchar *strcpy PARMS ((char *, char *)); X#endif X X#ifdef NDEBUG X# define assert(c) X#else X# ifdef STDINCLUDE X# include <assert.h> X# else X# define assert(c) if(!(c)) \ X fprintf(stderr,"assert error %s:%d\n",__FILE__,__LINE__) X# endif /* STDINCLUDE */ X#endif /* NDEBUG */ X X#ifdef USE_TABLE Xchar *bintab; X#endif X X#ifdef USE_SIG Xint got_sig; /* will indicate if signal received */ X#endif X Xchar *myname = NULL; X Xint exitstat = 0; /* exit status */ Xint verbose = 0; /* set by -v option */ Xint touch = 0; /* set by -t option */ Xint strip = 0; /* set by -s option */ Xint bintoo = 0; /* set by -b option */ Xint ztrunc = 0; /* set by -z option */ X Xmain (argc, argv) Xint argc; Xchar **argv; X X{ X int option; X extern int optind; X int i; X enum choices which = NEITHER; X#ifdef USE_TABLE X#define TABSIZ (256+1) /* 1 for EOF, 256 for chars */ X char table[TABSIZ]; X#endif X X#ifdef PICKNAME X register char *p; /* temp pointer for finding our name */ X register char *arg0 = *argv; X#endif /* PICKNAME */ X X SPEC_INIT /* optional initialization */ X X#ifdef USE_SIG X setup_sigs(); X#endif X X#ifdef PICKNAME X# define STRCMP(a,op,b) (strcmp(a,b) op 0) X p = arg0 + strlen(arg0); X X if (p != arg0) { /* if program name is defined */ X while (p != arg0 && *p != '/' && *p != '\\') X p--; X assert ((p - arg0) <= strlen (arg0)); X if (p != arg0) X p++; X X /* p now points to trailing name component, or nothing */ X myname = p; X while (*p != '\0' && *p != '.') { /* ASCII convert to lowercase */ X if (*p >= 'A' && *p <= 'Z') { X *p = (*p - 'A' + 'a'); X } X p++; X } X if (p != myname && *p == '.') X *p = '\0'; /* remove trailing .exe or .com under MS-DOS etc. */ X X if (STRCMP(myname,==,"toix")) X which = MSTOIX; X else if (STRCMP(myname,==,"toms")) X which = IXTOMS; X } else X myname = "flip"; X#else X myname = "flip"; X#endif /* PICKNAME */ X Xargv[0] = myname; /* for use by getopt */ X X#ifdef USE_TABLE X/* table to find out which characters are binary */ X table[0] = 0; /* EOF is not binary */ X for (i = 0; i < TABSIZ-1; i++) { X if ( (i < 7) || (i > 13 && i < 26) || (i > 126)) /*ASCII binary chars*/ X table[i+1] = 1; X else X table[i+1] = 0; X } X bintab = table; X#endif /* USE_TABLE */ X X if (argc < 2) { X usage(); X flip_exit (1); X } X X while ((option = getopt (argc, argv, "umhvtsbz")) != EOF) { X switch (option) { X case 'u': which = MSTOIX; break; X case 'm': which = IXTOMS; break; X case 'h': give_help(); flip_exit (0); X case 'v': verbose = 1; break; X case 't': touch = 1; break; X case 's': strip = 1; break; X case 'b': bintoo = 1; break; X case 'z': ztrunc = 1; break; X default: usage(); flip_exit (1); X } X } X X switch (which) { X case MSTOIX: X /* printf ("converting to **ix format\n"); */ X break; X case IXTOMS: X /* printf ("converting to msdos format\n"); */ X break; X default: X fprintf (stderr, "%s: error: -u or -m is required\n", myname); X flip_exit (1); X break; X } X X if (argc <= optind) { X fprintf (stderr, "%s: error: filenames are needed\n", myname); X flip_exit (1); X } X X for (i = optind; i < argc; i++) X doarg (argv[i], which); X X return (exitstat); X} X X X/* XDoes conversion for one argument, calling dofile with wildcards Xexpanded. Updates exitstat in case of error. X*/ X Xvoid doarg (arg, which) Xchar *arg; Xenum choices which; X{ X#ifdef WILDCARD X char *this_file; X X nextfile (0, arg, 0); X while ((this_file = nextfile(1, (char *) NULL, 0)) != NULL) { X exitstat |= dofile (this_file, which); X } X#else X exitstat |= dofile (arg, which); X#endif /* WILDCARD */ X} X X#ifdef USE_SIG X# include <signal.h> X#endif X XFILE *outfile; /* make it visible to both dofile and cleanup */ X X/* XHere we have filename and an option. We call a different routine Xfor each type of conversion. This way more types of conversions Xcan be easily added in the future. X*/ X Xint dofile (fname, which) Xchar *fname; Xenum choices which; X{ X FILE *infile; X char tfname[PATHSIZE]; X SGFTIME timestamp; /* save file timestamp here, restore later */ X int errstat = 0; X char *p; /* temp file ptr */ X X#ifdef USE_SIG X if (got_sig) X flip_exit (INT_EXIT); X#endif X X /* if writable, open for reading */ X if ((infile = fopen (fname, "r+b")) != NULL) { X fclose (infile); X infile = fopen (fname, "rb"); X } X X if (infile == NULL) { X error (fname, ": can't open"); X return (1); X } X X /* X to make temp file in same dir as original, we make p point to the filename X component of fname, put '\0' there, and strcat the temp name to it X */ X strcpy (tfname, fname); X p = tfname + strlen(tfname); X X while (p != tfname && *p != '/' && *p != '\\') X p--; X if (p != tfname) X p++; X *p = '\0'; X X#define TEMPLATE "XXXXXX" X { X char template[7]; X strcpy (template, TEMPLATE); X strcat (tfname, mktemp (template)); X } X X outfile = fopen (tfname, "wb"); X X if (outfile == NULL) { X fclose (infile); X error (fname, ": skipped, could not open temporary file"); X return (1); X } X X if (!touch) X GETFT (infile, fname, timestamp); /* save current timestamp */ X X assert (which == IXTOMS || which == MSTOIX); X X#ifdef BIGBUF X setvbuf (infile, (char *) NULL, _IOFBF, BIGBUF); X setvbuf (outfile, (char *) NULL, _IOFBF, BIGBUF); X#endif /* BIGBUF */ X X switch (which) { X case IXTOMS: X errstat = ixtoms (infile, outfile); X break; X case MSTOIX: X errstat = mstoix (infile, outfile); X break; X } X X fclose (infile); X X switch (errstat) { X case ERRBINF: X fclose (outfile); X DELFILE (tfname); X fprintf (stderr, "%s: binary file, not converted\n", fname); X return (1); X /* break; */ /* unreachable code */ X#ifdef USE_SIG X case ERRSIG: X fclose (outfile); X DELFILE (tfname); X flip_exit (INT_EXIT); X break; X#endif X default: X ; X } X X assert (errstat == 0); X X if (!ferror(outfile) && fflush(outfile) != EOF && fclose(outfile) != EOF) { X int moved; X DELFILE (fname); X moved = MVFILE (tfname, fname); X if (moved == 0) { X FILE *fptr; X if (!touch && (fptr = fopen (fname, "rb")) != NULL) { X SETFT (fptr, fname, timestamp); X fclose (fptr); X } X if (verbose) { X printf ("%s\n", fname); X fflush (stdout); X } X return (0); X } else { X error (fname, ": not converted, could not rename temp file"); X DELFILE (tfname); X return (1); X } X } else { X if (outfile != NULL) X fclose (outfile); /* in case it didn't get done due to && above */ X return (1); X } X} X X/* convert from ms-dos to **ix format */ Xint mstoix (infile, outfile) XFILE *infile; /* input file */ XFILE *outfile; /* output file */ X{ X int c; X enum state state = NONE; X X /* lone LF => unchanged, lone CR => unchanged, X CR LF => LF, ^Z at end means EOF; ^Z elsewhere => unchanged */ X X while (1) { /* break out on EOF only */ X while ((c = getc (infile)) != EOF) { X#ifdef USE_SIG X if (got_sig) X return (ERRSIG); X#endif X if (!bintoo && BINCHAR(c)) X return (ERRBINF); X IFSTRIP(c); X switch (c) { X case LF: X CHECK_BREAK X putc (c, outfile); if (state == SAWCR) state = NONE; break; X case CR: X state = SAWCR; break; X case CTRLZ: X if (state == SAWCR) putc (CR, outfile); X state = SAWCTRLZ; goto saweof; X default: X if (state == SAWCR) { state = NONE; putc (CR, outfile); } X putc (c, outfile); X break; X } X } X saweof: X /* exit outer loop only on EOF or ^Z as last char */ X if ( X ztrunc && state == SAWCTRLZ X || (c = getc (infile)) == EOF X ) X break; X else X ungetc (c, infile); X if (state == SAWCTRLZ) X putc (CTRLZ, outfile); X } X return (0); X} X X/* convert from **ix to ms-dos format */ Xint ixtoms (infile, outfile) XFILE *infile; /* input file */ XFILE *outfile; /* output file */ X{ X int c; X enum state state = NONE; X X /* LF => CR LF, but leave CR LF alone */ X while ((c = getc (infile)) != EOF) { X#ifdef USE_SIG X if (got_sig) X return (ERRSIG); X#endif X if (!bintoo && BINCHAR(c)) X return (ERRBINF); X IFSTRIP(c); X switch (c) { X case LF: X CHECK_BREAK X if (state == SAWCR) X state = NONE; X else X putc (CR, outfile); X putc (LF, outfile); X break; X case CR: X state = SAWCR; putc (c, outfile); break; X case CTRLZ: X if (ztrunc) X return (0); X /* FALL THROUGH */ X default: X state = NONE; putc (c, outfile); break; X } X } X return (0); X} X X/* set up signal handler for selected signals */ X#ifdef USE_SIG Xvoid setup_sigs () X{ X# ifdef SIGPIPE X if (signal (SIGPIPE, SIG_IGN) != SIG_IGN) X signal (SIGPIPE, cleanup); X# endif X# ifdef SIGHUP X if (signal (SIGHUP, SIG_IGN) != SIG_IGN) X signal (SIGHUP, cleanup); X# endif X# ifdef SIGQUIT X if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) X signal (SIGQUIT, cleanup); X# endif X# ifdef SIGINT X if (signal (SIGINT, SIG_IGN) != SIG_IGN) X signal (SIGINT, cleanup); X# endif X# ifdef SIGTERM X if (signal (SIGTERM, SIG_IGN) != SIG_IGN) X signal (SIGTERM, cleanup); X# endif X} X X/* set flag on signal */ Xvoid cleanup(sig) Xint sig; X{ X signal (sig, SIG_IGN); /* needed for flaky System V Release 2 */ X got_sig = 1; X signal (sig, cleanup); /* ditto */ X} X#endif /* USE_SIG */ X X#define ERRSIZE 200 X X/* prints error message via perror */ Xvoid error (msg1, msg2) Xchar *msg1, *msg2; X{ X char buf[ERRSIZE]; X strcpy (buf, myname); X strcat (buf, ": "); X strcat (buf, msg1); X strcat (buf, msg2); X perror (buf); X fflush (stderr); X} X X/* gives brief usage message */ Xvoid usage() X{ X fprintf (stderr, X"usage: %s [-u | -m] [other options] file ... (or \"%s -h\" for more help)\n", X myname, myname); X} X X/* gives help screen */ X Xvoid give_help() X{ Xprintf ("\ XFile interchange program flip version 0.50 beta, Copyright 1989 Rahul Dhesi,\n\ XAll rights reserved. Both noncommercial and commercial copying, use, and\n\ Xcreation of derivative works are permitted in accordance with the\n\ Xrequirements of the GNU license. This program does newline conversions.\n\ X\n\ X Usage: flip -umhvtb file ...\n\ X\n\ XOne of -u, -m, or -h is required; others are optional. See user manual.\n\ X\n\ X -u convert to **IX format (CR LF => LF, lone CR or LF unchanged,\n\ X trailing control Z removed, embedded control Z unchanged)\n\ X -m convert to MS-DOS format (lone LF => CR LF, lone CR unchanged)\n\ X -h give this help message\n\ X -v be verbose, print filenames as they are processed\n\ X -t touch files (don't preserve timestamps)\n\ X -s strip high bit\n\ X -b convert binary files too (else binary files are left unchanged)\n\ X -z truncate file at first control Z encountered\n\ X\n\ XMay be invoked as \"toix\" (same as \"flip -u\") or \"toms\" (same as \"flip -m\").\n\ X"); Xreturn; X} X X/* normal exits go through here -- atexit would be nice but not portable */ Xvoid flip_exit(stat) Xint stat; X{ X SPEC_EXIT X exit (stat); X} X X/* special code for **IX */ X#ifdef NIX X# ifndef MVFILE Xint MVFILE (src, dest) Xchar *dest; Xchar *src; X{ X char cmd[2 * PATHSIZE]; X sprintf (cmd, "/bin/mv %s %s", src, dest); X return (system(cmd)); X} X# endif /* MVFILE */ X#endif /* NIX */ SHAR_EOF fi echo shar: "extracting 'flip.doc'" '(3769 characters)' if test -f 'flip.doc' then echo shar: "will not over-write existing file 'flip.doc'" else sed 's/^X//' << \SHAR_EOF > 'flip.doc' X Flip 0.5 beta X A newline conversion program X by X Rahul Dhesi X XFlip 0.5 beta is a file interchange program that converts text file formats Xbetween **IX and MS-DOS. It converts lines ending with carriage-return (CR) Xand linefeed (LF) to lines ending with just linefeed, or vice versa. X XFlip 0.5 beta has the following features: X Xo If a file contains isolated CR characters for underlining or X overprinting, Flip does not change them. X Xo When asked to convert a file to the same format that it X already has, Flip causes no change to the file. Thus to X convert all files to **IX format you can type X X flip -u *.* (under MS-DOS) X flip -u * (under **IX) X X and all files will end up right, regardless of whether they X were in MS-DOS or in **IX format to begin with. This also X works in the opposite direction. X Xo Flip preserves file timestamps. You can override this. X Xo Flip is written in C and will compile and run under X MS-DOS/Turbo C, 4.3BSD, and System V. X Xo Flip accepts wildcards and multiple filenames on the X command line. X Xo If a user interrupt aborts Flip, it does not leave behind X any garbage files or cause corruption of the files being X converted. X Xo Flip will normally refuse to convert binary files. You can X override this. X Xo When converting from MS-DOS to **IX format, Flip removes any X trailing control Z (the last character in the file), but X leaves embedded control Z characters unchanged. This minimizes X the possibility of accidentally converting a binary file that X contains a control Z near the beginning. You can override this X and ask Flip to recognize the first control Z found as end-of-file. X Xo Flip can be asked to strip the high (parity) bit as it converts X a file. X X X USAGE X XFlip is normally invoked as: X X flip -umhvtb file ... X XOne of -u, -m, or -h is required. Switches may be given separately or Xcombined together after a dash. For example, the three command lines given Xbelow are equivalent: X X flip -uvt *.c X flip -u -v -t *.c X flip -u -vt *.c X XThe meanings of the switches are as follows. X X -u convert to **IX format (CR LF => LF, lone CR or LF unchanged, X trailing control Z removed, embedded control Z unchanged) X -m convert to MS-DOS format (lone LF => CR LF, lone CR unchanged) X -h give a help message X X -v be verbose, print filenames as they are processed X -t touch files (don't preserve timestamps) X -s strip high bit X -b convert binary files too (else binary files are left unchanged) X -z truncate file at first control Z encountered X XOn systems that allow a program to know its own name, Flip may be renamed (or Xlinked) to a file called "toix" (or "toix.exe" under MS-DOS) for conversion Xto **IX format, or to a file called "toms" (or "toms.exe" under MS-DOS) for Xconversion to MS-DOS format. When invoked with the name "toix" or "toms" XFlip will act as if it were invoked with the -u or -m option respectively. X X COPYRIGHT X XBoth this documentation and Flip 0.5 beta are Copyright 1989 Rahul Dhesi, all Xrights reserved. Permission is granted to copy, use, and distribute for any Xcommercial or noncommercial purpose in accordance with the requirements of Xthe GNU license. X XNote: This software has not been endorsed by the Free Software Foundation, Xthe creator of the GNU license, and I am not affiliated with that Xorganization. X X -- Rahul Dhesi 1989/06/19 SHAR_EOF fi echo shar: "extracting 'flip.h'" '(6945 characters)' if test -f 'flip.h' then echo shar: "will not over-write existing file 'flip.h'" else sed 's/^X//' << \SHAR_EOF > 'flip.h' X/* ::[[ @(#) flip.h 1.13 89/06/19 21:49:22 ]]:: */ X X/* XCopyright 1989 Rahul Dhesi, All rights reserved. X XChecksum: 2174221099 (check or update with "brik") X XANSI-compatibility strategy: X X1. If ANSIPROTO is defined, function prototypes are used, ANSI-style. X If it is not defined, regular function declarations (without a X parameter list) are used. This is achieved with the use of X the PARMS macro. X2. If STDINCLUDE is defined, ANSI-conformant header files are X included. Otherwise functions that would be declared in such X header files are declared individually. X*/ X X#ifndef OK_NL X X/* Define ANSIPROTO and/or STDINCLUDE here if needed */ X#ifdef TURBOC X# define ANSIPROTO X# define STDINCLUDE X#endif /* TURBOC */ X X X X#include <stdio.h> X X#ifndef PARMS X# ifdef ANSIPROTO X# define PARMS(x) x X# else X# define PARMS(x) () X# endif X#endif X X/************************************************************/ X/*** change following definitions as needed for your system */ X/************************************************************/ X/* XPATHSIZE size of buffer(s) to use to hold pathname(s) XPICKNAME Do "#define PICKNAME" if you want the program to know its X name and respond to it. If PICKNAME is not defined, the X program will assume that it is called "flip". XBIGBUF If defined, setvbuf() will be used to set input and X output buffers to BIGBUF characters XDELFILE Must be a function or macro that will accept one filenames X and delete that file, returning zero on success, nonzero X on failure. XMVFILE Must be a function or macro that will take two filenames X and rename the first file to the second file, returning X zero on success, nonzero on failure. XBINCHAR This must be a macro accepting a single character X argument and returning nonzero if and only if that X character is a binary character. By default, BINCHAR X is defined to look up a table, and the table is compiled X in by defining USE_TABLE. XUSE_TABLE If this is defined, flip code will use a table look-up X to decide which characters should be considered binary. XUSE_SIG If this is defined, then signal() will be used so flip X may trap user interrupts and delete temporary files. X If USE_SIG is defined, then SIG_T and INT_EXIT must also X be defined (below). XSIG_T If USE_SIG is defined, then SIG_T must be defined X (or typedef'd) to be the data type returned by X (*signal). Usually int or void. XINT_EXIT If USE_SIG is defined, INT_EXIT must be defined to X be the exit code returned by flip when its execution X is aborted by a user interrupt. XCHECK_BREAK If your operating system requires programs to check X for user interrupts at intervals, define CHECK_BREAK to X be a function or macro that checks for a user interrupt. X Flip will call this at intervals. If not needed, X define CHECK_BREAK to be null. XSPEC_INIT This is invoked to initialize flip. Should be defined to X be either a function call (with trailing semicolon) or X null string. XSPEC_EXIT Like SPEC_INIT, but is called just before flip exits. XSGFTIME This must be a typedef for a data type suitable to store X file times. XGETFT Must be a macro with usage GETFT(file,name,var) that will X take an open file, a filename, and a variable name, and X put in that variable the timestamp of the file. XSETFT Must be a function or macro with usage SETFT(file,name,var) X that will take an open file, a filename, and a variable X name, and set the timestamp of the file from the variable. XWILDCARD If this is defined, the function nextfile() will be called X to expand wildcards. If WILDCARD is not defined, no X wildcard expansion will be done and nextfile() is not X needed. For a description of nextfile() see turboc.c. XNIX If this symbol is defined, some things common to most X implementations of **IX get defined and need not be X individually defined. X*/ X X#ifdef TURBOC X# define PATHSIZE 200 X# define PICKNAME X# define BIGBUF 16384 X# define DELFILE remove Xextern int MVFILE PARMS ((char *src, char *dest)); /* Turbo C */ X# define USE_SIG X# define SIG_T void /* return type from (*signal) */ X# define INT_EXIT 127 /* status when a signal causes exit */ X# define CHECK_BREAK brktst(); Xvoid brktst PARMS ((void)); X# define SPEC_INIT spec_init(); X# define SPEC_EXIT spec_exit(); Xvoid spec_init PARMS ((void)); Xvoid spec_exit PARMS ((void)); X# define WILDCARD X X/* date and time */ X# include <io.h> X typedef struct ftime SGFTIME; X# define GETFT(f,name,var) getftime(fileno(f), &var) X# define SETFT(f,name,var) setftime(fileno(f), &var) X#endif /* TURBOC */ X X#ifdef SYS_V X# define NIX /* see below */ X# define PATHSIZE 200 X# define BIGBUF 16384 X# define MVFILE(src,dest) (!(!link(src,dest)&&!unlink(src))) X# define SIG_T int X#endif /* SYS_V */ X X#ifdef BSD X# define NIX /* see below */ X# define PATHSIZE 1024 X# undef BIGBUF X# define MVFILE rename X# define SIG_T int X#endif /* BSD */ X X#ifdef VMS X# define PATHSIZE 1024 X# define PICKNAME X# define BIGBUF 16384 X# define DELFILE delete X# define MVFILE rename X# define USE_SIG X# define SIG_T int X# define INT_EXIT 127 X# define SPEC_INIT X# define SPEC_EXIT X#endif /* VMS */ X X/************************************************************/ X/*** remaining definitions should not need to be changed ****/ X/************************************************************/ X X/* define ASCII character values for linefeed, carriage return, control Z */ X#define LF 10 X#define CR 13 X#define CTRLZ 26 X X/* error codes */ X#define ERRBINF 1 /* binary file */ X#define ERRSIG 2 /* interrupted by signal */ X X/* how to strip high bit */ X#define IFSTRIP(c) if (strip) c &= 0x7f X X/**** BINCHAR(c) returns nonzero if c is a binary char ****/ X#ifndef BINCHAR X# define USE_TABLE /* use internal table -- see flip.c */ X# define BINCHAR(c) bintab[(c)+1] X#endif X X/* things common to most **IX systems */ X#ifdef NIX X# define SPEC_INIT X# define SPEC_EXIT X# define CHECK_BREAK X# define PICKNAME X# define DELFILE unlink X# define USE_SIG X# define INT_EXIT 127 X# include <sys/types.h> /* for file time */ X# include <sys/stat.h> /* for file time */ X typedef struct stat SGFTIME; X# define GETFT(file,name,var) fstat(fileno(file),&var) X# define SETFT(file,name,var) do { time_t x[2]; x[0] = var.st_atime; \ X x[1] = var.st_mtime; utime (name, x); \ X } while (0) X#endif /* NIX */ X X#endif /* OK_NL */ SHAR_EOF fi echo shar: "extracting 'flip.prj'" '(56 characters)' if test -f 'flip.prj' then echo shar: "will not over-write existing file 'flip.prj'" else sed 's/^X//' << \SHAR_EOF > 'flip.prj' Xflip.c (flip.h) Xgetopt.c (flip.h) Xturboc.c (flip.h) SHAR_EOF fi echo shar: "extracting 'getopt.c'" '(2801 characters)' if test -f 'getopt.c' then echo shar: "will not over-write existing file 'getopt.c'" else sed 's/^X//' << \SHAR_EOF > 'getopt.c' X/* ::[[ @(#) getopt.c 1.4 89/06/19 05:42:37 ]]:: */ X#ifndef LINT Xstatic char sccsid[]="::[[ @(#) getopt.c 1.4 89/06/19 05:42:37 ]]::"; X#endif X X/* XChecksum: 505161377 (check or update this with "brik") X*/ X X/* X * Here's something you've all been waiting for: the AT&T public domain X * source for getopt(3). It is the code which was given out at the 1985 X * UNIFORUM conference in Dallas. I obtained it by electronic mail X * directly from AT&T. The people there assure me that it is indeed X * in the public domain. X * X * There is no manual page. That is because the one they gave out at X * UNIFORUM was slightly different from the current System V Release 2 X * manual page. The difference apparently involved a note about the X * famous rules 5 and 6, recommending using white space between an option X * and its first argument, and not grouping options that have arguments. X * Getopt itself is currently lenient about both of these things White X * space is allowed, but not mandatory, and the last option in a group can X * have an argument. That particular version of the man page evidently X * has no official existence, and my source at AT&T did not send a copy. X * The current SVR2 man page reflects the actual behavor of this getopt. X * However, I am not about to post a copy of anything licensed by AT&T. X */ X X/* XMinor modifications by Rahul Dhesi 1989/03/06 X*/ X X#include "flip.h" X X#ifdef STDINCLUDE X# include <string.h> X#else Xextern int strcmp PARMS ((char *, char *)); Xextern char *strchr PARMS ((char *, char)); X#endif X X/* Avoid possible compiler warning if we simply redefine NULL or EOF */ X#define XNULL 0 X#define XEOF (-1) X X#define ERR(szz,czz) if(opterr){fprintf(stderr,"%s%s%c\n",argv[0],szz,czz);} X Xint opterr = 1; Xint optind = 1; Xint optopt; Xchar *optarg; X Xint Xgetopt(argc, argv, opts) Xint argc; Xchar **argv, *opts; X{ X static int sp = 1; X register int c; X register char *cp; X X if(sp == 1) X if(optind >= argc || X argv[optind][0] != '-' || argv[optind][1] == '\0') X return(XEOF); X else if(strcmp(argv[optind], "--") == XNULL) { X optind++; X return(XEOF); X } X optopt = c = argv[optind][sp]; X if(c == ':' || (cp=strchr(opts, c)) == XNULL) { X ERR(": illegal option -- ", c); X if(argv[optind][++sp] == '\0') { X optind++; X sp = 1; X } X return('?'); X } X if(*++cp == ':') { X if(argv[optind][sp+1] != '\0') X optarg = &argv[optind++][sp+1]; X else if(++optind >= argc) { X ERR(": option requires an argument -- ", c); X sp = 1; X return('?'); X } else X optarg = argv[optind++]; X sp = 1; X } else { X if(argv[optind][++sp] == '\0') { X sp = 1; X optind++; X } X optarg = XNULL; X } X return(c); X} SHAR_EOF fi echo shar: "extracting 'makefile.nix'" '(1635 characters)' if test -f 'makefile.nix' then echo shar: "will not over-write existing file 'makefile.nix'" else sed 's/^X//' << \SHAR_EOF > 'makefile.nix' X# Makefile for flip for **IX. ::[[ @(#) makefile 1.5 89/06/19 15:15:10 ]]:: X X# The contents of this makefile are hereby released to the public domain. X# -- Rahul Dhesi 1989/06/19 X X# Before use make sure this file is called "makefile". (Rename it if X# necessary.) Then invoke as follows: X X# "make sys_v" makes executable flip for System V Release 2 X# "make bsd" makes executable flip for 4.3BSD X# "make install" moves flip into BINDIR, copies flip.1 into MANDIR X# "make clean" deletes object and executable files X X# Where to install executable and manual files on "make install". The trailing X# "/." forces an error message if the destination directory doesn't exist. XBINDIR = /usr/local/bin/. XMANDIR = /usr/man/man1/. X X# CC is compiler, LD is loader (may be same as compiler), CFLAGS are flags X# for compiler, LDFLAGS are flags for loader, CFMORE are additional X# (relatively unchanging) flags for compiler X XCC = cc XCFLAGS = XCFMORE = -c -DNDEBUG -O XLD = cc XLDFLAGS = -o flip X X# If your system does not supply getopt as a library function, X# add getopt.o to the RHS list on the next line and uncomment the X# two nonblank lines after that. XOBJS = flip.o X X#getopt.o: getopt.c flip.h X# $(CC) $(CFLAGS) $(CFMORE) $*.c X Xnothing: X @echo 'Please type "make sys_v" or "make bsd" or "make uport"' X Xsys_v: X make "CFLAGS=-DSYS_V" flip X Xuport: X make "CFLAGS=-DSYS_V -Ml" "LDFLAGS=-Ml -o flip" flip X Xbsd: X make "CFLAGS=-DBSD" flip X Xflip: $(OBJS) X $(LD) $(LDFLAGS) $(OBJS) X Xflip.o: flip.c flip.h X $(CC) $(CFLAGS) $(CFMORE) $*.c X Xclean: X rm -f *.o core flip X Xinstall: X mv flip $(BINDIR) X cp flip.1 $(MANDIR) SHAR_EOF fi echo shar: "extracting 'makefile.tcc'" '(491 characters)' if test -f 'makefile.tcc' then echo shar: "will not over-write existing file 'makefile.tcc'" else sed 's/^X//' << \SHAR_EOF > 'makefile.tcc' X# Makefile for flip for MS-DOS and Turbo C 2.0. The supplied turboc.cfg X# configuration file must be in the current directory; edit it to make X# sure the include directories are correct. X XCC = tcc XCFLAGS = -c -DTURBOC -DLINT -DNDEBUG XLD = tcc XLDFLAGS = -eFLIP X XOBJS = flip.obj getopt.obj turboc.obj X Xflip: $(OBJS) X $(LD) $(LDFLAGS) $(OBJS) X Xflip.obj: flip.c flip.h X $(CC) $(CFLAGS) $*.c X Xgetopt.obj: getopt.c flip.h X $(CC) $(CFLAGS) $*.c X Xturboc.obj: turboc.c flip.h X $(CC) $(CFLAGS) $*.c SHAR_EOF fi echo shar: "extracting 'turboc.c'" '(10224 characters)' if test -f 'turboc.c' then echo shar: "will not over-write existing file 'turboc.c'" else sed 's/^X//' << \SHAR_EOF > 'turboc.c' X/* ::[[ @(#) turboc.c 1.5 89/06/19 15:22:21 ]]:: */ X#ifndef LINT Xstatic char sccsid[]="::[[ @(#) turboc.c 1.5 89/06/19 15:22:21 ]]::"; X#endif X X/* XCopyright 1989 Rahul Dhesi, All rights reserved. X XThis file is used only for MS-DOS & Turbo C. X*/ X X/* XChecksum: 3933529970 (check or update this with "brik") X*/ X X/* Xnextfile() is a general wildcard expansion function that may be used Xwith other programs. Usage instructions are below. It does not Xsimply expand wildcards in an entire argument list. Instead, it is Xcalled in a loop as described below, and returns one matching Xfilename each time it is called. X XThese functions are for the SMALL MEMORY MODEL ONLY. X*/ X Xextern unsigned _stklen = 10000; X X#include "assert.h" X#include "flip.h" X X#define FMAX 2 /* Number of different filename patterns */ X#define PATHSIZE 200 /* Size of MS-DOS pathname */ X#define NULL 0 X X#ifdef ANSIPROTO Xchar *strtcpy (char *, char *); Xint strlen (char *); Xchar *strcpy (char *, char *); X#endif X X X/* Structure definitions for MS-DOS software interrupt intdos() */ X Xstruct WORD_REGISTERS { X unsigned int ax, bx, cx, dx, si, di, carry, flags; X}; X X/* byte registers */ X Xstruct BYTE_REGISTERS { X unsigned char al, ah, bl, bh, cl, ch, dl, dh; X}; X Xunion REGS { X struct WORD_REGISTERS x; X struct BYTE_REGISTERS h; X}; X Xint intdos (union REGS *, union REGS *); X X/* Xformat of disk transfer address after MS-DOS calls FindFirst and XFindNext X*/ Xstruct dta_t { X char junk[22]; X int time; X int date; X long size; X char fname[13]; X char just_in_case[4]; /* in case MS-DOS writes too much */ X}; X Xvoid setdta (struct dta_t *); Xvoid fcbpath (struct dta_t *, char *, char *); X X/*******************/ X/* Xnextfile() returns the name of the next source file matching a filespec. X XINPUT X what: A flag specifying what to do. If "what" is 0, nextfile() X initializes itself. If "what" is 1, nextfile() returns the next X matching filename. X filespec: The filespec, usually containing wildcard characters, that X specifies which files are needed. If "what" is 0, filespec must be X the filespec for which matching filenames are needed. If "what" is 1, X nextfile() does not use "filespec" and "filespec" should be NULL to X avoid an assertion error during debugging. X fileset: nextfile() can keep track of more than one set of filespecs. X The fileset specifies which filespec is being matched and therefore X which set of files is being considered. "fileset" can be in the X range 0:FMAX. Initialization of one fileset does not affect the X other filesets. X XOUTPUT X IF what == 0 THEN X return value is NULL X ELSE IF what == 1 THEN X IF a matching filename is found THEN X return value is pointer to matching filename including supplied path X ELSE X IF at least one file matched previously but no more match THEN X return value is NULL X ELSE IF supplied filespec never matched any filename THEN X IF this is the first call with what == 1 THEN X return value is pointer to original filespec X ELSE X return value is NULL X END IF X END IF X END IF X END IF X XNOTE X X Initialization done when "what"=0 is not dependent on the correctness X of the supplied filespec but simply initializes internal variables X and makes a local copy of the supplied filespec. If the supplied X filespec was illegal, the only effect is that the first time that X nextfile() is called with "what"=1, it will return the original X filespec instead of a matching filename. That the filespec was X illegal will become obvious when the caller attempts to open the X returned filename for input/output and the open attempt fails. X XUSAGE HINTS X Xnextfile() can be used in the following manner: X X char *filespec; -- will point to filespec X char *this_file; -- will point to matching filename X filespec = parse_command_line(); -- may contain wildcards X FILE *stream; X X nextfile (0, filespec, 0); -- initialize fileset 0 X while ((this_file = nextfile(1, (char *) NULL, 0)) != NULL) { X stream = fopen (this_file, "whatever"); X if (stream == NULL) X printf ("could not open %s\n", this_file); X else X perform_operations (stream); X } X*/ X Xchar *nextfile (what, filespec, fileset) Xint what; /* whether to initialize or match */ Xregister char *filespec; /* filespec to match if initializing */ Xregister int fileset; /* which set of files */ X{ X static struct dta_t new_dta [FMAX+1]; /* our own private dta */ X static int first_time [FMAX+1]; X static char pathholder [FMAX+1][PATHSIZE]; /* holds a pathname to return */ X static char saved_fspec [FMAX+1][PATHSIZE];/* our own copy of filespec */ X union REGS regs; X X assert(fileset >= 0 && fileset <= FMAX); X if (what == 0) { X assert(filespec != NULL); X strcpy (saved_fspec[fileset], filespec); /* save the filespec */ X first_time[fileset] = 1; X return ((char *) NULL); X } X X setdta (&new_dta[fileset]); /* set new dta -- our very own */ X assert(what == 1); X assert(filespec == NULL); X assert(first_time[fileset] == 0 || first_time[fileset] == 1); X X if (first_time[fileset]) { /* first time -- initialize etc. */ X /* find first matching file */ X regs.h.ah = 0x4e; /* FindFirst MS-DOS call */ X regs.x.dx = (unsigned int) saved_fspec[fileset]; /* filespec to match */ X regs.x.cx = 0; /* search attributes */ X intdos (®s, ®s); X } else { X /* find next matching file */ X regs.h.ah = 0x4f; /* FindNext MS-DOS call */ X intdos (®s, ®s); X } X X if (regs.x.carry != 0) { /* if error status */ X if (first_time[fileset]) { /* if file never matched then */ X first_time[fileset] = 0; X return (saved_fspec[fileset]);/* return original filespec */ X } else { /* else */ X first_time[fileset] = 0; /* */ X return ((char *) NULL); /* return (NULL) for no more */ X } X } else { /* a file matched */ X first_time[fileset] = 0; X /* add path info */ X fcbpath (&new_dta[fileset], saved_fspec[fileset], pathholder[fileset]); X return (pathholder[fileset]); /* matching path */ X } X} /* nextfile */ X X/*******************/ X/* This function sets the dta to a new dta */ Xvoid setdta (dta) Xstruct dta_t *dta; X{ X union REGS regs; X regs.h.ah = 0x1a; /* SetDTA Call */ X regs.x.dx = (unsigned int) dta; /* new DTA address */ X intdos (®s, ®s); X} X X/*******************/ X/* Xfcbpath() accepts a pointer to the Disk Transfer Area, a character Xpointer to a pathname that may contain wildcards, and a character Xpointer to a buffer. It copies into the buffer the path prefix from Xthe pathname and the filename prefix from the DTA so that it forms a Xcomplete path. X*/ X Xvoid fcbpath (dta, old_path, new_path) Xstruct dta_t *dta; Xchar *old_path; Xregister char *new_path; X{ X register int i; X int length, start_pos; X X strcpy(new_path, old_path); /* copy the whole thing first */ X length = strlen(new_path); X i = length - 1; /* i points to end of path */ X while (i >= 0 && new_path[i] != '/' && new_path[i] != '\\' && new_path[i] != ':') X i--; X /* either we found a "/", "\", or ":", or we reached the beginning of X the name. In any case, i points to the last character of the X path part. */ X start_pos = i + 1; X for (i = 0; i < 13; i++) X new_path[start_pos+i] = dta->fname[i]; X new_path[start_pos+13] = '\0'; X} X/* -- END OF nextfile() and related functions -- */ X X/* XFor Turbo C, we implement MVFILE as a file copy to avoid wildcard Xexpansion finding the same file again after a direct rename. To Xavoid leaving a partially-written destination file, we trap ^C, Xand if it occurs, delete the dest file and quickly do just a simple Xrename to it. X*/ X X#define BLOCKSIZ 16384 X#include <fcntl.h> X#include <sys/stat.h> X#include <io.h> X#include <signal.h> X Xvoid handler (int); /* ^C handler */ Xchar *xsrc, *xdest; /* global for handler() */ Xvoid (*oldsignal) (int); /* global for handler() */ Xint infd, outfd; /* global for handler() */ Xint brk_flag; /* ms-dos break flag status */ Xint getcbrk (void); Xint setcbrk (int); X Xint MVFILE (src, dest) Xchar *src; Xchar *dest; X{ X int retval; X char buf[BLOCKSIZ]; X X retval = -1; /* default error return */ X xsrc = src; xdest = dest; /* make visible to handler */ X X oldsignal = signal (SIGINT, handler); X outfd = open (dest, O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE); X if (outfd == -1) X goto erret; X infd = open (src, O_RDONLY|O_BINARY); X if (infd == -1) { X close (outfd); X goto erret; X } X while ((retval = read (infd, buf, BLOCKSIZ)) > 0) { X if (write (outfd, buf, retval) != retval) { X retval = -1; X goto done; X } X } X done: /* retval is zero on normal exit from loop, else nonzero */ X close (infd); close (outfd); X X if (retval == 0) { X signal (SIGINT, oldsignal); /* avoid race condition */ X unlink (src); X return (retval); X } Xerret: X /* if error during read/write, do rename to avoid loss of dest file */ X unlink (dest); X retval = rename (src, dest); X signal (SIGINT, oldsignal); X return (retval); X} X Xvoid handler (int sig) X{ X signal (sig, SIG_IGN); X close (infd); close (outfd); X unlink (xdest); X rename (xsrc, xdest); X signal (sig, oldsignal); X raise (sig); /* original handler gets signal now */ X} X X#include <conio.h> Xvoid brktst() { kbhit(); } /* test for user interrupt */ X Xvoid spec_init() X{ X brk_flag = getcbrk(); X setcbrk (0); X} X Xvoid spec_exit() X{ X setcbrk (brk_flag); X} SHAR_EOF fi echo shar: "extracting 'turboc.cfg'" '(108 characters)' if test -f 'turboc.cfg' then echo shar: "will not over-write existing file 'turboc.cfg'" else sed 's/^X//' << \SHAR_EOF > 'turboc.cfg' X-wamp X-wcln X-wuse X-wrvl X-wsig X-wamb X-wstv X-wpro X-wnod X-wucp X-A X-O X-Z X-k- X-d X-I\turboc\include X-L\turboc\lib SHAR_EOF fi exit 0 # End of shell archive -- Rahul Dhesi <dhesi@bsu-cs.bsu.edu> UUCP: ...!{iuvax,pur-ee}!bsu-cs!dhesi Career change search is on -- ask me for my resume