From: mfg@castle.ed.ac.uk (M Gordon)
Newsgroups: comp.bugs.4bsd
Subject: Re: A serious bug in unix2dos/dos2unix
Date: 16 Dec 92 09:26:46 GMT
Organization: Edinburgh University

jbayer@ispi.COM (Jonathan Bayer) writes:

>haiying@cs.mcgill.ca (Haiying ZHANG) writes:


>>   I came across this bug a while ago. This has to do with using wild
>>card in file names with unix2dos/dos2unix.

>>   If you use a wild card in the file name, be it a single * or a ?
>>embedded in a pattern, these two handy utilities will wipe out your
>>entire current directory with the exception of the first file. It will
>>set all the rest of the file to size 0. 

>>   Although the man page does mention anything about wild card in
>>filename making one believe that it is not supported, it should not in
>>any case cause serious damaging to your files. While I am at it, these
>>two programs look like a recompile of its DOS version. It should have
>>provided more - options such as -Rfp etc. as in cp. 


>First, what system are you running on?  Second, what are you trying to do?
>On a Sun system the dos2unix command is designed to operate on ONE file only,
>sending the output to the second file specification.  The wild cards are
>expanded by the shell, and all the program sees is a long list of filenames.


Running dos2unix with wildcards is incorrect, but it still shouldn't
destroy all of the other files.  Having seen the source for dos2unix,
what it does (at least on the Sun version) is

    for each argument
      if it's an option
	process it
      else
	if it's the first time we've seen a filename
	  open it for reading
	else
	  open it for writing


This is definitely a bug - it will process the first file on the
command line, with output going into the last file, and truncate the
others to zero length.  I ended up writing a script to process
multiple files, which is appended below in a shar archive with a
manual page.  The script should be installed as dos2unixdir, with
a link to it called unix2dosdir.


--------------------------------------------------------------------------------
#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	dos2unixdir.1
#	dos2unixdir
# This archive created: Wed Dec 16 09:20:28 1992
cat << \SHAR_EOF > dos2unixdir.1
.TH  "DOS2UNIXDIR" "1L" "14th November 1991" "uk.ac.ed.ee"  "LOCAL commands"
.SH NAME
dos2unixdir
.sp 1
unix2dosdir \- run conversion programs on directory trees.
.SH SYNOPSIS
\fBdos2unixdir\fP \fI[-v] input-dir [output-dir]\fP
.br
\fBunix2dosdir\fP \fI[-v] input-dir [output-dir]\fP
.SH DESCRIPTION
\fBDos2unixdir\fP copies the directory tree rooted at \fIinput-dir\fP
to \fIoutput-dir\fP,
running the command \fIdos2unix -ascii -7\fP on each one.
If \fIoutput-dir\fP is not given the files will be converted in place.
The \fI-v\fP option makes \fBdos2unixdir\fP print the name of each file
as it converts it.
.PP
\fBUnix2dosdir\fP is identical to \fBdos2unixdir\fP,
except that it runs \fIunix2dos -ascii -7\fP on the files.
.SH NOTES
If \fIoutput-dir\fP is not empty the converter will only be run on files 
that have been copied from \fIinput-dir\fP.
To convert all of the files in a directory run \fBdos2unixdir\fP with one
directory argument.
.SH AUTHOR
support@uk.ac.ed.ee : MFG
SHAR_EOF
cat << \SHAR_EOF > dos2unixdir
#!/bin/sh

# A function to make a directory hierarchy - mostly taken from X11 mkdirhier
mkdirhier ()
{
	parts=`echo $1 | sed 's/\(.\)\/\(.\)/\1 \2/g`

	path=""
	for d in $parts
	do
		if [ "$path" = "" ]
		then
			dir=$d
		else
			dir=$path/$d
		fi

		if [ ! -d $dir ]
		then
			[ "$verbose" = "yes" ] && echo "Making $dir" 
			mkdir $dir
		fi

		path=$dir
	done
}


verbose=no
progname=`expr $0 : '.*/\(.*\)'`
conv_options="-ascii -7"
if [ "$progname" = "dos2unixdir" ]
then
	conv=dos2unix
elif [ "$progname" = "unix2dosdir" ]
then
	conv=unix2dos
else
	echo "Conversion program started with name $progname"
	echo "I only understand being started as dos2unixdir or unix2dosdir"
	exit 1
fi

if [ "$1" = "-v" ]
then
	verbose=yes
	shift
fi
topindir=$1
topoutdir=$2

if [ ! -d $topindir ]
then
	echo "$0: $topindir - not a directory or doesn't exist"
	exit 1
fi

# If the input directory is a symbolic link (e.g. ~/floppy) find won't
# follow it. Find doesn't have an option to make it follow symbolic
# links so the following hack is necessary.
[ -h $topindir ] && topindir="$topindir/."

if [ $# -eq 1 ]
then
	for infile in `find $topindir -type f -print`
	do
		[ "$verbose" = "yes" ] && echo $infile
		$conv $conv_options $infile $infile
	done
elif [ $# -eq 2 ]
then
	if [ ! -d $topoutdir ]
	then
		echo "$0: $topoutdir - not a directory or doesn't exist"
		exit 1
	fi

	for infile in `find $topindir -type f -print`
	do
		reloutfile=`expr $infile : "$topindir/\(.*\)"`
		reloutdir=`dirname $reloutfile`
		outdir=$topoutdir/$reloutdir
		baseoutfile=`basename $infile`
		outfile=$outdir/$baseoutfile
		[ ! -d $outdir ] && mkdirhier $outdir
		[ "$verbose" = "yes" ] && echo $outfile
		$conv $conv_options $infile $outfile
	done
else
	echo "usage: $0 [-v] input-directory [output-directory]"
	exit 1
fi
SHAR_EOF
#	End of shell archive
exit 0

--------------------------------------------------------------------------------
-- 
Michael Gordon - mfg@castle.ed.ac.uk OR ee.ed.ac.uk
Computing Officer, EE Dept, Edinburgh University
It's not an optical illusion, it just looks like one
Newsgroups: comp.bugs.4bsd