1*a7c91847Schristos#! @CSH@ -f
2*a7c91847Schristos
3*a7c91847Schristos# Copyright (C) 1995-2005 The Free Software Foundation, Inc.
4*a7c91847Schristos
5*a7c91847Schristos# This program is free software; you can redistribute it and/or modify
6*a7c91847Schristos# it under the terms of the GNU General Public License as published by
7*a7c91847Schristos# the Free Software Foundation; either version 2, or (at your option)
8*a7c91847Schristos# any later version.
9*a7c91847Schristos#
10*a7c91847Schristos# This program is distributed in the hope that it will be useful,
11*a7c91847Schristos# but WITHOUT ANY WARRANTY; without even the implied warranty of
12*a7c91847Schristos# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*a7c91847Schristos# GNU General Public License for more details.
14*a7c91847Schristos#
15*a7c91847Schristos# Sccs2rcs is a script to convert an existing SCCS
16*a7c91847Schristos# history into an RCS history without losing any of
17*a7c91847Schristos# the information contained therein.
18*a7c91847Schristos# It has been tested under the following OS's:
19*a7c91847Schristos#     SunOS 3.5, 4.0.3, 4.1
20*a7c91847Schristos#     Ultrix-32 2.0, 3.1
21*a7c91847Schristos#
22*a7c91847Schristos# Things to note:
23*a7c91847Schristos#   + It will NOT delete or alter your ./SCCS history under any circumstances.
24*a7c91847Schristos#
25*a7c91847Schristos#   + Run in a directory where ./SCCS exists and where you can
26*a7c91847Schristos#       create ./RCS
27*a7c91847Schristos#
28*a7c91847Schristos#   + /usr/local/bin is put in front of the default path.
29*a7c91847Schristos#     (SCCS under Ultrix is set-uid sccs, bad bad bad, so
30*a7c91847Schristos#     /usr/local/bin/sccs here fixes that)
31*a7c91847Schristos#
32*a7c91847Schristos#   + Date, time, author, comments, branches, are all preserved.
33*a7c91847Schristos#
34*a7c91847Schristos#   + If a command fails somewhere in the middle, it bombs with
35*a7c91847Schristos#     a message -- remove what it's done so far and try again.
36*a7c91847Schristos#         "rm -rf RCS; sccs unedit `sccs tell`; sccs clean"
37*a7c91847Schristos#     There is no recovery and exit is far from graceful.
38*a7c91847Schristos#     If a particular module is hanging you up, consider
39*a7c91847Schristos#     doing it separately; move it from the current area so that
40*a7c91847Schristos#     the next run will have a better chance or working.
41*a7c91847Schristos#     Also (for the brave only) you might consider hacking
42*a7c91847Schristos#     the s-file for simpler problems:  I've successfully changed
43*a7c91847Schristos#     the date of a delta to be in sync, then run "sccs admin -z"
44*a7c91847Schristos#     on the thing.
45*a7c91847Schristos#
46*a7c91847Schristos#   + After everything finishes, ./SCCS will be moved to ./old-SCCS.
47*a7c91847Schristos#
48*a7c91847Schristos# This file may be copied, processed, hacked, mutilated, and
49*a7c91847Schristos# even destroyed as long as you don't tell anyone you wrote it.
50*a7c91847Schristos#
51*a7c91847Schristos# Ken Cox
52*a7c91847Schristos# Viewlogic Systems, Inc.
53*a7c91847Schristos# kenstir@viewlogic.com
54*a7c91847Schristos# ...!harvard!cg-atla!viewlog!kenstir
55*a7c91847Schristos#
56*a7c91847Schristos# Various hacks made by Brian Berliner before inclusion in CVS contrib area.
57*a7c91847Schristos#
58*a7c91847Schristos# Modified to detect SCCS binary files. If binary, skip the keyword
59*a7c91847Schristos# substitution and flag the RCS file as binary (using rcs -i -kb).
60*a7c91847Schristos#      -Allan G. Schrum schrum@ofsoptics.com agschrum@mindspring.com
61*a7c91847Schristos# Fri Sep 26 10:40:40 EDT 2003
62*a7c91847Schristos#
63*a7c91847Schristos
64*a7c91847Schristos
65*a7c91847Schristos#we'll assume the user set up the path correctly
66*a7c91847Schristos# for the Pmax, /usr/ucb/sccs is suid sccs, what a pain
67*a7c91847Schristos#   /usr/local/bin/sccs should override /usr/ucb/sccs there
68*a7c91847Schristosset path = (/usr/local/bin $path)
69*a7c91847Schristos
70*a7c91847Schristos
71*a7c91847Schristos############################################################
72*a7c91847Schristos# Error checking
73*a7c91847Schristos#
74*a7c91847Schristosif (! -w .) then
75*a7c91847Schristos    echo "Error: ./ not writeable by you."
76*a7c91847Schristos    exit 1
77*a7c91847Schristosendif
78*a7c91847Schristosif (! -d SCCS) then
79*a7c91847Schristos    echo "Error: ./SCCS directory not found."
80*a7c91847Schristos    exit 1
81*a7c91847Schristosendif
82*a7c91847Schristosset edits = (`sccs tell`)
83*a7c91847Schristosif ($#edits) then
84*a7c91847Schristos    echo "Error: $#edits file(s) out for edit...clean up before converting."
85*a7c91847Schristos    exit 1
86*a7c91847Schristosendif
87*a7c91847Schristosif (-d RCS) then
88*a7c91847Schristos    echo "Warning: RCS directory exists"
89*a7c91847Schristos    if (`ls -a RCS | wc -l` > 2) then
90*a7c91847Schristos        echo "Error: RCS directory not empty"
91*a7c91847Schristos        exit 1
92*a7c91847Schristos    endif
93*a7c91847Schristoselse
94*a7c91847Schristos    mkdir RCS
95*a7c91847Schristosendif
96*a7c91847Schristos
97*a7c91847Schristossccs clean
98*a7c91847Schristos
99*a7c91847Schristosset logfile = /tmp/sccs2rcs_$$_log
100*a7c91847Schristosrm -f $logfile
101*a7c91847Schristosset tmpfile = /tmp/sccs2rcs_$$_tmp
102*a7c91847Schristosrm -f $tmpfile
103*a7c91847Schristosset emptyfile = /tmp/sccs2rcs_$$_empty
104*a7c91847Schristosecho -n "" > $emptyfile
105*a7c91847Schristosset initialfile = /tmp/sccs2rcs_$$_init
106*a7c91847Schristosecho "Initial revision" > $initialfile
107*a7c91847Schristosset sedfile = /tmp/sccs2rcs_$$_sed
108*a7c91847Schristosrm -f $sedfile
109*a7c91847Schristosset revfile = /tmp/sccs2rcs_$$_rev
110*a7c91847Schristosrm -f $revfile
111*a7c91847Schristos
112*a7c91847Schristos# the quotes surround the dollar signs to fool RCS when I check in this script
113*a7c91847Schristosset sccs_keywords = (\
114*a7c91847Schristos    '%W%[ 	]*%G%'\
115*a7c91847Schristos    '%W%[ 	]*%E%'\
116*a7c91847Schristos    '%W%'\
117*a7c91847Schristos    '%Z%%M%[ 	]*%I%[ 	]*%G%'\
118*a7c91847Schristos    '%Z%%M%[ 	]*%I%[ 	]*%E%'\
119*a7c91847Schristos    '%M%[ 	]*%I%[ 	]*%G%'\
120*a7c91847Schristos    '%M%[ 	]*%I%[ 	]*%E%'\
121*a7c91847Schristos    '%M%'\
122*a7c91847Schristos    '%I%'\
123*a7c91847Schristos    '%G%'\
124*a7c91847Schristos    '%E%'\
125*a7c91847Schristos    '%U%')
126*a7c91847Schristosset rcs_keywords = (\
127*a7c91847Schristos    '$'Id'$'\
128*a7c91847Schristos    '$'Id'$'\
129*a7c91847Schristos    '$'Id'$'\
130*a7c91847Schristos    '$'SunId'$'\
131*a7c91847Schristos    '$'SunId'$'\
132*a7c91847Schristos    '$'Id'$'\
133*a7c91847Schristos    '$'Id'$'\
134*a7c91847Schristos    '$'RCSfile'$'\
135*a7c91847Schristos    '$'Revision'$'\
136*a7c91847Schristos    '$'Date'$'\
137*a7c91847Schristos    '$'Date'$'\
138*a7c91847Schristos    '')
139*a7c91847Schristos
140*a7c91847Schristos
141*a7c91847Schristos############################################################
142*a7c91847Schristos# Get some answers from user
143*a7c91847Schristos#
144*a7c91847Schristosecho ""
145*a7c91847Schristosecho "Do you want to be prompted for a description of each"
146*a7c91847Schristosecho "file as it is checked in to RCS initially?"
147*a7c91847Schristosecho -n "(y=prompt for description, n=null description) [y] ?"
148*a7c91847Schristosset ans = $<
149*a7c91847Schristosif ((_$ans == _) || (_$ans == _y) || (_$ans == _Y)) then
150*a7c91847Schristos    set nodesc = 0
151*a7c91847Schristoselse
152*a7c91847Schristos    set nodesc = 1
153*a7c91847Schristosendif
154*a7c91847Schristosecho ""
155*a7c91847Schristosecho "The default keyword substitutions are as follows and are"
156*a7c91847Schristosecho "applied in the order specified:"
157*a7c91847Schristosset i = 1
158*a7c91847Schristoswhile ($i <= $#sccs_keywords)
159*a7c91847Schristos#    echo '	'\"$sccs_keywords[$i]\"'	==>	'\"$rcs_keywords[$i]\"
160*a7c91847Schristos    echo "	$sccs_keywords[$i]	==>	$rcs_keywords[$i]"
161*a7c91847Schristos    @ i = $i + 1
162*a7c91847Schristosend
163*a7c91847Schristosecho ""
164*a7c91847Schristosecho -n "Do you want to change them [n] ?"
165*a7c91847Schristosset ans = $<
166*a7c91847Schristosif ((_$ans != _) && (_$ans != _n) && (_$ans != _N)) then
167*a7c91847Schristos    echo "You can't always get what you want."
168*a7c91847Schristos    echo "Edit this script file and change the variables:"
169*a7c91847Schristos    echo '    $sccs_keywords'
170*a7c91847Schristos    echo '    $rcs_keywords'
171*a7c91847Schristoselse
172*a7c91847Schristos    echo "good idea."
173*a7c91847Schristosendif
174*a7c91847Schristos
175*a7c91847Schristos# create the sed script
176*a7c91847Schristosset i = 1
177*a7c91847Schristoswhile ($i <= $#sccs_keywords)
178*a7c91847Schristos    echo "s,$sccs_keywords[$i],$rcs_keywords[$i],g" >> $sedfile
179*a7c91847Schristos    @ i = $i + 1
180*a7c91847Schristosend
181*a7c91847Schristos
182*a7c91847Schristosonintr ERROR
183*a7c91847Schristos
184*a7c91847Schristossort -k 1,1 /dev/null >& /dev/null
185*a7c91847Schristosif ($status == 0) then
186*a7c91847Schristos    set sort_each_field = '-k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9'
187*a7c91847Schristoselse
188*a7c91847Schristos    set sort_each_field = '+0 +1 +2 +3 +4 +5 +6 +7 +8'
189*a7c91847Schristosendif
190*a7c91847Schristos
191*a7c91847Schristos############################################################
192*a7c91847Schristos# Loop over every s-file in SCCS dir
193*a7c91847Schristos#
194*a7c91847Schristosforeach sfile (SCCS/s.*)
195*a7c91847Schristos    # get rid of the "s." at the beginning of the name
196*a7c91847Schristos    set file = `echo $sfile:t | sed -e "s/^..//"`
197*a7c91847Schristos
198*a7c91847Schristos    # work on each rev of that file in ascending order
199*a7c91847Schristos    set firsttime = 1
200*a7c91847Schristos
201*a7c91847Schristos    # Only scan the file up to the "I" keyword, then see if
202*a7c91847Schristos    # the "f" keyword is set to binary. The SCCS file has
203*a7c91847Schristos    # <ctrl>-aI denoting the start of the file (or end of header).
204*a7c91847Schristos    set binary = (`sed -e '/^.I/,$d' < $sfile | grep '^.f e 1$'`)
205*a7c91847Schristos    #if ($#binary) then
206*a7c91847Schristos    #    echo This is a binary file
207*a7c91847Schristos    #else
208*a7c91847Schristos    #    echo This is not a binary file
209*a7c91847Schristos    #endif
210*a7c91847Schristos
211*a7c91847Schristos    sccs prs $file | grep "^D " | @AWK@ '{print $2}' | sed -e 's/\./ /g' | sort -n -u $sort_each_field | sed -e 's/ /./g' > $revfile
212*a7c91847Schristos    foreach rev (`cat $revfile`)
213*a7c91847Schristos        if ($status != 0) goto ERROR
214*a7c91847Schristos
215*a7c91847Schristos        # get file into current dir and get stats
216*a7c91847Schristos
217*a7c91847Schristos	# Is the substr stuff and the +0 in the following awk script really
218*a7c91847Schristos	# necessary?  It seems to me that if we didn't find the date format
219*a7c91847Schristos	# we expected in the output we have other problems.
220*a7c91847Schristos	# Note: Solaris awk does not like the following line. Use gawk
221*a7c91847Schristos	# mawk, or nawk instead.
222*a7c91847Schristos	set date = `sccs prs -r$rev $file | @AWK@ '/^D / {print (substr($3,0,2)+0<70?20:19) $3, $4; exit}'`
223*a7c91847Schristos        set author = `sccs prs -r$rev $file | @AWK@ '/^D / {print $5; exit}'`
224*a7c91847Schristos        echo ""
225*a7c91847Schristos        echo "==> file $file, rev=$rev, date=$date, author=$author"
226*a7c91847Schristos        sccs edit -r$rev $file >>& $logfile
227*a7c91847Schristos        if ($status != 0) goto ERROR
228*a7c91847Schristos        echo checked out of SCCS
229*a7c91847Schristos
230*a7c91847Schristos        # add RCS keywords in place of SCCS keywords (only if not binary)
231*a7c91847Schristos        if ($#binary == 0) then
232*a7c91847Schristos            sed -f $sedfile $file > $tmpfile
233*a7c91847Schristos            if ($status != 0) goto ERROR
234*a7c91847Schristos            echo performed keyword substitutions
235*a7c91847Schristos            cp $tmpfile $file
236*a7c91847Schristos        endif
237*a7c91847Schristos
238*a7c91847Schristos        # check file into RCS
239*a7c91847Schristos        if ($firsttime) then
240*a7c91847Schristos            set firsttime = 0
241*a7c91847Schristos
242*a7c91847Schristos            if ($#binary) then
243*a7c91847Schristos                echo this is a binary file
244*a7c91847Schristos                # Mark initial, empty file as binary
245*a7c91847Schristos                rcs -i -kb -t$emptyfile $file
246*a7c91847Schristos            endif
247*a7c91847Schristos
248*a7c91847Schristos            if ($nodesc) then
249*a7c91847Schristos		echo about to do ci
250*a7c91847Schristos                echo ci -f -r$rev -d"$date" -w$author -t$emptyfile $file
251*a7c91847Schristos                ci -f -r$rev -d"$date" -w$author -t$emptyfile $file < $initialfile >>& $logfile
252*a7c91847Schristos                if ($status != 0) goto ERROR
253*a7c91847Schristos                echo initial rev checked into RCS without description
254*a7c91847Schristos            else
255*a7c91847Schristos                echo ""
256*a7c91847Schristos                echo Enter a brief description of the file $file \(end w/ Ctrl-D\):
257*a7c91847Schristos                cat > $tmpfile
258*a7c91847Schristos                ci -f -r$rev -d"$date" -w$author -t$tmpfile $file < $initialfile >>& $logfile
259*a7c91847Schristos                if ($status != 0) goto ERROR
260*a7c91847Schristos                echo initial rev checked into RCS
261*a7c91847Schristos            endif
262*a7c91847Schristos        else
263*a7c91847Schristos            # get RCS lock
264*a7c91847Schristos	    set lckrev = `echo $rev | sed -e 's/\.[0-9]*$//'`
265*a7c91847Schristos	    if ("$lckrev" =~ [0-9]*.*) then
266*a7c91847Schristos		# need to lock the brach -- it is OK if the lock fails
267*a7c91847Schristos		rcs -l$lckrev $file >>& $logfile
268*a7c91847Schristos	    else
269*a7c91847Schristos		# need to lock the trunk -- must succeed
270*a7c91847Schristos                rcs -l $file >>& $logfile
271*a7c91847Schristos                if ($status != 0) goto ERROR
272*a7c91847Schristos	    endif
273*a7c91847Schristos            echo got lock
274*a7c91847Schristos            sccs prs -r$rev $file | grep "." > $tmpfile
275*a7c91847Schristos            # it's OK if grep fails here and gives status == 1
276*a7c91847Schristos            # put the delta message in $tmpfile
277*a7c91847Schristos            ed $tmpfile >>& $logfile <<EOF
278*a7c91847Schristos/COMMENTS
279*a7c91847Schristos1,.d
280*a7c91847Schristosw
281*a7c91847Schristosq
282*a7c91847SchristosEOF
283*a7c91847Schristos            ci -f -r$rev -d"$date" -w$author $file < $tmpfile >>& $logfile
284*a7c91847Schristos            if ($status != 0) goto ERROR
285*a7c91847Schristos            echo checked into RCS
286*a7c91847Schristos        endif
287*a7c91847Schristos        sccs unedit $file >>& $logfile
288*a7c91847Schristos        if ($status != 0) goto ERROR
289*a7c91847Schristos    end
290*a7c91847Schristos    rm -f $file
291*a7c91847Schristosend
292*a7c91847Schristos
293*a7c91847Schristos
294*a7c91847Schristos############################################################
295*a7c91847Schristos# Clean up
296*a7c91847Schristos#
297*a7c91847Schristosecho cleaning up...
298*a7c91847Schristosmv SCCS old-SCCS
299*a7c91847Schristosrm -f $tmpfile $emptyfile $initialfile $sedfile
300*a7c91847Schristosecho ===================================================
301*a7c91847Schristosecho "       Conversion Completed Successfully"
302*a7c91847Schristosecho ""
303*a7c91847Schristosecho "         SCCS history now in old-SCCS/"
304*a7c91847Schristosecho ===================================================
305*a7c91847Schristosset exitval = 0
306*a7c91847Schristosgoto cleanup
307*a7c91847Schristos
308*a7c91847SchristosERROR:
309*a7c91847Schristosforeach f (`sccs tell`)
310*a7c91847Schristos    sccs unedit $f
311*a7c91847Schristosend
312*a7c91847Schristosecho ""
313*a7c91847Schristosecho ""
314*a7c91847Schristosecho Danger\!  Danger\!
315*a7c91847Schristosecho Some command exited with a non-zero exit status.
316*a7c91847Schristosecho Log file exists in $logfile.
317*a7c91847Schristosecho ""
318*a7c91847Schristosecho Incomplete history in ./RCS -- remove it
319*a7c91847Schristosecho Original unchanged history in ./SCCS
320*a7c91847Schristosset exitval = 1
321*a7c91847Schristos
322*a7c91847Schristoscleanup:
323*a7c91847Schristos# leave log file
324*a7c91847Schristosrm -f $tmpfile $emptyfile $initialfile $sedfile $revfile
325*a7c91847Schristos
326*a7c91847Schristosexit $exitval
327