mkCTM revision 6788
16563Sphk#!/usr/local/bin/tcl 22886Sphk 36563Sphk############################################################################# 46563Sphk### Add something 56563Sphk############################################################################# 66563Sphk# Type Name Mode User Group Barf Size Hash 72926Sphk 86563Sphkproc CTMadd {t n m u g b s h} { 96563Sphk global fo_files fo_mkdir changes CTMref 102886Sphk 116563Sphk puts stderr "A $b $t $n" 126563Sphk incr changes 133833Sphk 146563Sphk if {$t == "d"} { 156563Sphk puts $fo_mkdir "CTMDM $n $u $g $m" 166563Sphk } elseif {$t == "f"} { 176563Sphk puts $fo_files "CTMFM $n $u $g $m $h $s" 186563Sphk flush $fo_files 196563Sphk exec cat $CTMref/$n >@ $fo_files 206563Sphk puts $fo_files "" 216563Sphk } else { 226563Sphk puts "confused in CTMadd" 236563Sphk exit 0 246553Sphk } 256553Sphk} 265014Sphk 276563Sphk############################################################################# 286563Sphk### Delete something 296563Sphk############################################################################# 302886Sphk# Type Name Mode User Group Barf Size Hash 312886Sphk 322886Sphkproc CTMdel {t n m u g b s h} { 336563Sphk global fo_del fo_rmdir changes damage max_damage 346563Sphk 352886Sphk puts stderr "D $b $t $n" 366563Sphk incr damage 376563Sphk incr changes 386563Sphk 396563Sphk if {$damage > $max_damage} { 406563Sphk puts "Too much damage" 416563Sphk exit 0 426563Sphk } 432886Sphk if {$t == "d"} { 442886Sphk puts $fo_rmdir "CTMDR $n" 456563Sphk } elseif {$t == "f"} { 466563Sphk puts $fo_del "CTMFR $n $h" 476563Sphk } else { 486563Sphk puts "confused in CTMdel" 496563Sphk exit 0 502886Sphk } 512886Sphk} 526563Sphk 536563Sphk############################################################################# 546563Sphk### Change something 556563Sphk############################################################################# 566563Sphk# Type Name Mode User Group Barf Size Hash 576563Sphk 582886Sphkproc CTMchg {t1 n1 m1 u1 g1 b1 s1 h1 t2 n2 m2 u2 g2 b2 s2 h2} { 596563Sphk global fo_files CTMref CTMcopy changes damage CTMscratch 606563Sphk 616563Sphk # Ignore attribute changes for directories 626563Sphk if {$t1 == "d" && $t2 == "d"} return 636563Sphk 646563Sphk # turn file into dir or vice versa... 656563Sphk if {$t1 != $t2} { 662886Sphk CTMdel $t1 $n1 $m1 $u1 $g1 $b1 $s1 $h1 672886Sphk CTMadd $t2 $n2 $m2 $u2 $g2 $b2 $s2 $h2 682886Sphk return 692886Sphk } 706563Sphk 716563Sphk # only files allowed past this poing... 726563Sphk if {$t1 != "f" && $t2 != "f"} { 736563Sphk puts "confused in CTMchg" 746563Sphk exit 0 752886Sphk } 766563Sphk 776563Sphk # Ignore attribute changes for files 786563Sphk if {"x$h1" == "x$h2" && $s1 == $s2} return 796563Sphk 806563Sphk if {$s2 == 0} { incr damage } 816563Sphk incr changes 826563Sphk 836563Sphk # If diff will deal with it... 842948Sphk if {$b1 == "0" && $b2 == "0"} { 856563Sphk set i [catch "exec diff -n $CTMcopy/$n1 $CTMref/$n2 > $CTMscratch" j] 866563Sphk set s [file size $CTMscratch] 872926Sphk if {$s < $s2} { 883112Sphk puts stderr "E $b1$b2 $t1$t2 $n1" 892971Sphk puts $fo_files "CTMFN $n1 $u2 $g2 $m2 $h1 $h2 $s" 902926Sphk flush $fo_files 916563Sphk exec cat $CTMscratch >@ $fo_files 922926Sphk puts $fo_files "" 932926Sphk return 942926Sphk } 956563Sphk } 962926Sphk puts stderr "R $b1$b2 $t1$t2 $n1" 972926Sphk puts $fo_files "CTMFS $n2 $u2 $g2 $m2 $h1 $h2 $s2" 982886Sphk flush $fo_files 996563Sphk exec cat $CTMref/$n2 >@ $fo_files 1002886Sphk puts $fo_files "" 1012886Sphk} 1022886Sphk 1036563Sphk############################################################################# 1046563Sphk### Do we already have this delta ? 1056563Sphk############################################################################# 1066563Sphk 1076563Sphkproc find_delta {nbr} { 1086563Sphk global CTMname CTMdest 1096563Sphk if {[file exists [format "%s/$CTMname.%04d" $CTMdest $nbr]]} { return 1 } 1106563Sphk if {[file exists [format "%s/$CTMname.%04d.gz" $CTMdest $nbr]]} { return 1 } 1116563Sphk return 0 1126563Sphk} 1136563Sphk 1146563Sphk############################################################################# 1156563Sphk### The top level code... 1166563Sphk############################################################################# 1176563Sphk 1186563Sphkset CTMSW /home/ctm/SW 1196563Sphk 1206563Sphkcd $CTMSW 1216563Sphk 1226563Sphk# Defaults... 1236563Sphkset CTMapply 1 1246563Sphkset CTMdont {^///} 1256563Sphkset CTMmail {} 1266563Sphkset CTMsuff {} 1276563Sphkset CTMdate [exec date -u +%Y%m%d%H%M%SZ] 1286563Sphkset CTMtmp {} 1296563Sphkset CTMcopy {} 1306563Sphkset CTMdest {} 1316563Sphkset CTMprefix . 1326563Sphkset CTMtest 0 1336777Sphkset CTMspecial 0 1346563Sphkset max_damage 100 1356563Sphk 1366563Sphkset damage 0 1376563Sphkset changes 0 1386563Sphk 1396563Sphksource $argv 1406563Sphk 1416563Sphkif {$CTMtmp == ""} { 1426563Sphk set CTMtmp $CTMSW/../tmp/${CTMname}_${CTMsuff} 1436563Sphk} 1446563Sphkif {$CTMcopy == ""} { 1456563Sphk set CTMcopy $CTMSW/../$CTMname 1466563Sphk} 1476563Sphkif {$CTMdest == ""} { 1486563Sphk set CTMdest $CTMSW/../CTM-pub/$CTMname 1496563Sphk} 1506563Sphk 1516788Sphk# Make sure we only run one at a time... 1526788Sphk 1536788Sphkset CTMlock Lck.${CTMname}.${CTMdate}.[id process] 1546788Sphkexec rm -f ${CTMlock} 1556788Sphkexec echo starting > ${CTMlock} 1566788Sphkif {[catch "ln $CTMlock LCK.$CTMname" a]} { 1576788Sphk puts "Not going, lock exists..." 1586788Sphk exec rm -f $CTMlock 1596788Sphk} 1606788Sphkexec rm -f $CTMlock 1616788Sphkset CTMlock LCK.$CTMname 1626788Sphk 1636563Sphkset CTMscratch ${CTMtmp}.tmp 1646563Sphk 1652886Sphkwhile 1 { 1666777Sphk if { ! $CTMspecial} { 1676563Sphk set CTMnbr [lindex [exec cat $CTMcopy/.ctm_status] 1] 1682886Sphk 1696563Sphk if {![find_delta $CTMnbr]} { 1706563Sphk puts "$CTMname delta $CTMnbr doesn't exist..." 1716788Sphk exec rm -f $CTMlock 1726788Sphk exit 0 1736563Sphk } 1742886Sphk 1756563Sphk incr CTMnbr 1762886Sphk 1776563Sphk if {[find_delta $CTMnbr]} { 1786563Sphk puts "$CTMname delta $CTMnbr does already exist..." 1796788Sphk exec rm -f $CTMlock 1806563Sphk exit 0 1816563Sphk } 1822886Sphk 1836563Sphk set fo [open $CTMref/.ctm_status w] 1846563Sphk puts $fo "$CTMname $CTMnbr" 1856563Sphk close $fo 1866563Sphk incr changes -1 1873833Sphk 1886563Sphk } else { 1896563Sphk set CTMnbr [lindex [exec cat $CTMref/.ctm_status] 1] 1906777Sphk } 1916777Sphk 1926777Sphk if {"$CTMcopy" == "" } { 1936563Sphk set f1 [open /dev/null] 1946777Sphk } else { 1956777Sphk set f1 [open "| ./ctm_scan $CTMcopy"] 1962926Sphk } 1972926Sphk 1986777Sphk puts "Doing CTMname $CTMname CTMnbr $CTMnbr$CTMsuff CTMdate $CTMdate" 1996563Sphk flush stdout 2006563Sphk exec sh -c "rm -f ${CTMtmp}.* ${CTMtmp}:*" >&@ stdout 2012886Sphk 2026563Sphk set f2 [open "| ./ctm_scan $CTMref"] 2032886Sphk 2046563Sphk set fo_del [open $CTMtmp.del w] 2056563Sphk set fo_rmdir [open $CTMtmp.rmdir w] 2066563Sphk set fo_mkdir [open $CTMtmp.mkdir w] 2076563Sphk set fo_files [open $CTMtmp.files w] 2085014Sphk 2096563Sphk set l1 "" 2106563Sphk set l2 "" 2115014Sphk 2126563Sphk while 1 { 2136563Sphk 2146563Sphk if {$l1 == ""} {gets $f1 l1} 2156563Sphk 2166563Sphk if {$l2 == ""} {gets $f2 l2} 2176563Sphk 2186563Sphk if {$l1 == "" && $l2 == ""} break 2196563Sphk 2206563Sphk set n1 [lindex $l1 1] 2216563Sphk set n2 [lindex $l2 1] 2226563Sphk 2236563Sphk if {[regexp $CTMdont /$n1]} { set l1 "" ; continue } 2246563Sphk if {[regexp $CTMdont /$n2]} { set l2 "" ; continue } 2256563Sphk 2266563Sphk # they're all the same... 2276563Sphk if {$l1 == $l2} { set l1 "" ; set l2 "" ; continue } 2286563Sphk 2296563Sphk if {$l1 == "" } { eval CTMadd $l2 ; set l2 "" ; continue } 2306563Sphk 2316563Sphk if {$l2 == "" } { eval CTMdel $l1 ; set l1 "" ; continue } 2326563Sphk 2336563Sphk # if the name is the same we're safe... 2346563Sphk if {$n1 == $n2} { 2356563Sphk eval CTMchg $l1 $l2 2366563Sphk set l1 "" 2376563Sphk set l2 "" 2386563Sphk continue 2396563Sphk } 2406563Sphk 2416563Sphk # To avoid this anomaly: 2426563Sphk # A - d src/gnu/lib/libreadline/readline/Attic 2436563Sphk # A 0 f src/gnu/lib/libreadline/readline/Attic/readline.h,v 2446563Sphk # A 0 f src/gnu/lib/libreadline/readline.c,v 2456563Sphk # D 0 f src/gnu/lib/libreadline/readline/readline.h,v 2466563Sphk # D 0 f src/gnu/lib/libreadline/readline.c,v 2476563Sphk # we have to make things somewhat complicated... 2486563Sphk 2496563Sphk # if they have the same number of components... 2506563Sphk set ll1 [llength [split $n1 /]] 2516563Sphk set ll2 [llength [split $n2 /]] 2526563Sphk if {$ll1 == $ll2} { 2536563Sphk if {$n1 < $n2 } { 2546563Sphk eval CTMdel $l1 ; set l1 "" ; continue 2556563Sphk } else { 2566563Sphk eval CTMadd $l2 ; set l2 "" ; continue 2576563Sphk } 2586563Sphk } 2596563Sphk if {$ll1 < $ll2} { 2606563Sphk eval CTMadd $l2 ; set l2 "" ; continue 2615014Sphk } else { 2626563Sphk eval CTMdel $l1 ; set l1 "" ; continue 2635014Sphk } 2645014Sphk } 2655014Sphk 2666563Sphk close $fo_del 2676563Sphk close $fo_rmdir 2686563Sphk close $fo_mkdir 2696563Sphk close $fo_files 2702886Sphk 2716563Sphk if {$damage > $max_damage} { 2726563Sphk puts "Too much damage: $damage deletes" 2736563Sphk exec sh -c "rm -f ${CTMtmp}.*" 2746788Sphk exec rm -f $CTMlock 2756563Sphk exit 0 2766563Sphk } 2772886Sphk 2786563Sphk if {!$changes} { 2796563Sphk puts "no changes" 2806563Sphk exec sh -c "rm -f ${CTMtmp}.*" 2816788Sphk exec rm -f $CTMlock 2826563Sphk exit 0 2836563Sphk } 2842886Sphk 2856563Sphk exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $CTMtmp.begin 2862886Sphk 2876563Sphk puts "Assembling delta" 2886563Sphk flush stdout 2896563Sphk set nm [format "%s.%04d%s" $CTMname $CTMnbr $CTMsuff] 2902886Sphk 2916777Sphk set fdout [open "| /sbin/md5 -p | gzip -9 > ${CTMtmp}:${nm}.gz" w] 2923112Sphk 2936563Sphk foreach i {begin del rmdir mkdir files} { 2946563Sphk exec cat $CTMtmp.$i >@$fdout 2956563Sphk } 2966563Sphk puts $fdout "CTM_END " nonewline 2976563Sphk close $fdout ; unset fdout 2983112Sphk 2996563Sphk exec sh -x -c "rm -f ${CTMtmp}.*" >&@ stdout 3005014Sphk 3016563Sphk if {$CTMtest} { 3026563Sphk puts "testing, stopping now." 3036788Sphk exec rm -f $CTMlock 3046563Sphk exit 0 3056563Sphk } 3066563Sphk if {$CTMapply} { 3076563Sphk puts "Applying delta" 3086563Sphk flush stdout 3096788Sphk exec echo now applying > $CTMlock 3106563Sphk exec sh -e -x -c "cd $CTMcopy ; $CTMSW/ctm -v -v -v ${CTMtmp}:${nm}.gz" >&@ stdout 3116788Sphk exec echo did apply > $CTMlock 3126563Sphk } 3136563Sphk puts "Moving delta" 3146563Sphk flush stdout 3156563Sphk exec mv ${CTMtmp}:${nm}.gz $CTMdest/.CTMtmp_${nm}.gz >&@ stdout 3166563Sphk exec mv $CTMdest/.CTMtmp_${nm}.gz $CTMdest/${nm}.gz >&@ stdout 3176788Sphk exec echo moved > $CTMlock 3186563Sphk 3196563Sphk if {$CTMmail != ""} { 3206563Sphk puts "Mailing delta" 3216563Sphk flush stdout 3226777Sphk exec $CTMSW/ctm_smail -m 100000 -c 3000000 $CTMdest/${nm}.gz $CTMmail >&@ stdout 3236563Sphk } 3246788Sphk exec echo mailed > $CTMlock 3256563Sphk 3266563Sphk # If we did an absolute delta: stop. 3276563Sphk if {$CTMsuff != ""} break 3286563Sphk 3296563Sphk # Make a absolute delta (!) every 100 deltas 3306563Sphk if {$CTMnbr % 100} break 3316563Sphk 3326563Sphk # Make an absolute delta too... 3336563Sphk set CTMref $CTMcopy 3346563Sphk set CTMsuff A 3356563Sphk set CTMcopy "" 3366563Sphk set CTMmail "" 3376563Sphk set CTMapply 0 3386777Sphk set CTMspecial 1 3395014Sphk} 3406563Sphkputs "done." 3416788Sphkexec rm -f $CTMlock 342