diff -acrpNC5 findutils-4.1.orig/doc/find.texi findutils-4.1.djgpp/doc/find.texi
*** findutils-4.1.orig/doc/find.texi	Fri Nov  4 04:13:50 1994
--- findutils-4.1.djgpp/doc/find.texi	Sun May 28 02:42:06 2000
***************
*** 4,16 ****
  @settitle Finding Files
  @c For double-sided printing, uncomment:
  @c @setchapternewpage odd
  @c %**end of header
  
! @set EDITION 1.1
  @set VERSION 4.1
! @set UPDATED November 1994
  
  @iftex
  @finalout
  @end iftex
  
--- 4,16 ----
  @settitle Finding Files
  @c For double-sided printing, uncomment:
  @c @setchapternewpage odd
  @c %**end of header
  
! @set EDITION 1.1a
  @set VERSION 4.1
! @set UPDATED April 1996
  
  @iftex
  @finalout
  @end iftex
  
*************** The default is system-dependent.
*** 424,436 ****
  @table @code
  @item --database=@var{path}
  @itemx -d @var{path}
  Instead of searching the default file name database, search the file
  name databases in @var{path}, which is a colon-separated list of
! database file names.  You can also use the environment variable
! @code{LOCATE_PATH} to set the list of database files to search.  The
! option overrides the environment variable if both are used.
  @end table
  
  @node Shell Pattern Matching
  @subsection Shell Pattern Matching
  
--- 424,437 ----
  @table @code
  @item --database=@var{path}
  @itemx -d @var{path}
  Instead of searching the default file name database, search the file
  name databases in @var{path}, which is a colon-separated list of
! database file names.  (A semicolon is used on MS-DOS systems.)  You can
! also use the environment variable @code{LOCATE_PATH} to set the list of
! database files to search.  The option overrides the environment variable
! if both are used.
  @end table
  
  @node Shell Pattern Matching
  @subsection Shell Pattern Matching
  
*************** names, to shell patterns.  A @dfn{shell 
*** 439,449 ****
  contain the following special characters, which are known as
  @dfn{wildcards} or @dfn{metacharacters}.
  
  You must quote patterns that contain metacharacters to prevent the shell
  from expanding them itself.  Double and single quotes both work; so does
! escaping with a backslash.
  
  @table @code
  @item *
  Matches any zero or more characters.
  
--- 440,452 ----
  contain the following special characters, which are known as
  @dfn{wildcards} or @dfn{metacharacters}.
  
  You must quote patterns that contain metacharacters to prevent the shell
  from expanding them itself.  Double and single quotes both work; so does
! escaping with a backslash.  (Don't use backslashes on MS-DOS, except for
! escaping quote characters, because backslashes in other places are
! treated as directory separators.)
  
  @table @code
  @item *
  Matches any zero or more characters.
  
*************** placing a @samp{!} or @samp{^} immediate
*** 460,470 ****
  Thus, @samp{[^A-Z@@]} matches any character except an uppercase letter
  or an at sign.
  
  @item \
  Removes the special meaning of the character that follows it.  This
! works even in character classes.
  @end table
  
  In the @code{find} tests that do shell pattern matching (@samp{-name},
  @samp{-path}, etc.), wildcards in the pattern do not match a @samp{.}
  at the beginning of a file name.  This is not the case for
--- 463,474 ----
  Thus, @samp{[^A-Z@@]} matches any character except an uppercase letter
  or an at sign.
  
  @item \
  Removes the special meaning of the character that follows it.  This
! works even in character classes.  (On MS-DOS, only the quote characters
! are protected by the backslash.)
  @end table
  
  In the @code{find} tests that do shell pattern matching (@samp{-name},
  @samp{-path}, etc.), wildcards in the pattern do not match a @samp{.}
  at the beginning of a file name.  This is not the case for
*************** find . -path './src/emacs' -prune -o -pr
*** 830,851 ****
  @end example
  @end deffn
  
  @deffn Option -noleaf
  Do not optimize by assuming that directories contain 2 fewer
! subdirectories than their hard link count.  This option is needed when
! searching filesystems that do not follow the Unix directory-link
  convention, such as CD-ROM or MS-DOS filesystems or AFS volume mount
  points.  Each directory on a normal Unix filesystem has at least 2 hard
  links: its name and its @file{.}  entry.  Additionally, its
  subdirectories (if any) each have a @file{..}  entry linked to that
  directory.  When @code{find} is examining a directory, after it has
  statted 2 fewer subdirectories than the directory's link count, it knows
  that the rest of the entries in the directory are non-directories
  (@dfn{leaf} files in the directory tree).  If only the files' names need
  to be examined, there is no need to stat them; this gives a significant
! increase in search speed.
  @end deffn
  
  @node Filesystems
  @section Filesystems
  
--- 834,857 ----
  @end example
  @end deffn
  
  @deffn Option -noleaf
  Do not optimize by assuming that directories contain 2 fewer
! subdirectories than their hard link count.  This option might be needed
! when searching filesystems that do not follow the Unix directory-link
  convention, such as CD-ROM or MS-DOS filesystems or AFS volume mount
  points.  Each directory on a normal Unix filesystem has at least 2 hard
  links: its name and its @file{.}  entry.  Additionally, its
  subdirectories (if any) each have a @file{..}  entry linked to that
  directory.  When @code{find} is examining a directory, after it has
  statted 2 fewer subdirectories than the directory's link count, it knows
  that the rest of the entries in the directory are non-directories
  (@dfn{leaf} files in the directory tree).  If only the files' names need
  to be examined, there is no need to stat them; this gives a significant
! increase in search speed.  Usually, you won't need this option even on
! MS-DOS systems, so unless you see that some subdirectories aren't
! listed, don't use it: it makes @code{find} run 2 to 4 times slower.
  @end deffn
  
  @node Filesystems
  @section Filesystems
  
*************** filesystem types vary among different ve
*** 870,883 ****
  list of filesystem types that are accepted on some version of Unix or
  another is:
  @example
  ufs 4.2 4.3 nfs tmp mfs S51K S52K
  @end example
  You can use @samp{-printf} with the @samp{%F} directive to see the types
  of your filesystems.  @xref{Print File Information}.  @samp{-fstype} is
! usually used with @samp{-prune} to avoid searching remote filesystems
! (@pxref{Directories}). 
  @end deffn
  
  @node Combining Primaries With Operators
  @section Combining Primaries With Operators
  
--- 876,913 ----
  list of filesystem types that are accepted on some version of Unix or
  another is:
  @example
  ufs 4.2 4.3 nfs tmp mfs S51K S52K
  @end example
+ 
+ The DJGPP port of @code{find} recognizes the following filesystem types:
+ 
+ @table @code
+ @item hd
+ a hard (aka fixed) disk
+ @item fd
+ a floppy disk
+ @item cdrom
+ a CD-ROM disk
+ @item ram
+ a RAM-disk
+ @item net
+ a networked drive
+ @item dblsp
+ a disk compressed with the DblSpace method
+ @item stac
+ a disk compressed with the Stacker method
+ @item subst
+ a SUBSTed disk
+ @item join
+ a JOINed disk
+ @end table
+ 
  You can use @samp{-printf} with the @samp{%F} directive to see the types
  of your filesystems.  @xref{Print File Information}.  @samp{-fstype} is
! usually used with @samp{-prune} to avoid searching remote filesystems or
! removable media (@pxref{Directories}). 
  @end deffn
  
  @node Combining Primaries With Operators
  @section Combining Primaries With Operators
  
*************** specified as with the @code{printf} C fu
*** 1025,1034 ****
--- 1055,1068 ----
  @deffn Action -fprintf file format
  True; like @samp{-printf} but write to @var{file} like @samp{-fprint}
  (@pxref{Print File Name}).
  @end deffn
  
+ When you work under @code{COMMAND.COM} or any of its work-alikes, you
+ have to double every @samp{%} character, because they are special to
+ those shells.
+ 
  @menu
  * Escapes::
  * Format Directives::
  * Time Formats::
  @end menu
*************** printed to the standard error output (be
*** 1068,1077 ****
--- 1102,1117 ----
  
  @samp{-printf} and @samp{-fprintf} support the following format
  directives to print information about the file being processed.  Unlike
  the C @code{printf} function, they do not support field width specifiers.
  
+ On MS-DOS, you will have to type 2 @samp{%} characters for each one you
+ want to pass to @code{find}.  That's because one of them is removed by
+ the standard shell @code{COMMAND.COM} which uses @samp{%} for
+ environment variable substitution.  Thus, you will have to write
+ @samp{%%f} for the filename and @samp{%%%%} for the literal @samp{%}.
+ 
  @samp{%%} is a literal percent sign.  A @samp{%} character followed by
  any other character is discarded (but the other character is printed),
  and a warning message is printed to the standard error output (because
  it was probably a typo).
  
*************** the file @file{/tmp/master}:
*** 1304,1320 ****
  @example
  find . -name '*.h' -exec diff -u '@{@}' /tmp/master ';'
  @end example
  @end deffn
  
  @node Multiple Files
  @subsection Multiple Files
  
! Sometimes you need to process files alone.  But when you
! don't, it is faster to run a command on as many files as possible at a
! time, rather than once per file.  Doing this saves on the time it takes
! to start up the command each time.
  
  To run a command on more than one file at once, use the @code{xargs}
  command, which is invoked like this:
  
  @example
--- 1344,1386 ----
  @example
  find . -name '*.h' -exec diff -u '@{@}' /tmp/master ';'
  @end example
  @end deffn
  
+ @deffn Action -dosexec command ;
+ Like @samp{-exec}, but submits the filename to @var{command} in MS-DOS
+ format by converting all Unix-style forward slashes to DOS-style
+ backslashes.  This is useful for invoking native DOS programs and
+ commands internal to @code{COMMAND.COM} that don't understand Unix-style
+ forward slashes.  Note that the above conversion is done unconditionally
+ and you cannot avoid you by using any quotes; in particular, @code{find}
+ couldn't care less if the arguments aren't filenames at all.  Also note
+ that the way this action is implemented, it affects all the @samp{-exec}
+ and @samp{-ok} (@pxref{Querying}) actions for this invocation of
+ @code{find}; so mixing @samp{-exec}, @samp{-ok} and @samp{-dosexec}
+ might be unwise unless the programs involved understand both kinds of
+ slashes.
+ 
+ For example, here is a command that will rename each file with a
+ @file{.cpp} extension to have a @file{.cc} extension, in the current
+ directory and all of its subdirectories:
+ 
+ @example
+ find . -name '*.cpp' -dosexec command /c ren @{@} '*.cc' ;
+ @end example
+ 
+ (Note that on MS-DOS you don't have to quote the @samp{@{@}} construct
+ and the semicolon.)
+ @end deffn
+ 
  @node Multiple Files
  @subsection Multiple Files
  
! Sometimes you need to process files one by one.  But when you don't,
! it is faster to run a command on as many files as possible at a time,
! rather than once per file.  Doing this saves on the time it takes to
! start up the command each time.
  
  To run a command on more than one file at once, use the @code{xargs}
  command, which is invoked like this:
  
  @example
*************** xargs @r{[}@var{option}@dots{}@r{]} @r{[
*** 1322,1342 ****
  @end example
  
  @code{xargs} reads arguments from the standard input, delimited by
  blanks (which can be protected with double or single quotes or a
  backslash) or newlines.  It executes the @var{command} (default is
! @file{/bin/echo}) one or more times with any @var{initial-arguments}
! followed by arguments read from standard input.  Blank lines on the
! standard input are ignored.
  
  Instead of blank-delimited names, it is safer to use @samp{find -print0}
  or @samp{find -fprint0} and process the output by giving the @samp{-0}
  or @samp{--null} option to GNU @code{xargs}, GNU @code{tar}, GNU
  @code{cpio}, or @code{perl}.
  
! You can use shell command substitution (backquotes) to process a list of
! arguments, like this:
  
  @example
  grep -l sprintf `find $HOME -name '*.c' -print`
  @end example
  
--- 1388,1409 ----
  @end example
  
  @code{xargs} reads arguments from the standard input, delimited by
  blanks (which can be protected with double or single quotes or a
  backslash) or newlines.  It executes the @var{command} (default is
! @file{echo} on MS-DOS systems and @file{/bin/echo} elsewhere) one or
! more times with any @var{initial-arguments} followed by arguments read
! from standard input.  Blank lines on the standard input are ignored.
  
  Instead of blank-delimited names, it is safer to use @samp{find -print0}
  or @samp{find -fprint0} and process the output by giving the @samp{-0}
  or @samp{--null} option to GNU @code{xargs}, GNU @code{tar}, GNU
  @code{cpio}, or @code{perl}.
  
! Except with MS-DOS native shells (that don't support command
! substitution), you can use shell command substitution (backquotes) to
! process a list of arguments, like this:
  
  @example
  grep -l sprintf `find $HOME -name '*.c' -print`
  @end example
  
*************** However, that method produces an error i
*** 1344,1354 ****
  file names exceeds the operating system's command-line length limit.
  @code{xargs} avoids that problem by running the command as many times as
  necessary without exceeding the limit:
  
  @example
! find $HOME -name '*.c' -print | grep -l sprintf
  @end example
  
  However, if the command needs to have its standard input be a terminal
  (@code{less}, for example), you have to use the shell command
  substitution method.
--- 1411,1421 ----
  file names exceeds the operating system's command-line length limit.
  @code{xargs} avoids that problem by running the command as many times as
  necessary without exceeding the limit:
  
  @example
! find $HOME -name '*.c' -print | xargs grep -l sprintf
  @end example
  
  However, if the command needs to have its standard input be a terminal
  (@code{less}, for example), you have to use the shell command
  substitution method.
*************** the argument strings.
*** 1475,1486 ****
--- 1542,1571 ----
  Run up to @var{max-procs} processes at a time; the default is 1.  If
  @var{max-procs} is 0, @code{xargs} will run as many processes as
  possible at a time.  Use the @samp{-n}, @samp{-s}, or @samp{-l} option
  with @samp{-P}; otherwise chances are that the command will be run only
  once.
+ 
+ On MS-DOS, you cannot run more than 1 process at a time.
  @end table
  
+ When you run @code{xargs} on MS-DOS, the maxumum length of the arguments
+ is further limited by the inherent restriction in the operating system
+ call that invokes child programs.  When the child program starts, it
+ gets the command-line tail which cannot be longer than 126 characters.
+ When DJGPP programs are invoked by @code{xargs}, they don't suffer from
+ this limitation, so @code{xargs} does not automatically limit the
+ maximum command-line length so that it won't get into the way of
+ benefits from using DJGPP programs.  It is your responsibility to know
+ which programs can and which cannot get long command lines, and use the
+ @code{-s 126} option with those which cannot.  If any of the commands
+ are invoked with @code{-dosexec} action (@pxref{Single File}),
+ @code{xargs} automatically impose the 126-character restriction.
+ (Actually, only the tail of the command, without the command name
+ itself, is limited to 126 characters, so @code{xargs} limits the command
+ line to 126 + 1 blank + the length of the command name.)
+ 
  @node Interspersing File Names
  @subsubsection Interspersing File Names
  
  @code{xargs} can insert the name of the file it is processing between
  arguments you give for the command.  Unless you also give options to
*************** use the @code{find} primary @samp{-ok} i
*** 1519,1528 ****
--- 1604,1624 ----
  Like @samp{-exec} (@pxref{Single File}), but ask the user first (on
  the standard input); if the response does not start with @samp{y} or
  @samp{Y}, do not run the command, and return false.
  @end deffn
  
+ @deffn Action -dosok command ;
+ Like @samp{-dosexec} (@pxref{Single File}), but ask the user first (on
+ the standard input); if the response does not start with @samp{y} or
+ @samp{Y}, do not run the command, and return false.  Like
+ @samp{-dosexec}, this action also affects all the other @samp{-ok} and
+ @samp{-exec} (@pxref{Single File}) actions for this invocation of
+ @code{find}; so mixing @samp{-exec}, @samp{-ok} and @samp{-dosok} might
+ be unwise unless the programs involved understand both kinds of
+ slashes.
+ @end deffn
+ 
  When processing multiple files with a single command, to query the user
  you give @code{xargs} the following option.  When using this option, you
  might find it useful to control the number of files processed per
  invocation of the command (@pxref{Limiting Command Size}).
  
*************** unstripped ones in @file{ubins}.
*** 1589,1598 ****
--- 1685,1698 ----
  @example
  find /usr/local -type f -perm +a=x \
    \( -exec unstripped '@{@}' \; -fprint ubins -o -fprint sbins \)
  @end example
  
+ Note that due to limitations of native MS-DOS shells, this technique is
+ unavailable on MS-DOS (@code{COMMAND.COM} doesn't return the exit code
+ of the last program it executed).
+ 
  @node Common Tasks, Databases, Actions, Top
  @chapter Common Tasks
  
  The sections that follow contain some extended examples that both give a
  good idea of the power of these programs, and show you how to solve
*************** nightly.
*** 1849,1860 ****
  
  In networked environments, it often makes sense to build a database at
  the root of each filesystem, containing the entries for that filesystem.
  @code{updatedb} is then run for each filesystem on the fileserver where
  that filesystem is on a local disk, to prevent thrashing the network.
! Here are the options to @code{updatedb} to select which directories each
! database contains entries for:
  
  @table @code
  @item --localpaths='@var{path}@dots{}'
  Non-network directories to put in the database.
  Default is @file{/}.
--- 1949,1960 ----
  
  In networked environments, it often makes sense to build a database at
  the root of each filesystem, containing the entries for that filesystem.
  @code{updatedb} is then run for each filesystem on the fileserver where
  that filesystem is on a local disk, to prevent thrashing the network.
! Here are the options to @code{updatedb} shell script to select which
! directories each database contains entries for:
  
  @table @code
  @item --localpaths='@var{path}@dots{}'
  Non-network directories to put in the database.
  Default is @file{/}.
*************** Default is system-dependent, but typical
*** 1874,1883 ****
--- 1974,1986 ----
  @item --netuser=@var{user}
  The user to search network directories as, using @code{su}.
  Default is @code{daemon}.
  @end table
  
+ Note that the simplified @file{updatedb.bat} batch file used on MS-DOS
+ doesn't support these options.
+ 
  @node Database Formats
  @section Database Formats
  
  The file name databases contain lists of files that were in particular
  directory trees when the databases were last updated.  The file name
*************** and count bytes made printable:
*** 1962,1972 ****
  @node Old Database Format
  @subsection Old Database Format
  
  The old database format is used by Unix @code{locate} and @code{find}
  programs and earlier releases of the GNU ones.  @code{updatedb} produces
! this format if given the @samp{--old-format} option.
  
  @code{updatedb} runs programs called @code{bigram} and @code{code} to
  produce old-format databases.  The old format differs from the new one
  in the following ways.  Instead of each entry starting with an
  offset-differential count byte and ending with a null, byte values from
--- 2065,2076 ----
  @node Old Database Format
  @subsection Old Database Format
  
  The old database format is used by Unix @code{locate} and @code{find}
  programs and earlier releases of the GNU ones.  @code{updatedb} produces
! this format if given the @samp{--old-format} option (supported by the
! MS-DOS @file{updatedb.bat} batch file).
  
  @code{updatedb} runs programs called @code{bigram} and @code{code} to
  produce old-format databases.  The old format differs from the new one
  in the following ways.  Instead of each entry starting with an
  offset-differential count byte and ending with a null, byte values from
*************** purpose of counting the lines.  Implies 
*** 2155,2164 ****
--- 2259,2275 ----
  Use at most @var{max-args} arguments per command line.  Fewer than
  @var{max-args} arguments will be used if the size (see the @samp{-s}
  option) is exceeded, unless the @samp{-x} option is given, in which case
  @code{xargs} will exit.
  
+ @item --dos-format
+ @item -D
+ Convert the filenames to DOS format by replacing forward slashes with
+ backslashes before submitting the filenames to the command.  Implies a
+ limit on the command-line length that is 127 characters plus the length
+ of the command name.
+ 
  @item --interactive
  @itemx -p
  Prompt the user about whether to run each command line and read a line
  from the terminal.  Only run the command line if the response starts
  with @samp{y} or @samp{Y}.  Implies @samp{-t}.
diff -acrpNC5 findutils-4.1.orig/find/defs.h findutils-4.1.djgpp/find/defs.h
*** findutils-4.1.orig/find/defs.h	Wed Nov  2 20:59:14 1994
--- findutils-4.1.djgpp/find/defs.h	Sun May 28 02:42:06 2000
*************** struct predicate
*** 193,203 ****
  };
  
  /* find library function declarations.  */
  
  /* dirname.c */
! char *dirname P_((char *path));
  
  /* error.c */
  void error P_((int status, int errnum, char *message, ...));
  
  /* listfile.c */
--- 193,203 ----
  };
  
  /* find library function declarations.  */
  
  /* dirname.c */
! char *find_dirname P_((char *path));
  
  /* error.c */
  void error P_((int status, int errnum, char *message, ...));
  
  /* listfile.c */
*************** void print_list P_((struct predicate *no
*** 299,309 ****
  struct predicate *get_expr P_((struct predicate **input, int prev_prec));
  boolean opt_expr P_((struct predicate **eval_treep));
  boolean mark_stat P_((struct predicate *tree));
  
  /* util.c */
! char *basename P_((char *fname));
  struct predicate *get_new_pred P_((void));
  struct predicate *get_new_pred_chk_op P_((void));
  struct predicate *insert_primary P_((boolean (*pred_func )()));
  void usage P_((char *msg));
  
--- 299,309 ----
  struct predicate *get_expr P_((struct predicate **input, int prev_prec));
  boolean opt_expr P_((struct predicate **eval_treep));
  boolean mark_stat P_((struct predicate *tree));
  
  /* util.c */
! char *find_basename P_((char *fname));
  struct predicate *get_new_pred P_((void));
  struct predicate *get_new_pred_chk_op P_((void));
  struct predicate *insert_primary P_((boolean (*pred_func )()));
  void usage P_((char *msg));
  
diff -acrpNC5 findutils-4.1.orig/find/find.1 findutils-4.1.djgpp/find/find.1
*** findutils-4.1.orig/find/find.1	Wed Nov  2 20:59:16 1994
--- findutils-4.1.djgpp/find/find.1	Sun May 28 02:42:06 2000
*************** command, not just in arguments where it 
*** 240,249 ****
--- 240,256 ----
  of
  .BR find .
  Both of these constructions might need to be escaped (with a `\e') or
  quoted to protect them from expansion by the shell.  The command is
  executed in the starting directory.
+ .IP "\-dosexec \fIcommand\fR ;"
+ Like \-exec, but all the slashes in the filename are converted to
+ DOS-style backslashes.  This should be used with DOS prograns which
+ don't understand pathnames with Unix-style forward slashes.  Note that
+ this option is currently implemented in a way that makes it effect
+ global: it also affects any \-exec or \-ok options that follow
+ \-dosexec on the command line.
  .IP "\-fls \fIfile\fR"
  True; like \-ls but write to \fIfile\fR like \-fprint.
  .IP "\-fprint \fIfile\fR"
  True; print the full file name into file \fIfile\fR.  If \fIfile\fR
  does not exist when \fBfind\fR is run, it is created; if it does
*************** True; like \-print0 but write to \fIfile
*** 256,265 ****
--- 263,279 ----
  True; like \-printf but write to \fIfile\fR like \-fprint.
  .IP "\-ok \fIcommand\fR ;"
  Like \-exec but ask the user first (on the standard input); if the
  response does not start with `y' or `Y', do not run the command, and
  return false.
+ .IP "\-dosok \fIcommand\fR ;"
+ Like \-ok, but all the slashes in the filename are converted to
+ DOS-style backslashes.  This should be used with DOS prograns which
+ don't understand pathnames with Unix-style forward slashes.  Note that
+ this option is currently implemented in a way that makes it effect
+ global: it also affects any \-ok or \-exec options that follow \-dosok
+ on the command line.
  .IP \-print
  True; print the full file name on the standard output, followed by a newline.
  .IP \-print0
  True; print the full file name on the standard output, followed by a
  null character.  This allows file names that contain newlines to be
diff -acrpNC5 findutils-4.1.orig/find/find.c findutils-4.1.djgpp/find/find.c
*** findutils-4.1.orig/find/find.c	Wed Oct 12 21:21:10 1994
--- findutils-4.1.djgpp/find/find.c	Sun May 28 02:42:06 2000
*************** main (argc, argv)
*** 157,166 ****
--- 157,172 ----
    xstat = debug_stat;
  #else /* !DEBUG_STAT */
    xstat = lstat;
  #endif /* !DEBUG_STAT */
  
+ #ifdef __DJGPP__
+   /* This makes `find' 40% faster when we aren't required
+      to know about execute permissions.  */
+   _djstat_flags |= _STAT_EXEC_MAGIC;
+ #endif
+ 
  #ifdef DEBUG
    printf ("cur_day_start = %s", ctime (&cur_day_start));
  #endif /* DEBUG */
  
    /* Find where in ARGV the predicates begin. */
*************** process_path (pathname, name, leaf, pare
*** 392,402 ****
    if (stop_at_current_level == false)
      /* Scan directory on disk. */
      process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
  
    if (do_dir_first == false && curdepth >= mindepth)
!     apply_predicate (pathname, &stat_buf, eval_tree);
  
    dir_curr--;
  
    return 1;
  }
--- 398,411 ----
    if (stop_at_current_level == false)
      /* Scan directory on disk. */
      process_dir (pathname, name, strlen (pathname), &stat_buf, parent);
  
    if (do_dir_first == false && curdepth >= mindepth)
!     {
!       rel_pathname = name;
!       apply_predicate (pathname, &stat_buf, eval_tree);
!     }
  
    dir_curr--;
  
    return 1;
  }
diff -acrpNC5 findutils-4.1.orig/find/fstype.c findutils-4.1.djgpp/find/fstype.c
*** findutils-4.1.orig/find/fstype.c	Thu Nov  3 16:33:48 1994
--- findutils-4.1.djgpp/find/fstype.c	Sun May 28 02:42:06 2000
*************** filesystem_type_uncached (path, relpath,
*** 320,330 ****
  #ifdef FSTYPE_STATFS		/* 4.4BSD.  */
    struct statfs fss;
    char *p;
  
    if (S_ISLNK (statp->st_mode))
!     p = dirname (relpath);
    else
      p = relpath;
  
    if (statfs (p, &fss) == -1)
      {
--- 320,330 ----
  #ifdef FSTYPE_STATFS		/* 4.4BSD.  */
    struct statfs fss;
    char *p;
  
    if (S_ISLNK (statp->st_mode))
!     p = find_dirname (relpath);
    else
      p = relpath;
  
    if (statfs (p, &fss) == -1)
      {
diff -acrpNC5 findutils-4.1.orig/find/parser.c findutils-4.1.djgpp/find/parser.c
*** findutils-4.1.orig/find/parser.c	Wed Nov  2 20:59:18 1994
--- findutils-4.1.djgpp/find/parser.c	Sun May 28 02:42:06 2000
*************** static boolean parse_cmin P_((char *argv
*** 77,86 ****
--- 77,90 ----
  static boolean parse_cnewer P_((char *argv[], int *arg_ptr));
  static boolean parse_comma P_((char *argv[], int *arg_ptr));
  static boolean parse_ctime P_((char *argv[], int *arg_ptr));
  static boolean parse_daystart P_((char *argv[], int *arg_ptr));
  static boolean parse_depth P_((char *argv[], int *arg_ptr));
+ #ifdef __MSDOS__
+ static boolean parse_dosexec P_((char *argv[], int *arg_ptr));
+ static boolean parse_dosok P_((char *argv[], int *arg_ptr));
+ #endif
  static boolean parse_empty P_((char *argv[], int *arg_ptr));
  static boolean parse_exec P_((char *argv[], int *arg_ptr));
  static boolean parse_false P_((char *argv[], int *arg_ptr));
  static boolean parse_fls P_((char *argv[], int *arg_ptr));
  static boolean parse_fprintf P_((char *argv[], int *arg_ptr));
*************** static struct parser_table const parse_t
*** 175,184 ****
--- 179,192 ----
    {"cpio", parse_cpio},		/* Unix */
  #endif
    {"ctime", parse_ctime},
    {"daystart", parse_daystart},	/* GNU */
    {"depth", parse_depth},
+ #ifdef __MSDOS__
+   {"dosexec", parse_dosexec},	/* MS-DOS */
+   {"dosok", parse_dosok},	/* MS-DOS */
+ #endif
    {"empty", parse_empty},	/* GNU */
    {"exec", parse_exec},
    {"false", parse_false},	/* GNU */
    {"fls", parse_fls},		/* GNU */
    {"follow", parse_follow},	/* GNU, Unix */
*************** parse_depth (argv, arg_ptr)
*** 432,442 ****
       int *arg_ptr;
  {
    do_dir_first = false;
    return (true);
  }
!  
  static boolean
  parse_empty (argv, arg_ptr)
       char *argv[];
       int *arg_ptr;
  {
--- 440,474 ----
       int *arg_ptr;
  {
    do_dir_first = false;
    return (true);
  }
! 
! #ifdef __MSDOS__
! 
! int dossify_filename = false;
! 
! static boolean
! parse_dosexec (argv, arg_ptr)
!      char *argv[];
!      int *arg_ptr;
! {
!   dossify_filename = true;
!   return parse_exec (argv, arg_ptr);
! }
! 
! static boolean
! parse_dosok (argv, arg_ptr)
!      char *argv[];
!      int *arg_ptr;
! {
!   dossify_filename = true;
!   return parse_ok (argv, arg_ptr);
! }
! 
! #endif /* __MSDOS__ */
! 
  static boolean
  parse_empty (argv, arg_ptr)
       char *argv[];
       int *arg_ptr;
  {
*************** parse_fls (argv, arg_ptr)
*** 475,484 ****
--- 507,519 ----
      return (false);
    our_pred = insert_primary (pred_fls);
    our_pred->args.stream = open_output_file (argv[*arg_ptr]);
    our_pred->side_effects = true;
    (*arg_ptr)++;
+ #ifdef __DJGPP__
+   _djstat_flags &= ~_STAT_EXEC_MAGIC;
+ #endif
    return (true);
  }
  
  static boolean 
  parse_fprintf (argv, arg_ptr)
*************** tests (N can be +N or -N or N): -amin N 
*** 620,632 ****
--- 655,674 ----
        -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE\n");
    printf ("\
        -nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\
        -size N[bckw] -true -type [bcdpfls] -uid N -used N -user NAME\n\
        -xtype [bcdpfls]\n");
+ #ifdef __MSDOS__
+   printf ("\
+ actions: -exec COMMAND ; -fprint FILE -fprint0 FILE -fprintf FILE FORMAT\n\
+       -ok COMMAND ; -print -print0 -printf FORMAT -prune -ls\n\
+       -dosexec COMMAND ; -dosok COMMAND\n");
+ #else
    printf ("\
  actions: -exec COMMAND ; -fprint FILE -fprint0 FILE -fprintf FILE FORMAT\n\
        -ok COMMAND ; -print -print0 -printf FORMAT -prune -ls\n");
+ #endif
    exit (0);
  }
  
  static boolean
  parse_ilname (argv, arg_ptr)
*************** parse_ls (argv, arg_ptr)
*** 721,730 ****
--- 763,775 ----
  {
    struct predicate *our_pred;
  
    our_pred = insert_primary (pred_ls);
    our_pred->side_effects = true;
+ #ifdef __DJGPP__
+   _djstat_flags &= ~_STAT_EXEC_MAGIC;
+ #endif
    return (true);
  }
  
  static boolean
  parse_maxdepth (argv, arg_ptr)
*************** parse_perm (argv, arg_ptr)
*** 1046,1055 ****
--- 1091,1104 ----
      default:
        /* True if exactly the given bits are set. */
        our_pred->args.perm = (perm_val & 07777);
        break;
      }
+ #ifdef __DJGPP__
+   if (perm_val & (S_IXUSR | S_IXGRP | S_IXOTH))
+     _djstat_flags &= ~_STAT_EXEC_MAGIC;
+ #endif
    (*arg_ptr)++;
    return (true);
  }
  
  boolean
*************** make_segment (segment, format, len, kind
*** 1581,1590 ****
--- 1630,1642 ----
        break;
  
      case 'm':			/* mode as octal number (perms only) */
        *fmt++ = 'o';
        fprintf_stat_needed = true;
+ #ifdef __DJGPP__
+       _djstat_flags &= ~_STAT_EXEC_MAGIC;
+ #endif
        break;
      }
    *fmt = '\0';
  
    return (&(*segment)->next);
diff -acrpNC5 findutils-4.1.orig/find/pred.c findutils-4.1.djgpp/find/pred.c
*** findutils-4.1.orig/find/pred.c	Wed Nov  2 20:59:22 1994
--- findutils-4.1.djgpp/find/pred.c	Sun May 28 02:42:06 2000
***************
*** 25,34 ****
--- 25,38 ----
  #include <grp.h>
  #include "defs.h"
  #include "modetype.h"
  #include "wait.h"
  
+ #ifdef __MSDOS__
+ #include <process.h>
+ #endif
+ 
  #if !defined(SIGCHLD) && defined(SIGCLD)
  #define SIGCHLD SIGCLD
  #endif
  
  #ifndef _POSIX_VERSION
*************** struct group *getgrgid ();
*** 51,60 ****
--- 55,70 ----
  # if HAVE_NDIR_H
  #  include <ndir.h>
  # endif
  #endif
  
+ #ifdef __DJGPP__
+ /* This ensures `find' will see all the files, including
+    those with SYSTEM and HIDDEN attributes.  */
+ int __opendir_flags = __OPENDIR_FIND_HIDDEN;
+ #endif
+ 
  #ifdef CLOSEDIR_VOID
  /* Fake a return value. */
  #define CLOSEDIR(d) (closedir (d), 0)
  #else
  #define CLOSEDIR(d) closedir (d)
*************** struct group *getgrgid ();
*** 67,77 ****
  /* Extract or fake data from a `struct stat'.
     ST_NBLOCKS: Number of 512-byte blocks in the file
     (including indirect blocks).
     HP-UX, perhaps uniquely, counts st_blocks in 1024-byte units.
     This workaround loses when mixing HP-UX and 4BSD filesystems, though.  */
! #ifdef _POSIX_SOURCE
  # define ST_NBLOCKS(statp) (((statp)->st_size + 512 - 1) / 512)
  #else
  # ifndef HAVE_ST_BLOCKS
  #  define ST_NBLOCKS(statp) (st_blocks ((statp)->st_size))
  # else
--- 77,87 ----
  /* Extract or fake data from a `struct stat'.
     ST_NBLOCKS: Number of 512-byte blocks in the file
     (including indirect blocks).
     HP-UX, perhaps uniquely, counts st_blocks in 1024-byte units.
     This workaround loses when mixing HP-UX and 4BSD filesystems, though.  */
! #if defined(_POSIX_SOURCE) || defined(__DJGPP__)
  # define ST_NBLOCKS(statp) (((statp)->st_size + 512 - 1) / 512)
  #else
  # ifndef HAVE_ST_BLOCKS
  #  define ST_NBLOCKS(statp) (st_blocks ((statp)->st_size))
  # else
*************** pred_empty (pathname, stat_buf, pred_ptr
*** 420,429 ****
--- 430,443 ----
      return (stat_buf->st_size == 0);
    else
      return (false);
  }
  
+ #ifdef __MSDOS__
+ extern int dossify_filename;
+ #endif
+ 
  boolean
  pred_exec (pathname, stat_buf, pred_ptr)
       char *pathname;
       struct stat *stat_buf;
       struct predicate *pred_ptr;
*************** pred_exec (pathname, stat_buf, pred_ptr)
*** 446,455 ****
--- 460,482 ----
        for (from = execp->paths[path_pos].origarg, to = execp->vec[i]; *from; )
  	if (from[0] == '{' && from[1] == '}')
  	  {
  	    to = stpcpy (to, pathname);
  	    from += 2;
+ #ifdef __MSDOS__
+ 	    if (dossify_filename)
+ 	      {
+ 		char *p = to - strlen (pathname);
+ 
+ 		while (*p)
+ 		  {
+ 		    if (*p == '/')
+ 		      *p = '\\';
+ 		    p++;
+ 		  }
+ 	      }
+ #endif
  	  }
  	else
  	  *to++ = *from++;
        *to = *from;		/* Copy null. */
      }
*************** pred_iname (pathname, stat_buf, pred_ptr
*** 760,770 ****
       struct stat *stat_buf;
       struct predicate *pred_ptr;
  {
    char *base;
  
!   base = basename (pathname);
    if (fnmatch (pred_ptr->args.str, base, FNM_PERIOD | FNM_CASEFOLD) == 0)
      return (true);
    return (false);
  }
  
--- 787,797 ----
       struct stat *stat_buf;
       struct predicate *pred_ptr;
  {
    char *base;
  
!   base = find_basename (pathname);
    if (fnmatch (pred_ptr->args.str, base, FNM_PERIOD | FNM_CASEFOLD) == 0)
      return (true);
    return (false);
  }
  
*************** pred_name (pathname, stat_buf, pred_ptr)
*** 927,937 ****
       struct stat *stat_buf;
       struct predicate *pred_ptr;
  {
    char *base;
  
!   base = basename (pathname);
    if (fnmatch (pred_ptr->args.str, base, FNM_PERIOD) == 0)
      return (true);
    return (false);
  }
  
--- 954,964 ----
       struct stat *stat_buf;
       struct predicate *pred_ptr;
  {
    char *base;
  
!   base = find_basename (pathname);
    if (fnmatch (pred_ptr->args.str, base, FNM_PERIOD) == 0)
      return (true);
    return (false);
  }
  
*************** pred_xtype (pathname, stat_buf, pred_ptr
*** 1295,1304 ****
--- 1322,1372 ----
        return (false);
      }
    return (pred_type (pathname, &sbuf, pred_ptr));
  }
  
+ #ifdef __MSDOS__
+ 
+ volatile sig_atomic_t proc_status;
+ volatile sig_atomic_t child_running;
+ 
+ /* Don't die if the child got the signal.  */
+ static void dos_signal_catcher (int sig)
+ {
+   if (child_running)
+     {
+       signal (sig, dos_signal_catcher);
+       proc_status |= (sig << 8);
+       if (sig == SIGINT)
+         exit (1);
+       else
+         return;
+     }
+   else
+     {
+       signal (sig, SIG_DFL);
+       kill (getpid (), sig);
+     }
+ }
+ 
+ /* Replacement for the `wait' library function that doesn't
+    merely fail.  */
+ pid_t wait (int *status)
+ {
+   if (child_running)
+     return (pid_t)(-1);
+   *status = proc_status;
+   return (pid_t)42;
+ }
+ 
+ /* The macros we need with `wait'.  */
+ 
+ #undef  WTERMSIG
+ #define WTERMSIG(s)	((s) >> 8)
+ 
+ #endif /* __MSDOS__ */
+ 
  /*  1) fork to get a child; parent remembers the child pid
      2) child execs the command requested
      3) parent waits for child; checks for proper pid of child
  
      Possible returns:
*************** launch (pred_ptr)
*** 1332,1344 ****
--- 1400,1451 ----
  
    /* Make sure to listen for the kids.  */
    if (first_time)
      {
        first_time = 0;
+ #ifdef __MSDOS__
+       signal (SIGINT, dos_signal_catcher);
+ #else
        signal (SIGCHLD, SIG_DFL);
+ #endif
      }
  
+ #ifdef __MSDOS__
+ 
+   /* On MS-DOS, CWD is global, so we must remember where we were
+      before spawning a child, and return there after the child exits.  */
+   {
+     char *cwd =  xgetcwd ();
+     int spawn_result;
+ 
+     if (chdir (starting_dir) < 0)
+       {
+ 	error (0, errno, "%s", starting_dir);
+ 	_exit (1);
+       }
+ 
+     proc_status = 0;
+     child_running = 1;
+     spawn_result = spawnvp(P_WAIT, execp->vec[0], execp->vec);
+     child_running = 0;
+ 
+     if (spawn_result == -1)
+       error (0, errno, "%s", execp->vec[0]);
+     else
+       proc_status |= (spawn_result & 0xff);
+ 
+     if (chdir (cwd) < 0)
+       {
+ 	error (0, errno, "%s", cwd);
+ 	_exit (1);
+       }
+ 
+     child_pid = (pid_t)42;
+   }
+ 
+ #else /* not __MSDOS__ */
+ 
    child_pid = fork ();
    if (child_pid == -1)
      error (1, errno, "cannot fork");
    if (child_pid == 0)
      {
*************** launch (pred_ptr)
*** 1358,1367 ****
--- 1465,1475 ----
  #endif
        execvp (execp->vec[0], execp->vec);
        error (0, errno, "%s", execp->vec[0]);
        _exit (1);
      }
+ #endif /* not __MSDOS__ */
  
    wait_ret = wait (&status);
    if (wait_ret == -1)
      {
        error (0, errno, "error waiting for %s", execp->vec[0]);
diff -acrpNC5 findutils-4.1.orig/find/util.c findutils-4.1.djgpp/find/util.c
*** findutils-4.1.orig/find/util.c	Thu Oct 20 04:49:46 1994
--- findutils-4.1.djgpp/find/util.c	Sun May 28 02:42:06 2000
***************
*** 23,37 ****
  
  /* Return the last component of pathname FNAME, with leading slashes
     compressed into one slash. */
  
  char *
! basename (fname)
       char *fname;
  {
    char *p;
  
    /* For "/", "//", etc., return "/". */
    for (p = fname; *p == '/'; ++p)
      /* Do nothing. */ ;
    if (*p == '\0')
      return p - 1;
--- 23,42 ----
  
  /* Return the last component of pathname FNAME, with leading slashes
     compressed into one slash. */
  
  char *
! find_basename (fname)
       char *fname;
  {
    char *p;
  
+ #ifdef __MSDOS__
+   if (fname[1] == ':')
+     fname += 2;
+ #endif
+ 
    /* For "/", "//", etc., return "/". */
    for (p = fname; *p == '/'; ++p)
      /* Do nothing. */ ;
    if (*p == '\0')
      return p - 1;
diff -acrpNC5 findutils-4.1.orig/lib/dirname.c findutils-4.1.djgpp/lib/dirname.c
*** findutils-4.1.orig/lib/dirname.c	Tue Oct 18 04:24:08 1994
--- findutils-4.1.djgpp/lib/dirname.c	Sun May 28 02:42:06 2000
*************** char *malloc ();
*** 37,47 ****
     allocated with malloc.  If out of memory, return 0.
     Assumes that trailing slashes have already been
     removed.  */
  
  char *
! dirname (path)
       char *path;
  {
    char *newpath;
    char *slash;
    int length;			/* Length of result, not including NUL.  */
--- 37,47 ----
     allocated with malloc.  If out of memory, return 0.
     Assumes that trailing slashes have already been
     removed.  */
  
  char *
! find_dirname (path)
       char *path;
  {
    char *newpath;
    char *slash;
    int length;			/* Length of result, not including NUL.  */
diff -acrpNC5 findutils-4.1.orig/lib/listfile.c findutils-4.1.djgpp/lib/listfile.c
*** findutils-4.1.orig/lib/listfile.c	Wed Nov  2 20:59:24 1994
--- findutils-4.1.djgpp/lib/listfile.c	Sun May 28 02:42:06 2000
*************** int readlink ();
*** 73,83 ****
  /* Extract or fake data from a `struct stat'.
     ST_NBLOCKS: Number of 512-byte blocks in the file
     (including indirect blocks).
     HP-UX, perhaps uniquely, counts st_blocks in 1024-byte units.
     This workaround loses when mixing HP-UX and 4BSD filesystems, though.  */
! #ifdef _POSIX_SOURCE
  # define ST_NBLOCKS(statp) (((statp)->st_size + 512 - 1) / 512)
  #else
  # ifndef HAVE_ST_BLOCKS
  #  define ST_NBLOCKS(statp) (st_blocks ((statp)->st_size))
  # else
--- 73,83 ----
  /* Extract or fake data from a `struct stat'.
     ST_NBLOCKS: Number of 512-byte blocks in the file
     (including indirect blocks).
     HP-UX, perhaps uniquely, counts st_blocks in 1024-byte units.
     This workaround loses when mixing HP-UX and 4BSD filesystems, though.  */
! #if defined(_POSIX_SOURCE) || defined(__DJGPP__)
  # define ST_NBLOCKS(statp) (((statp)->st_size + 512 - 1) / 512)
  #else
  # ifndef HAVE_ST_BLOCKS
  #  define ST_NBLOCKS(statp) (st_blocks ((statp)->st_size))
  # else
diff -acrpNC5 findutils-4.1.orig/lib/nextelem.c findutils-4.1.djgpp/lib/nextelem.c
*** findutils-4.1.orig/lib/nextelem.c	Tue Sep 27 13:02:44 1994
--- findutils-4.1.djgpp/lib/nextelem.c	Sun May 28 02:42:06 2000
*************** next_element (new_path)
*** 71,81 ****
--- 71,85 ----
      }
  
    start = end;
    final_colon = 1;		/* Maybe there will be one.  */
  
+ #ifdef __MSDOS__
+   end = strchr (start, ';');
+ #else
    end = strchr (start, ':');
+ #endif
    if (end == start)
      {
        /* An empty path element.  */
        *end++ = '\0';
        return ".";
diff -acrpNC5 findutils-4.1.orig/locate/bigram.c findutils-4.1.djgpp/locate/bigram.c
*** findutils-4.1.orig/locate/bigram.c	Fri Oct  7 17:21:34 1994
--- findutils-4.1.djgpp/locate/bigram.c	Sun May 28 02:42:06 2000
***************
*** 41,50 ****
--- 41,61 ----
  #ifdef STDC_HEADERS
  #include <stdlib.h>
  #endif
  #include <sys/types.h>
  
+ #ifdef __DJGPP__
+ 
+ /* Make our disk image as small as possible.  */
+ 
+ #include <crt0.h>
+ 
+ void __crt0_load_environment_file(char *_app_name) {}
+ char **__crt0_glob_function(char *_argument) { return 0; }
+ 
+ #endif
+ 
  char *xmalloc ();
  
  /* The name this program was run with.  */
  char *program_name;
  
diff -acrpNC5 findutils-4.1.orig/locate/code.c findutils-4.1.djgpp/locate/code.c
*** findutils-4.1.orig/locate/code.c	Mon Sep 26 22:06:08 1994
--- findutils-4.1.djgpp/locate/code.c	Sun May 28 02:42:06 2000
***************
*** 55,64 ****
--- 55,79 ----
  
  #ifdef STDC_HEADERS
  #include <stdlib.h>
  #endif
  
+ #ifdef __DJGPP__
+ #include <fcntl.h>
+ #include <io.h>
+ 
+ int _fmode = O_BINARY;
+ 
+ /* Make our disk image as small as possible.  */
+ 
+ #include <crt0.h>
+ 
+ void __crt0_load_environment_file(char *_app_name) {}
+ char **__crt0_glob_function(char *_argument) { return 0; }
+ 
+ #endif
+ 
  #include "locatedb.h"
  
  char *xmalloc ();
  
  /* The name this program was run with.  */
*************** main (argc, argv)
*** 133,142 ****
--- 148,162 ----
        fprintf (stderr, "%s: ", argv[0]);
        perror (argv[1]);
        exit (1);
      }
  
+ #ifdef __DJGPP__
+   if (!isatty (fileno (stdout)))
+     setmode (fileno (stdout), O_BINARY);
+ #endif
+ 
    pathsize = oldpathsize = 1026; /* Increased as necessary by getstr.  */
    path = xmalloc (pathsize);
    oldpath = xmalloc (oldpathsize);
  
    /* Set to anything not starting with a slash, to force the first
diff -acrpNC5 findutils-4.1.orig/locate/frcode.c findutils-4.1.djgpp/locate/frcode.c
*** findutils-4.1.orig/locate/frcode.c	Mon Sep 26 22:06:10 1994
--- findutils-4.1.djgpp/locate/frcode.c	Sun May 28 02:42:06 2000
***************
*** 73,82 ****
--- 73,96 ----
  
  #ifdef STDC_HEADERS
  #include <stdlib.h>
  #endif
  
+ #ifdef __DJGPP__
+ 
+ #include <fcntl.h>
+ #include <io.h>
+ 
+ /* Make our disk image as small as possible.  */
+ 
+ #include <crt0.h>
+ 
+ void __crt0_load_environment_file(char *_app_name) {}
+ char **__crt0_glob_function(char *_argument) { return 0; }
+ 
+ #endif
+ 
  #include "locatedb.h"
  
  char *xmalloc ();
  
  /* The name this program was run with.  */
*************** main (argc, argv)
*** 126,135 ****
--- 140,154 ----
    /* Set to anything not starting with a slash, to force the first
       prefix count to 0.  */
    strcpy (oldpath, " ");
    oldcount = 0;
  
+ #ifdef __MSDOS__
+   if (!isatty (fileno (stdout)))
+     setmode (fileno (stdout), O_BINARY);
+ #endif
+ 
    fwrite (LOCATEDB_MAGIC, sizeof (LOCATEDB_MAGIC), 1, stdout);
  
    /* FIXME temporary: change the \n to \0 when we figure out how to sort
       null-terminated strings.  */
    while ((line_len = getstr (&path, &pathsize, stdin, '\n', 0)) > 0)
diff -acrpNC5 findutils-4.1.orig/locate/locate.c findutils-4.1.djgpp/locate/locate.c
*** findutils-4.1.orig/locate/locate.c	Mon Sep 26 22:06:14 1994
--- findutils-4.1.djgpp/locate/locate.c	Sun May 28 02:42:06 2000
*************** char *getenv ();
*** 76,85 ****
--- 76,90 ----
  #include <stdlib.h>
  #else
  extern int errno;
  #endif
  
+ #ifdef __DJGPP__
+ #include <fcntl.h>
+ int _fmode = O_BINARY;
+ #endif
+ 
  #include "locatedb.h"
  
  typedef enum {false, true} boolean;
  
  /* Warn if a database is older than this.  8 days allows for a weekly
diff -acrpNC5 findutils-4.1.orig/locate/updatedb.bat findutils-4.1.djgpp/locate/updatedb.bat
*** findutils-4.1.orig/locate/updatedb.bat	Thu Jan  1 00:00:00 1970
--- findutils-4.1.djgpp/locate/updatedb.bat	Sun May 28 02:42:06 2000
***************
*** 0 ****
--- 1,94 ----
+ @echo off
+ rem -----------------------------------------------------------------
+ rem
+ rem             UpdateDB.Bat
+ rem
+ rem Beside GNU Findutils, you will need ports of these utilities:
+ rem
+ rem    sort
+ rem    tr
+ rem    uniq
+ rem    gawk
+ rem
+ rem Only `sort' is required for the new-style data-base format; the
+ rem rest are used when creating old-style data-bases.
+ rem
+ rem ------------------------------------------------------------------
+ rem
+ rem This is a pale imitation of the original `updatedb.sh' (which see).
+ rem
+ rem          Written by Eli Zaretskii "<eliz@is.elta.co.il>"
+ rem
+ rem ------------------------------------------------------------------
+ rem
+ set old_format=
+ set locate_args=
+ :again
+ If "%1" == "?" Goto help
+ If "%1" == "/?" Goto help
+ If "%1" == "-h" Goto help
+ If "%1" == "--help" Goto help
+ If "%1" == "--version" Goto version
+ If "%1" == "--old-format" Goto old
+ Goto doit
+ :help
+ echo.
+ echo Usage: updatedb [--old-format] [dir1 dir2...]
+ echo   or   updatedb [--version] [--help]
+ echo.
+ echo  Warning: Keep the list of directories short, lest it makes
+ echo           some command-lines longer than 126 characters!
+ echo.
+ Goto end
+ :version
+ echo GNU updatedb version 4.1 (for MS-DOS)
+ Goto end
+ :old
+ set old_format=OLD
+ shift
+ Goto again
+ :doit
+ set locate_args=%1 %2 %3 %4 %5 %6 %7 %8 %9
+ If "%1" == "" Set locate_args=/
+ If "%old_format%" == "" Goto New
+ rem
+ rem  ---- Old format ---
+ rem
+ set tmp_prefix=
+ If "%TMPDIR%" == "" Goto try_temp
+ set tmp_prefix=%TMPDIR%
+ Goto action
+ :try_temp
+ If "%TEMP%" == "" Goto try_tmp
+ set tmp_prefix=%TEMP%
+ Goto action
+ :try_tmp
+ If "%TMP%" == "" Goto action
+ set tmp_prefix=%TMP%
+ :action
+ If "%tmp_prefix%" == "" set tmp_prefix=.
+ set bigrams_file=%tmp_prefix%\bigrams.tmp
+ set filelist=%tmp_prefix%\filelist
+ find %locate_args% ( -type d -iregex '^[a-zA-Z]:/te?mp$' ) -prune -o -print > %filelist%.1
+ tr / "\001" < %filelist%.1 | sort -f | tr "\001" / > %filelist%.2
+ bigram < %filelist%.2 | sort | uniq -c | sort -nr > %filelist%.3
+ gawk "{ if (NR <= 128) print $2 }" < %filelist%.3 | tr -d "\012" > %bigrams_file%
+ code %bigrams_file% < %filelist%.2 > locatedb.dat
+ If exist %bigrams_file% Del %bigrams_file%
+ If exist %filelist%.* Del %filelist%.*
+ set bigrams_file=
+ set filelist=
+ set tmp_prefix=
+ Goto end
+ :New
+ rem
+ rem  ---- New format ---
+ rem
+ find %locate_args% ( -type d -iregex '^[a-zA-Z]:/te?mp$' ) -prune -o -print | sort -f | frcode > locatedb.n
+ find locatedb.n -empty
+ If errorlevel 1 goto end
+ If exist locatedb.dat Del locatedb.dat
+ Ren locatedb.n locatedb.dat
+ :end
+ set old_format=
+ set locate_args=
diff -acrpNC5 findutils-4.1.orig/locate/updatedb.sh findutils-4.1.djgpp/locate/updatedb.sh
*** findutils-4.1.orig/locate/updatedb.sh	Wed Oct  5 02:24:18 1994
--- findutils-4.1.djgpp/locate/updatedb.sh	Sun May 28 02:56:22 2000
*************** $usage" >&2
*** 44,53 ****
--- 44,55 ----
  done
  
  # You can set these in the environment, or use command-line options,
  # to override their defaults:
  
+ PATH_SEPARATOR=:
+ 
  # Non-network directories to put in the database.
  : ${SEARCHPATHS="/"}
  
  # Network (NFS, AFS, RFS, etc.) directories to put in the database.
  : ${NETPATHS=}
*************** test -z "$PRUNEREGEX" &&
*** 64,74 ****
  
  # Directory to hold intermediate files.
  if test -d /var/tmp; then
    : ${TMPDIR=/var/tmp}
  else
!   : ${TMPDIR=/usr/tmp}
  fi
  
  # The user to search network directories as.
  : ${NETUSER=daemon}
  
--- 66,76 ----
  
  # Directory to hold intermediate files.
  if test -d /var/tmp; then
    : ${TMPDIR=/var/tmp}
  else
!   : ${TMPDIR=.}
  fi
  
  # The user to search network directories as.
  : ${NETUSER=daemon}
  
*************** fi
*** 100,120 ****
  
  if test -n "$NETPATHS"; then
    su $NETUSER -c \
    "$find $NETPATHS \\( -type d -regex \"$PRUNEREGEX\" -prune \\) -o -print"
  fi
! } | sort -f | $frcode > $LOCATE_DB.n
  
  # To avoid breaking locate while this script is running, put the
  # results in a temp file, then rename it atomically.
! if test -s $LOCATE_DB.n; then
    rm -f $LOCATE_DB
!   mv $LOCATE_DB.n $LOCATE_DB
    chmod 644 $LOCATE_DB
  else
    echo "updatedb: new database would be empty" >&2
!   rm -f $LOCATE_DB.n
  fi
  
  else # old
  
  bigrams=$TMPDIR/f.bigrams$$
--- 102,122 ----
  
  if test -n "$NETPATHS"; then
    su $NETUSER -c \
    "$find $NETPATHS \\( -type d -regex \"$PRUNEREGEX\" -prune \\) -o -print"
  fi
! } | sort -f | $frcode > n$LOCATE_DB
  
  # To avoid breaking locate while this script is running, put the
  # results in a temp file, then rename it atomically.
! if test -s n$LOCATE_DB; then
    rm -f $LOCATE_DB
!   mv n$LOCATE_DB $LOCATE_DB
    chmod 644 $LOCATE_DB
  else
    echo "updatedb: new database would be empty" >&2
!   rm -f n$LOCATE_DB
  fi
  
  else # old
  
  bigrams=$TMPDIR/f.bigrams$$
diff -acrpNC5 findutils-4.1.orig/xargs/xargs.1 findutils-4.1.djgpp/xargs/xargs.1
*** findutils-4.1.orig/xargs/xargs.1	Wed Nov  2 20:11:38 1994
--- findutils-4.1.djgpp/xargs/xargs.1	Sun May 28 02:42:06 2000
***************
*** 1,11 ****
  .TH XARGS 1L \" -*- nroff -*-
  .SH NAME
  xargs \- build and execute command lines from standard input
  .SH SYNOPSIS
  .B xargs
! [\-0prtx] [\-e[eof-str]] [\-i[replace-str]] [\-l[max-lines]]
  [\-n max-args] [\-s max-chars] [\-P max-procs] [\-\-null] [\-\-eof[=eof-str]]
  [\-\-replace[=replace-str]] [\-\-max-lines[=max-lines]] [\-\-interactive]
  [\-\-max-chars=max-chars] [\-\-verbose] [\-\-exit] [\-\-max-procs=max-procs]
  [\-\-max-args=max-args] [\-\-no-run-if-empty] [\-\-version] [\-\-help]
  [command [initial-arguments]]
--- 1,11 ----
  .TH XARGS 1L \" -*- nroff -*-
  .SH NAME
  xargs \- build and execute command lines from standard input
  .SH SYNOPSIS
  .B xargs
! [\-0prtxD] [\-e[eof-str]] [\-i[replace-str]] [\-\-dos-format] [\-l[max-lines]]
  [\-n max-args] [\-s max-chars] [\-P max-procs] [\-\-null] [\-\-eof[=eof-str]]
  [\-\-replace[=replace-str]] [\-\-max-lines[=max-lines]] [\-\-interactive]
  [\-\-max-chars=max-chars] [\-\-verbose] [\-\-exit] [\-\-max-procs=max-procs]
  [\-\-max-args=max-args] [\-\-no-run-if-empty] [\-\-version] [\-\-help]
  [command [initial-arguments]]
*************** names read from standard input.
*** 61,70 ****
--- 61,82 ----
  Also, unquoted blanks do not terminate arguments.
  If \fIreplace-str\fR is omitted, it
  defaults to "{}" (like for `find \-exec').  Implies \fI\-x\fP and
  \fI\-l 1\fP.
  .TP
+ .I "\-\-dos-format, \-D"
+ Convert all filenames to DOS format.  This option causes
+ .B xargs
+ to convert all Unix-style forward slashes to DOS-style backslashes.
+ It should be used on MS-DOS systems when the command invoked by
+ .B xargs
+ doesn't understand forward slashes in filenames.  Note that all the
+ slashes are unconditionally converted, whether the arguments are or
+ aren't filenames, and whether they are in- or outside quotes or
+ protected by a backslash.  Implies \fI\-s 126\fP (actually, 126 plus
+ the length of the first initial argument).
+ .TP
  .I "\-\-max-lines[=max-lines], -l[max-lines]"
  Use at most \fImax-lines\fR nonblank input lines per command line;
  \fImax-lines\fR defaults to 1 if omitted.  Trailing blanks cause an
  input line to be logically continued on the next input line.  Implies
  \fI\-x\fR.
diff -acrpNC5 findutils-4.1.orig/xargs/xargs.c findutils-4.1.djgpp/xargs/xargs.c
*** findutils-4.1.orig/xargs/xargs.c	Fri Oct  7 17:21:38 1994
--- findutils-4.1.djgpp/xargs/xargs.c	Sun May 28 02:42:06 2000
*************** static boolean print_command = false;
*** 216,225 ****
--- 216,234 ----
  
  /* If true, query the user before executing each command, and only
     execute the command if the user responds affirmatively.  */
  static boolean query_before_executing = false;
  
+ #ifdef __MSDOS__
+ /* If true, the command arguments are DOS-ified: all forward slashes
+    in the arguments appended after the initial arguments, or inside
+    the replace-string, are converted to DOS-style backslashes.  This
+    is meant to be used for invoking DOS programs which don't
+    understand Unix-style slashes.  */
+ static boolean dossify_args = false;
+ #endif
+ 
  static struct option const longopts[] =
  {
    {"null", no_argument, NULL, '0'},
    {"eof", optional_argument, NULL, 'e'},
    {"replace", optional_argument, NULL, 'i'},
*************** static struct option const longopts[] =
*** 229,238 ****
--- 238,250 ----
    {"no-run-if-empty", no_argument, NULL, 'r'},
    {"max-chars", required_argument, NULL, 's'},
    {"verbose", no_argument, NULL, 't'},
    {"exit", no_argument, NULL, 'x'},
    {"max-procs", required_argument, NULL, 'P'},
+ #ifdef __MSDOS__
+   {"dos-format", no_argument, NULL, 'D'},
+ #endif
    {"version", no_argument, NULL, 'v'},
    {"help", no_argument, NULL, 'h'},
    {NULL, no_argument, NULL, 0}
  };
  
*************** static void add_proc P_ ((pid_t pid));
*** 246,264 ****
--- 258,322 ----
  static void wait_for_proc P_ ((boolean all));
  static long parse_num P_ ((char *str, int option, long min, long max));
  static long env_size P_ ((char **envp));
  static void usage P_ ((FILE * stream, int status));
  
+ #ifdef __MSDOS__
+ 
+ #include <process.h>
+ 
+ char *xgetcwd P_ ((void));
+ 
+ volatile sig_atomic_t proc_status;
+ volatile sig_atomic_t child_running;
+ 
+ /* Don't die if the child got the signal.  */
+ static void dos_signal_catcher (int sig)
+ {
+   if (child_running)
+     {
+       signal (sig, dos_signal_catcher);
+       proc_status |= (sig << 8);
+       return;
+     }
+   else
+     {
+       signal (sig, SIG_DFL);
+       kill (getpid (), sig);
+     }
+ }
+ 
+ /* Replacement for the `wait' library function that doesn't
+    merely fail.  */
+ pid_t wait (int *status)
+ {
+   if (child_running)
+     return (pid_t)(-1);
+   *status = proc_status;
+   return (pid_t)42;
+ }
+ 
+ /* The macros we need with `wait'.  */
+ 
+ #undef  WTERMSIG
+ #define WTERMSIG(s)	((s) >> 8)
+ 
+ #endif /* __MSDOS__ */
+ 
  void
  main (argc, argv)
       int argc;
       char **argv;
  {
    int optc;
    int always_run_command = 1;
    long orig_arg_max;
+ #ifdef __MSDOS__
+   char *default_cmd = "echo";
+ #else
    char *default_cmd = "/bin/echo";
+ #endif
    int (*read_args) P_ ((void)) = read_line;
  
    program_name = argv[0];
  
    orig_arg_max = ARG_MAX - 2048; /* POSIX.2 requires subtracting 2048.  */
*************** main (argc, argv)
*** 274,284 ****
    /* Take the size of the environment into account.  */
    arg_max -= env_size (environ);
    if (arg_max <= 0)
      error (1, 0, "environment is too large for exec");
  
!   while ((optc = getopt_long (argc, argv, "+0e::i::l::n:prs:txP:",
  			      longopts, (int *) 0)) != -1)
      {
        switch (optc)
  	{
  	case '0':
--- 332,347 ----
    /* Take the size of the environment into account.  */
    arg_max -= env_size (environ);
    if (arg_max <= 0)
      error (1, 0, "environment is too large for exec");
  
!   while ((optc = getopt_long (argc, argv,
! #ifdef __MSDOS__
! 			      "+0e::i::l::n:prs:txP:D",
! #else
! 			      "+0e::i::l::n:prs:txP:",
! #endif
  			      longopts, (int *) 0)) != -1)
      {
        switch (optc)
  	{
  	case '0':
*************** main (argc, argv)
*** 345,354 ****
--- 408,423 ----
  
  	case 'P':
  	  proc_max = parse_num (optarg, 'P', 0L, -1L);
  	  break;
  
+ #ifdef __MSDOS__
+ 	case 'D':
+ 	  dossify_args = true;
+ 	  break;
+ #endif
+ 
  	case 'v':
  	  printf ("GNU xargs version %s\n", version_string);
  	  exit (0);
  
  	default:
*************** main (argc, argv)
*** 367,378 ****
--- 436,475 ----
      }
  
    linebuf = (char *) xmalloc (arg_max + 1);
    argbuf = (char *) xmalloc (arg_max + 1);
  
+ #ifdef __MSDOS__
+   if (proc_max > 1)
+     {
+       error (0, 0, "multiple processes not supported on MS-DOS");
+       proc_max = 1;
+     }
+ 
+   /* DOS programs cannot take command-line tails longer
+      than 126 characters, so the command line is limited to
+      126 + one blank + the length of the program name.  */
+   if (dossify_args)
+     {
+       size_t maxlen = 127 + strlen (argv[optind]);
+ 
+       if (arg_max > maxlen)
+ 	arg_max = maxlen;
+     }
+ 
+   signal (SIGSEGV, dos_signal_catcher);
+   signal (SIGFPE,  dos_signal_catcher);
+   signal (SIGTRAP, dos_signal_catcher);
+   signal (SIGNOFP, dos_signal_catcher);
+   signal (SIGINT,  dos_signal_catcher);
+   signal (SIGILL,  dos_signal_catcher);
+   signal (SIGABRT, dos_signal_catcher);
+   signal (SIGTERM, dos_signal_catcher);
+ #else
    /* Make sure to listen for the kids.  */
    signal (SIGCHLD, SIG_DFL);
+ #endif
  
    if (!replace_pat)
      {
        for (; optind < argc; optind++)
  	push_arg (argv[optind], strlen (argv[optind]) + 1);
*************** read_line ()
*** 535,544 ****
--- 632,645 ----
  	  state = NORM;
  	  break;
  	}
        if (p >= endbuf)
  	error (1, 0, "argument line too long");
+ #ifdef __MSDOS__
+       if (dossify_args && c == '/')
+ 	c = '\\';
+ #endif
        *p++ = c;
      }
  }
  
  /* Read a null-terminated string from stdin and add it to the list of
*************** read_string ()
*** 580,589 ****
--- 681,694 ----
  	    push_arg (linebuf, len);
  	  return len;
  	}
        if (p >= endbuf)
  	error (1, 0, "argument line too long");
+ #ifdef __MSDOS__
+       if (dossify_args && c == '/')
+ 	c = '\\';
+ #endif
        *p++ = c;
      }
  }
  
  /* Replace all instances of `replace_pat' in ARG with `linebuf',
*************** do_exec ()
*** 748,757 ****
--- 853,890 ----
      {
        if (proc_max && procs_executing >= proc_max)
  	wait_for_proc (false);
        if (!query_before_executing && print_command)
  	print_args (false);
+ 
+ #ifdef __MSDOS__
+ 
+       {
+ 	/* We should return to the same directory we started from
+ 	   to avoid side-effects of apps that change directories.  */
+ 	char *cwd = xgetcwd ();
+ 	int e, spawn_retval;
+ 
+ 	errno = 0;
+ 	proc_status = 0;
+ 	child_running = 1;
+ 	spawn_retval = spawnvp (P_WAIT, cmd_argv[0], cmd_argv);
+ 	child_running = 0;
+ 	e = errno;
+ 	chdir (cwd);
+ 	if (spawn_retval == -1)
+ 	  {
+ 	    error (0, e, "%s", cmd_argv[0]);
+ 	    proc_status |= (e == ENOENT ? 127 : 126);
+ 	  }
+ 	else
+ 	  proc_status |= (spawn_retval & 0xff);
+ 	child = (pid_t)42;
+       }
+ 
+ #else /* not __MSDOS__ */
+ 
        /* If we run out of processes, wait for a child to return and
           try again.  */
        while ((child = fork ()) < 0 && errno == EAGAIN && procs_executing)
  	wait_for_proc (false);
        switch (child)
*************** do_exec ()
*** 762,771 ****
--- 895,907 ----
  	case 0:		/* Child.  */
  	  execvp (cmd_argv[0], cmd_argv);
  	  error (0, errno, "%s", cmd_argv[0]);
  	  _exit (errno == ENOENT ? 127 : 126);
  	}
+ 
+ #endif /* not __MSDOS__ */
+ 
        add_proc (child);
      }
  
    cmd_argc = initial_argc;
    cmd_argv_chars = initial_argv_chars;
