From 97074d779fffceae5ff9112307a29d7690bac432 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Mon, 20 Feb 1995 03:03:02 +0000 Subject: [PATCH] The new and improved mkCTM. Learning from this experience it has been improved on a couple of accounts. Amongst these are "damage control" more than 100 files removed and it will bail out... --- usr.sbin/ctm/mkCTM/ctm_conf.cvs-cur | 11 +- usr.sbin/ctm/mkCTM/ctm_conf.ports-cur | 6 + usr.sbin/ctm/mkCTM/ctm_conf.src-cur | 12 +- usr.sbin/ctm/mkCTM/mkCTM | 449 ++++++++++++++++---------- 4 files changed, 288 insertions(+), 190 deletions(-) create mode 100644 usr.sbin/ctm/mkCTM/ctm_conf.ports-cur diff --git a/usr.sbin/ctm/mkCTM/ctm_conf.cvs-cur b/usr.sbin/ctm/mkCTM/ctm_conf.cvs-cur index b6e54bb03372..7453435df9f4 100644 --- a/usr.sbin/ctm/mkCTM/ctm_conf.cvs-cur +++ b/usr.sbin/ctm/mkCTM/ctm_conf.cvs-cur @@ -1,11 +1,6 @@ #!/usr/local/bin/tclsh set CTMname cvs-cur -set CTMref /u1/CVS-FreeBSD -set CTMdest /u4/ftp/pub/CTM -set CTMprefix . -set CTMdont {.*\.core$|^/CVSROOT/history.*$|^/src/secure|^/src/eBones|^/sup/} - -set CTMcopy /u1/CTM/$CTMname -set CTMtmp /u1/CTM/tmp/_tmp_$CTMname -set CTMdate [exec date -u +%Y%m%d%H%M%SZ] +set CTMref /home/ncvs +set CTMdest $CTMSW/../CTM-priv/$CTMname +set CTMdont {\.core$|^/CVSROOT/history.*$|^/src/secure|^/src/eBones|^/src/kerberosIV} diff --git a/usr.sbin/ctm/mkCTM/ctm_conf.ports-cur b/usr.sbin/ctm/mkCTM/ctm_conf.ports-cur new file mode 100644 index 000000000000..46843a9e5f7b --- /dev/null +++ b/usr.sbin/ctm/mkCTM/ctm_conf.ports-cur @@ -0,0 +1,6 @@ +#!/usr/local/bin/tclsh + +set CTMname ports-cur +set CTMref /usr/ports +set CTMdont {\.core$|/CVS$|/CVS/|^/distfiles} + diff --git a/usr.sbin/ctm/mkCTM/ctm_conf.src-cur b/usr.sbin/ctm/mkCTM/ctm_conf.src-cur index 8efd6a065147..e928ad3a4eae 100644 --- a/usr.sbin/ctm/mkCTM/ctm_conf.src-cur +++ b/usr.sbin/ctm/mkCTM/ctm_conf.src-cur @@ -1,12 +1,6 @@ #!/usr/local/bin/tclsh set CTMname src-cur -set CTMref /u4/ftp/pub/FreeBSD/SRC-current/src -set CTMdest /u4/ftp/pub/CTM -set CTMprefix . -set CTMdont {.*\.core$|/CVS$|/CVS/Entries$|/CVS/Repository$|^secure|^eBones} -set CTMmail ctm-src-cur@freebsd.org - -set CTMcopy /u1/CTM/$CTMname -set CTMtmp /u1/CTM/tmp/_tmp_$CTMname -set CTMdate [exec date -u +%Y%m%d%H%M%SZ] +set CTMref /usr/src +set CTMdont {\.core$|/CVS$|/CVS/|^/secure|^/eBones} +#set CTMmail ctm-src-cur@freebsd.org diff --git a/usr.sbin/ctm/mkCTM/mkCTM b/usr.sbin/ctm/mkCTM/mkCTM index 7001046149f7..885498e1089b 100644 --- a/usr.sbin/ctm/mkCTM/mkCTM +++ b/usr.sbin/ctm/mkCTM/mkCTM @@ -1,216 +1,319 @@ -#!/usr/local/bin/tclsh +#!/usr/local/bin/tcl -set CTMignoreCVS 0 -set CTMapply 1 -set CTMdont {^///} -set CTMmail {} -set CTMsuff {} - -source $argv - -cd /u1/CTM/SW - -set tmp $CTMtmp -set dd $CTMdest -set d1 $CTMcopy -set d2 $CTMref -set foo $CTMdate -set foo $CTMprefix -set foo $CTMname - -if { "$d1" != "" } { - #### - # Find CTM# - for {set i 0} {1} {incr i} { - if {[file exists [format "%s/$CTMname.%04d" $dd $i]]} continue - if {[file exists [format "%s/$CTMname.%04d.gz" $dd $i]]} continue - break - } - set CTMnbr $i - - set fo [open $d2/.ctm_status w] - puts $fo "$CTMname $CTMnbr" - close $fo - - puts "Doing CTMname $CTMname CTMnbr $CTMnbr CTMdate $CTMdate" - - exec sh -x -c "rm -f ${tmp}.*" >&@ stdout - - set f1 [open "| ./ctm_scan $d1"] - # set this to minus one, to compensate for .ctm_status - set changes -1 -} else { - set CTMnbr [lindex [exec cat $d2/.ctm_status] 1] - puts "Doing CTMname $CTMname CTMnbr $CTMnbr CTMdate $CTMdate" - exec sh -x -c "rm -f ${tmp}.*" >&@ stdout - set f1 [open /dev/null] - set changes 0 -} -set f2 [open "| ./ctm_scan $d2"] - -set fo_del [open $tmp.del w] -set fo_rmdir [open $tmp.rmdir w] -set fo_mkdir [open $tmp.mkdir w] -set fo_files [open $tmp.files w] - -##### +############################################################################# +### Add something +############################################################################# # Type Name Mode User Group Barf Size Hash proc CTMadd {t n m u g b s h} { - global fo_files fo_mkdir changes d2 + global fo_files fo_mkdir changes CTMref + puts stderr "A $b $t $n" + incr changes + if {$t == "d"} { puts $fo_mkdir "CTMDM $n $u $g $m" - incr changes - return + } elseif {$t == "f"} { + puts $fo_files "CTMFM $n $u $g $m $h $s" + flush $fo_files + exec cat $CTMref/$n >@ $fo_files + puts $fo_files "" + } else { + puts "confused in CTMadd" + exit 0 } - puts $fo_files "CTMFM $n $u $g $m $h $s" - flush $fo_files - exec cat $d2/$n >@ $fo_files - puts $fo_files "" - incr changes - return } + +############################################################################# +### Delete something +############################################################################# +# Type Name Mode User Group Barf Size Hash + proc CTMdel {t n m u g b s h} { - global fo_del fo_rmdir changes + global fo_del fo_rmdir changes damage max_damage + puts stderr "D $b $t $n" + incr damage + incr changes + + if {$damage > $max_damage} { + puts "Too much damage" + exit 0 + } if {$t == "d"} { puts $fo_rmdir "CTMDR $n" - incr changes - return + } elseif {$t == "f"} { + puts $fo_del "CTMFR $n $h" + } else { + puts "confused in CTMdel" + exit 0 } - puts $fo_del "CTMFR $n $h" - incr changes - return } + +############################################################################# +### Change something +############################################################################# +# Type Name Mode User Group Barf Size Hash + proc CTMchg {t1 n1 m1 u1 g1 b1 s1 h1 t2 n2 m2 u2 g2 b2 s2 h2} { - global fo_files d2 d1 changes - if {$t1 == "d" && $t2 == "d"} { - return - } - if {$t1 == "d" || $t2 == "d"} { + global fo_files CTMref CTMcopy changes damage CTMscratch + + # Ignore attribute changes for directories + if {$t1 == "d" && $t2 == "d"} return + + # turn file into dir or vice versa... + if {$t1 != $t2} { CTMdel $t1 $n1 $m1 $u1 $g1 $b1 $s1 $h1 CTMadd $t2 $n2 $m2 $u2 $g2 $b2 $s2 $h2 return } - if {"x$h1" == "x$h2" && $s1 == $s2} { - return - puts stderr "M $b1$b2 $t1$t2 $n1" - puts $fo_files "CTMFA $n2 $u2 $g2 $m2 $h2" - incr changes - return + + # only files allowed past this poing... + if {$t1 != "f" && $t2 != "f"} { + puts "confused in CTMchg" + exit 0 } + + # Ignore attribute changes for files + if {"x$h1" == "x$h2" && $s1 == $s2} return + + if {$s2 == 0} { incr damage } + incr changes + + # If diff will deal with it... if {$b1 == "0" && $b2 == "0"} { - set i [catch "exec diff -n $d1/$n1 $d2/$n2 > tmp" j] - set s [file size tmp] + set i [catch "exec diff -n $CTMcopy/$n1 $CTMref/$n2 > $CTMscratch" j] + set s [file size $CTMscratch] if {$s < $s2} { puts stderr "E $b1$b2 $t1$t2 $n1" puts $fo_files "CTMFN $n1 $u2 $g2 $m2 $h1 $h2 $s" flush $fo_files - exec cat tmp >@ $fo_files + exec cat $CTMscratch >@ $fo_files puts $fo_files "" - incr changes return } - } + } puts stderr "R $b1$b2 $t1$t2 $n1" puts $fo_files "CTMFS $n2 $u2 $g2 $m2 $h1 $h2 $s2" flush $fo_files - exec cat $d2/$n2 >@ $fo_files + exec cat $CTMref/$n2 >@ $fo_files puts $fo_files "" - incr changes - return } -##### -set l1 "" -set l2 "" + +############################################################################# +### Do we already have this delta ? +############################################################################# + +proc find_delta {nbr} { + global CTMname CTMdest + if {[file exists [format "%s/$CTMname.%04d" $CTMdest $nbr]]} { return 1 } + if {[file exists [format "%s/$CTMname.%04d.gz" $CTMdest $nbr]]} { return 1 } + return 0 +} + +############################################################################# +### The top level code... +############################################################################# + +set CTMSW /home/ctm/SW + +cd $CTMSW + +# Defaults... +set CTMapply 1 +set CTMdont {^///} +set CTMmail {} +set CTMsuff {} +set CTMdate [exec date -u +%Y%m%d%H%M%SZ] +set CTMtmp {} +set CTMcopy {} +set CTMdest {} +set CTMprefix . +set CTMtest 0 +set max_damage 100 + +set damage 0 +set changes 0 + +source $argv + +if {$CTMtmp == ""} { + set CTMtmp $CTMSW/../tmp/${CTMname}_${CTMsuff} +} +if {$CTMcopy == ""} { + set CTMcopy $CTMSW/../$CTMname +} +if {$CTMdest == ""} { + set CTMdest $CTMSW/../CTM-pub/$CTMname +} + +set CTMscratch ${CTMtmp}.tmp while 1 { + if { "$CTMcopy" != "" } { + set CTMnbr [lindex [exec cat $CTMcopy/.ctm_status] 1] - if {$l1 == ""} {gets $f1 l1} - - if {$l2 == ""} {gets $f2 l2} - - if {$l1 == "" && $l2 == ""} break - - set n1 [lindex $l1 1] - set n2 [lindex $l2 1] - - #if {[regexp $CTMdont /$n1]} { set l1 "" ; continue } - if {[regexp $CTMdont /$n2]} { set l2 "" ; continue } - - # they're all the same... - if {$l1 == $l2} { set l1 "" ; set l2 "" ; continue } - - if {$CTMignoreCVS } { - if {[regexp {/CVS/} $l1]} {set l1 ""; continue } - if {[regexp {/CVS/} $l2]} {set l2 ""; continue } - } - - if {$l1 == "" } { eval CTMadd $l2 ; set l2 "" ; continue } - - if {$l2 == "" } { eval CTMdel $l1 ; set l1 "" ; continue } - - # if the name is the same we're safe... - if {$n1 == $n2} { eval CTMchg $l1 $l2 ; set l1 "" ; set l2 "" ; continue } - - # To avoid this anomaly: - # A - d src/gnu/lib/libreadline/readline/Attic - # A 0 f src/gnu/lib/libreadline/readline/Attic/readline.h,v - # A 0 f src/gnu/lib/libreadline/readline.c,v - # D 0 f src/gnu/lib/libreadline/readline/readline.h,v - # D 0 f src/gnu/lib/libreadline/readline.c,v - # we have to make things somewhat complicated... - - # if they have the same number of components... - set ll1 [llength [split $n1 /]] - set ll2 [llength [split $n2 /]] - if {$ll1 == $ll2} { - if {$n1 < $n2 } { - eval CTMdel $l1 ; set l1 "" ; continue - } else { - eval CTMadd $l2 ; set l2 "" ; continue + if {![find_delta $CTMnbr]} { + puts "$CTMname delta $CTMnbr doesn't exist..." + # exit 0 } - } - if {$ll1 < $ll2} { - eval CTMadd $l2 ; set l2 "" ; continue + + incr CTMnbr + + if {[find_delta $CTMnbr]} { + puts "$CTMname delta $CTMnbr does already exist..." + exit 0 + } + + set fo [open $CTMref/.ctm_status w] + puts $fo "$CTMname $CTMnbr" + close $fo + incr changes -1 + + set f1 [open "| ./ctm_scan $CTMcopy"] } else { - eval CTMdel $l1 ; set l1 "" ; continue + set CTMnbr [lindex [exec cat $CTMref/.ctm_status] 1] + set f1 [open /dev/null] } - + puts "Doing CTMname $CTMname CTMnbr $CTMnbr CTMdate $CTMdate" + flush stdout + exec sh -c "rm -f ${CTMtmp}.* ${CTMtmp}:*" >&@ stdout + set f2 [open "| ./ctm_scan $CTMref"] + + set fo_del [open $CTMtmp.del w] + set fo_rmdir [open $CTMtmp.rmdir w] + set fo_mkdir [open $CTMtmp.mkdir w] + set fo_files [open $CTMtmp.files w] + + set l1 "" + set l2 "" + + while 1 { + + if {$l1 == ""} {gets $f1 l1} + + if {$l2 == ""} {gets $f2 l2} + + if {$l1 == "" && $l2 == ""} break + + set n1 [lindex $l1 1] + set n2 [lindex $l2 1] + + if {[regexp $CTMdont /$n1]} { set l1 "" ; continue } + if {[regexp $CTMdont /$n2]} { set l2 "" ; continue } + + # they're all the same... + if {$l1 == $l2} { set l1 "" ; set l2 "" ; continue } + + if {$l1 == "" } { eval CTMadd $l2 ; set l2 "" ; continue } + + if {$l2 == "" } { eval CTMdel $l1 ; set l1 "" ; continue } + + # if the name is the same we're safe... + if {$n1 == $n2} { + eval CTMchg $l1 $l2 + set l1 "" + set l2 "" + continue + } + + # To avoid this anomaly: + # A - d src/gnu/lib/libreadline/readline/Attic + # A 0 f src/gnu/lib/libreadline/readline/Attic/readline.h,v + # A 0 f src/gnu/lib/libreadline/readline.c,v + # D 0 f src/gnu/lib/libreadline/readline/readline.h,v + # D 0 f src/gnu/lib/libreadline/readline.c,v + # we have to make things somewhat complicated... + + # if they have the same number of components... + set ll1 [llength [split $n1 /]] + set ll2 [llength [split $n2 /]] + if {$ll1 == $ll2} { + if {$n1 < $n2 } { + eval CTMdel $l1 ; set l1 "" ; continue + } else { + eval CTMadd $l2 ; set l2 "" ; continue + } + } + if {$ll1 < $ll2} { + eval CTMadd $l2 ; set l2 "" ; continue + } else { + eval CTMdel $l1 ; set l1 "" ; continue + } + } + + close $fo_del + close $fo_rmdir + close $fo_mkdir + close $fo_files + + if {$damage > $max_damage} { + puts "Too much damage: $damage deletes" + exec sh -c "rm -f ${CTMtmp}.*" + exit 0 + } + + if {!$changes} { + puts "no changes" + exec sh -c "rm -f ${CTMtmp}.*" + exit 0 + } + + exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $CTMtmp.begin + + puts "Assembling delta" + flush stdout + set nm [format "%s.%04d%s" $CTMname $CTMnbr $CTMsuff] + + set fdmd5 [open "|/sbin/md5 >> $CTMtmp.end" w] + set fdout [open "| gzip -9 > ${CTMtmp}:${nm}.gz" w] + + foreach i {begin del rmdir mkdir files} { + exec cat $CTMtmp.$i >@$fdmd5 + exec cat $CTMtmp.$i >@$fdout + } + puts $fdmd5 "CTM_END " nonewline + close $fdmd5 ; unset fdmd5 + puts $fdout "CTM_END " nonewline + flush $fdout + exec cat $CTMtmp.end >@$fdout + close $fdout ; unset fdout + + exec sh -x -c "rm -f ${CTMtmp}.*" >&@ stdout + + if {$CTMtest} { + puts "testing, stopping now." + exit 0 + } + if {$CTMapply} { + puts "Applying delta" + flush stdout + exec sh -e -x -c "cd $CTMcopy ; $CTMSW/ctm -v -v -v ${CTMtmp}:${nm}.gz" >&@ stdout + } + puts "Moving delta" + flush stdout + exec mv ${CTMtmp}:${nm}.gz $CTMdest/.CTMtmp_${nm}.gz >&@ stdout + exec mv $CTMdest/.CTMtmp_${nm}.gz $CTMdest/${nm}.gz >&@ stdout + + if {$CTMmail != ""} { + puts "Mailing delta" + flush stdout + exec $CTMSW/ctm_smail -m 50000 -c 300000 $CTMdest/${nm}.gz $CTMmail >&@ stdout + } + + # If we did an absolute delta: stop. + if {$CTMsuff != ""} break + + # Make a absolute delta (!) every 100 deltas + if {$CTMnbr % 100} break + + # Make an absolute delta too... + set CTMref $CTMcopy + set CTMsuff A + set CTMcopy "" + set CTMmail "" + set CTMapply 0 } - -close $fo_del -close $fo_rmdir -close $fo_mkdir -close $fo_files - -exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $tmp.begin -exec echo -n "CTM_END " >> $tmp.end -set m [exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end | /sbin/md5] -exec echo "$m" >> $tmp.end - -if {!$changes} { - puts "no changes" - exec sh -c "rm -f ${tmp}.*" - exit 0 -} -flush stdout -set nm [format "%s.%04d%s" $CTMname $CTMnbr $CTMsuff] - -exec cat $tmp.begin $tmp.del $tmp.rmdir $tmp.mkdir $tmp.files $tmp.end \ - | gzip -9 > ${tmp}:${nm}.gz - -exec sh -x -c "rm -f ${tmp}.*" >&@ stdout - -if {$CTMapply} { - exec sh -e -x -c "cd $CTMcopy ; /u1/CTM/SW/ctm -v -v -v ${tmp}:${nm}.gz" >&@ stdout -} -exec mv ${tmp}:${nm}.gz $dd/.tmp_${nm}.gz >&@ stdout -exec mv $dd/.tmp_${nm}.gz $dd/${nm}.gz >&@ stdout - -if {$CTMmail != ""} { - exec /u1/phk/ctm_smail/ctm_smail -m 50000 -c 300000 $dd/${nm}.gz $CTMmail >&@ stdout -} +puts "done."