[alt.sources] newline conversion program

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 (&regs, &regs);
X   } else {
X      /* find next matching file */
X      regs.h.ah = 0x4f;                   /* FindNext MS-DOS call     */
X      intdos (&regs, &regs);
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 (&regs, &regs);
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