#!/bin/csh -f
#
# Sccs2rcs is a script to convert an existing SCCS
# history into an RCS history without losing any of
# the information contained therein.
#
# Things to note:
#   + The -b (batch) option can be used to tell this script to run
#     non-interactively.  In this mode, it assumes that you do not
#     want to enter descriptions on initial checkins, nor change
#     the default keyword substitution
#
#   + The -u option will cause a copy of the file to be checked out
#     after the conversion, so if you started with a workfile in place,
#     you'll end up with one there.
#
#   + It will NOT delete or alter your ./SCCS history under any circumstances.
#
#   + Run in a directory where ./SCCS exists and where you can create ./RCS
#
#   + Date, time, author, comments, branches, are all preserved.
#
#   + If a command fails somewhere in the middle, it bombs with
#     a message -- remove what it's done so far and try again.
#     (`rm -rf RCS; unget SCCS/s.*' should do the job.)
#     There is no recovery and exit is far from graceful.
#     If a particular module is hanging you up, consider
#     doing it separately; move it from the current area so that
#     the next run will have a better chance or working.
#     Also (for the brave only) you might consider hacking
#     the s-file for simpler problems:  I've successfully changed
#     the date of a delta to be in sync, then run "sccs admin -z"
#     on the thing.
#
#   + After everything finishes, ./SCCS will be moved to ./old-SCCS.
#
# This file may be copied, processed, hacked, mutilated, and
# even destroyed as long as you don't tell anyone you wrote it.
#
# Ken Cox
# Viewlogic Systems, Inc.
# kenstir@viewlogic.com
# ...!harvard!cg-atla!viewlog!kenstir
#
# 1.1: I added some portability fixes and the -u option.  More importantly,
# I removed the dependencies on the BSD/SV `sccs' utility; this script
# will now work on any system that has the base SCCS/RCS tools available.
#
# 1.2: Merges in Roger Pilkey's fix for the case in which date spans 
# cross the millenium boundary.  Use GNU tac instead of tail, which can't 
# reverse large files properly.
#
# 1.3: Merges in Brian Berliner's branch hack from the other fork
# of this script, the one distributed with CVS.  That and 4 SCCS 
# keyword substitutions were we only thing it did that this didn't.
#
# Eric S. Raymond <esr@thyrsus.com>
#
# $Id: sccs2rcs,v 1.10 2007/07/11 03:36:22 esr Exp $


# Note: newer versions of RCS require century digits on the -d option
# of ci.  Losing SCCS doesn't supply them.  Kluge around this.
#
set century = 19

############################################################
# Option handling
#
set nodesc = 0
set nohack = 0
set regen  = 0
while ($#argv)

    if ($argv[1] == "-b") then
	set nodesc = 1
	set nohack = 1    
    endif

    if ($argv[1] == "-u") then
	set regen = 1
    endif

    shift
end

############################################################
# Error checking
#
if (! -w .) then
    echo "Error: ./ not writeable by you."
    exit 1
endif
if (! -d SCCS) then
    echo "Error: ./SCCS directory not found."
    exit 1
endif
foreach f (*)
    if (-f SCCS/s.$f && -w $f) then
	echo "Error: $f is out for edit...clean up before converting."
	exit 1
    endif
end
if (-d RCS) then
    echo "Warning: RCS directory exists"
    if (`ls -a RCS | wc -l` > 2) then
        echo "Error: RCS directory not empty"
        exit 1
    endif
else
    mkdir RCS
endif

set months = (Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)

# Remove all files for which there exist SCCS masters
foreach f (*)
    if (-f SCCS/s.$f) then
	rm $f
    endif
end

set logfile = /tmp/sccs2rcs_$$_log
rm -f $logfile
set tmpfile = /tmp/sccs2rcs_$$_tmp
rm -f $tmpfile
set initialfile = /tmp/sccs2rcs_$$_init
echo "Initial revision" > $initialfile
set sedfile = /tmp/sccs2rcs_$$_sed
rm -f $sedfile

# the quotes surround the dollar signs are to fool RCS when I check in this script
set sccs_keywords = (\
    '%W%[ 	]*%G%'\
    '%W%[ 	]*%E%'\
    '%W%'\
    '%Z%%M%[ 	]*%I%[ 	]*%G%'\
    '%Z%%M%[ 	]*%I%[ 	]*%E%'\
    '%M%[ 	]*%I%[ 	]*%G%'\
    '%M%[ 	]*%I%[ 	]*%E%'\
    '%M%'\
    '%I%'\
    '%G%'\
    '%E%'\
    '%U%')
set rcs_keywords = (\
    '$'Id'$'\
    '$'Id'$'\
    '$'Id'$'\
    '$'SunId'$'\
    '$'SunId'$'\
    '$'Id'$'\
    '$'Id'$'\
    '$'RCSfile'$'\
    '$'Revision'$'\
    '$'Date'$'\
    '$'Date'$'\
    '')


############################################################
# Get some answers from user
#
if ($nodesc == 0) then
    echo ""
    echo "Do you want to be prompted for a description of each"
    echo "file as it is checked in to RCS initially?"
    echo -n "(y = prompt for description, n = null description) [y]? "
    set ans = $<
    if ((_$ans == _n) || (_$ans == _N)) then
	set nodesc = 1
    endif
endif

if ($nohack == 0) then
    echo ""
    echo "The default keyword substitutions are as follows and are"
    echo "applied in the order specified:"
    set i = 1
    while ($i <= $#sccs_keywords)
#	echo '	'\"$sccs_keywords[$i]\"'	==>	'\"$rcs_keywords[$i]\"
	echo "	$sccs_keywords[$i]	==>	$rcs_keywords[$i]"
	@ i = $i + 1
    end
    echo ""
    echo -n "Do you want to change them [n]? "
    set ans = $<
    if ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then
	echo "You can't always get what you want."
	echo "Edit this script file and change the variables:"
	echo '    $sccs_keywords'
	echo '    $rcs_keywords'
    else
	echo "Good idea."
    endif
endif

# create the sed script
set i = 1
while ($i <= $#sccs_keywords)
    echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile
    @ i = $i + 1
end

mkdir old-SCCS

############################################################
# Loop over every s-file in SCCS dir
#
foreach sfile (SCCS/s.*)
    # get rid of the "s." at the beginning of the name
    set file = `echo $sfile:t | sed -e "s/^..//"`

    # work on each rev of that file in ascending order
    set firsttime = 1
    foreach rev (`prs SCCS/s.$file | grep "^D " | awk '{print $2}' | tac`)
        if ($status != 0) goto ERROR

        # get file into current dir and get stats
        set date   = (`prs -d":Dd: :Dm: :Dy: :T: :P:" -r$rev SCCS/s.$file`)
	set day    = $date[1]
	set month  = $date[2]
	if ($date[3] < 10) then
		set next_century = (`expr $century + 1`)	
		set year   = ${next_century}${date[3]}
	else
		set year   = ${century}${date[3]}
	endif
	set time   = $date[4]
	set author = $date[5]
	set date = "$day $months[$month] $year $time"

        echo ""
        echo "==> file $file, rev=$rev, date=$date, author=$author"
        get -e -r$rev SCCS/s.$file >>& $logfile
        if ($status != 0) goto ERROR
        echo checked out of SCCS

        # add RCS keywords in place of SCCS keywords
        sed -f $sedfile $file > $tmpfile
        if ($status != 0) goto ERROR
        echo performed keyword substitutions
        cp $tmpfile $file

        # check file into RCS
        if ($firsttime) then
            set firsttime = 0
            if ($nodesc == 1) then
                ci -f -r$rev -d"$date" -w$author -t/dev/null $file <$initialfile >>& $logfile
                if ($status != 0) goto ERROR
                echo initial rev checked into RCS without description
            else
                echo ""
                echo Enter a brief description of the file $file \(end w/ Ctrl-D\):
                cat > $tmpfile
                ci -f -r$rev -d"$date" -w$author -t$tmpfile $file <$initialfile >>& $logfile
                if ($status != 0) goto ERROR
                echo initial rev checked into RCS
            endif
        else
            # get RCS lock
	    set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'`
	    if ("$lckrev" =~ [0-9]*.*) then
		# need to lock the brach -- it is OK if the lock fails
		rcs -l$lckrev $file >>& $logfile
	    else
		# need to lock the trunk -- must succeed
        	rcs -l $file >>& $logfile
        	if ($status != 0) goto ERROR
	    endif
            echo got lock
            prs -r$rev SCCS/s.$file | grep "." > $tmpfile
            # it's OK if grep fails here and gives status == 1
            # put the delta message in $tmpfile
            ed $tmpfile >>& $logfile <<EOF
/COMMENTS
1,.d
w
q
EOF
            ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile
            if ($status != 0) goto ERROR
            echo checked into RCS
        endif
        unget SCCS/s.$file >>& $logfile
        if ($status != 0) goto ERROR
    end
    rm -f $file
    mv $sfile old-SCCS
    if ($regen == 1) then
	co $file
    endif
end


############################################################
# Clean up
#
echo cleaning up...
rm -f $tmpfile $initialfile $sedfile
echo ===================================================
echo "Conversion of `pwd` OK"
echo ===================================================
exit 0

ERROR:
foreach f (*)
    if (-f SCCS/s.$f && -w $f) then
	unget SCCS/s.$f
    endif
end
echo ""
echo ""
echo Danger\!  Danger\!
echo Some command exited with a non-zero exit status.
echo Log file exists in $logfile.
echo ""
echo Incomplete history in ./RCS -- remove it
echo Original unchanged history in ./SCCS
exit 1
