mkCTM revision 7463
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} { 337463Sphk global fo_del fo_rmdir changes damage max_damage CTMlock 346563Sphk 352886Sphk puts stderr "D $b $t $n" 366563Sphk incr damage 376563Sphk incr changes 386563Sphk 396563Sphk if {$damage > $max_damage} { 407463Sphk exec rm -f $CTMlock 417463Sphk return 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 1347463Sphkset CTMscan . 1357463Sphkset CTMfirst 0 1367463Sphkset max_damage 1200 1376563Sphk 1386563Sphkset damage 0 1396563Sphkset changes 0 1406563Sphk 1416563Sphksource $argv 1426563Sphk 1436563Sphkif {$CTMtmp == ""} { 1446563Sphk set CTMtmp $CTMSW/../tmp/${CTMname}_${CTMsuff} 1456563Sphk} 1466563Sphkif {$CTMcopy == ""} { 1476563Sphk set CTMcopy $CTMSW/../$CTMname 1486563Sphk} 1496563Sphkif {$CTMdest == ""} { 1506563Sphk set CTMdest $CTMSW/../CTM-pub/$CTMname 1516563Sphk} 1526563Sphk 1536788Sphk# Make sure we only run one at a time... 1546788Sphk 1556788Sphkset CTMlock Lck.${CTMname}.${CTMdate}.[id process] 1566788Sphkexec rm -f ${CTMlock} 1576788Sphkexec echo starting > ${CTMlock} 1587463Sphkif {[catch "exec ln $CTMlock LCK.$CTMname" a]} { 1596788Sphk puts "Not going, lock exists..." 1606788Sphk exec rm -f $CTMlock 1617463Sphk exit 0 1626788Sphk} 1636788Sphkexec rm -f $CTMlock 1646788Sphkset CTMlock LCK.$CTMname 1656788Sphk 1666563Sphkset CTMscratch ${CTMtmp}.tmp 1676563Sphk 1682886Sphkwhile 1 { 1696777Sphk if { ! $CTMspecial} { 1707463Sphk if {$CTMfirst} { 1717463Sphk set CTMnbr 0 1727463Sphk } else { 1737463Sphk set CTMnbr [lindex [exec cat $CTMcopy/.ctm_status] 1] 1747463Sphk } 1752886Sphk 1767463Sphk if {$CTMnbr > 0 && ![find_delta $CTMnbr]} { 1776563Sphk puts "$CTMname delta $CTMnbr doesn't exist..." 1786788Sphk exec rm -f $CTMlock 1796788Sphk exit 0 1806563Sphk } 1812886Sphk 1826563Sphk incr CTMnbr 1832886Sphk 1846563Sphk if {[find_delta $CTMnbr]} { 1856563Sphk puts "$CTMname delta $CTMnbr does already exist..." 1866788Sphk exec rm -f $CTMlock 1876563Sphk exit 0 1886563Sphk } 1892886Sphk 1906563Sphk set fo [open $CTMref/.ctm_status w] 1916563Sphk puts $fo "$CTMname $CTMnbr" 1926563Sphk close $fo 1936563Sphk incr changes -1 1943833Sphk 1956563Sphk } else { 1966563Sphk set CTMnbr [lindex [exec cat $CTMref/.ctm_status] 1] 1976777Sphk } 1986777Sphk 1996777Sphk if {"$CTMcopy" == "" } { 2006563Sphk set f1 [open /dev/null] 2016777Sphk } else { 2027463Sphk set f1 [open "| ./ctm_scan $CTMcopy $CTMscan"] 2032926Sphk } 2042926Sphk 2056777Sphk puts "Doing CTMname $CTMname CTMnbr $CTMnbr$CTMsuff CTMdate $CTMdate" 2066563Sphk flush stdout 2076563Sphk exec sh -c "rm -f ${CTMtmp}.* ${CTMtmp}:*" >&@ stdout 2082886Sphk 2097463Sphk set f2 [open "| ./ctm_scan $CTMref $CTMscan"] 2102886Sphk 2116563Sphk set fo_del [open $CTMtmp.del w] 2126563Sphk set fo_rmdir [open $CTMtmp.rmdir w] 2136563Sphk set fo_mkdir [open $CTMtmp.mkdir w] 2146563Sphk set fo_files [open $CTMtmp.files w] 2155014Sphk 2166563Sphk set l1 "" 2176563Sphk set l2 "" 2185014Sphk 2196563Sphk while 1 { 2206563Sphk 2216563Sphk if {$l1 == ""} {gets $f1 l1} 2226563Sphk 2236563Sphk if {$l2 == ""} {gets $f2 l2} 2246563Sphk 2256563Sphk if {$l1 == "" && $l2 == ""} break 2266563Sphk 2276563Sphk set n1 [lindex $l1 1] 2286563Sphk set n2 [lindex $l2 1] 2296563Sphk 2306563Sphk if {[regexp $CTMdont /$n1]} { set l1 "" ; continue } 2316563Sphk if {[regexp $CTMdont /$n2]} { set l2 "" ; continue } 2326563Sphk 2336563Sphk # they're all the same... 2346563Sphk if {$l1 == $l2} { set l1 "" ; set l2 "" ; continue } 2356563Sphk 2366563Sphk if {$l1 == "" } { eval CTMadd $l2 ; set l2 "" ; continue } 2376563Sphk 2386563Sphk if {$l2 == "" } { eval CTMdel $l1 ; set l1 "" ; continue } 2396563Sphk 2406563Sphk # if the name is the same we're safe... 2416563Sphk if {$n1 == $n2} { 2426563Sphk eval CTMchg $l1 $l2 2436563Sphk set l1 "" 2446563Sphk set l2 "" 2456563Sphk continue 2466563Sphk } 2476563Sphk 2486563Sphk # To avoid this anomaly: 2496563Sphk # A - d src/gnu/lib/libreadline/readline/Attic 2506563Sphk # A 0 f src/gnu/lib/libreadline/readline/Attic/readline.h,v 2516563Sphk # A 0 f src/gnu/lib/libreadline/readline.c,v 2526563Sphk # D 0 f src/gnu/lib/libreadline/readline/readline.h,v 2536563Sphk # D 0 f src/gnu/lib/libreadline/readline.c,v 2546563Sphk # we have to make things somewhat complicated... 2556563Sphk 2566563Sphk # if they have the same number of components... 2576563Sphk set ll1 [llength [split $n1 /]] 2586563Sphk set ll2 [llength [split $n2 /]] 2596563Sphk if {$ll1 == $ll2} { 2606563Sphk if {$n1 < $n2 } { 2616563Sphk eval CTMdel $l1 ; set l1 "" ; continue 2626563Sphk } else { 2636563Sphk eval CTMadd $l2 ; set l2 "" ; continue 2646563Sphk } 2656563Sphk } 2666563Sphk if {$ll1 < $ll2} { 2676563Sphk eval CTMadd $l2 ; set l2 "" ; continue 2685014Sphk } else { 2696563Sphk eval CTMdel $l1 ; set l1 "" ; continue 2705014Sphk } 2715014Sphk } 2725014Sphk 2736563Sphk close $fo_del 2746563Sphk close $fo_rmdir 2756563Sphk close $fo_mkdir 2766563Sphk close $fo_files 2772886Sphk 2786563Sphk if {$damage > $max_damage} { 2796563Sphk puts "Too much damage: $damage deletes" 2806563Sphk exec sh -c "rm -f ${CTMtmp}.*" 2816788Sphk exec rm -f $CTMlock 2826563Sphk exit 0 2836563Sphk } 2842886Sphk 2856563Sphk if {!$changes} { 2866563Sphk puts "no changes" 2876563Sphk exec sh -c "rm -f ${CTMtmp}.*" 2886788Sphk exec rm -f $CTMlock 2896563Sphk exit 0 2906563Sphk } 2912886Sphk 2926563Sphk exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $CTMtmp.begin 2932886Sphk 2946563Sphk puts "Assembling delta" 2956563Sphk flush stdout 2966563Sphk set nm [format "%s.%04d%s" $CTMname $CTMnbr $CTMsuff] 2972886Sphk 2986777Sphk set fdout [open "| /sbin/md5 -p | gzip -9 > ${CTMtmp}:${nm}.gz" w] 2993112Sphk 3006563Sphk foreach i {begin del rmdir mkdir files} { 3016563Sphk exec cat $CTMtmp.$i >@$fdout 3026563Sphk } 3036563Sphk puts $fdout "CTM_END " nonewline 3046563Sphk close $fdout ; unset fdout 3053112Sphk 3066563Sphk exec sh -x -c "rm -f ${CTMtmp}.*" >&@ stdout 3075014Sphk 3086563Sphk if {$CTMtest} { 3096563Sphk puts "testing, stopping now." 3106788Sphk exec rm -f $CTMlock 3116563Sphk exit 0 3126563Sphk } 3136563Sphk if {$CTMapply} { 3146563Sphk puts "Applying delta" 3156563Sphk flush stdout 3166788Sphk exec echo now applying > $CTMlock 3176563Sphk exec sh -e -x -c "cd $CTMcopy ; $CTMSW/ctm -v -v -v ${CTMtmp}:${nm}.gz" >&@ stdout 3186788Sphk exec echo did apply > $CTMlock 3196563Sphk } 3206563Sphk puts "Moving delta" 3216563Sphk flush stdout 3226563Sphk exec mv ${CTMtmp}:${nm}.gz $CTMdest/.CTMtmp_${nm}.gz >&@ stdout 3236563Sphk exec mv $CTMdest/.CTMtmp_${nm}.gz $CTMdest/${nm}.gz >&@ stdout 3246788Sphk exec echo moved > $CTMlock 3256563Sphk 3266563Sphk if {$CTMmail != ""} { 3276563Sphk puts "Mailing delta" 3286563Sphk flush stdout 3296777Sphk exec $CTMSW/ctm_smail -m 100000 -c 3000000 $CTMdest/${nm}.gz $CTMmail >&@ stdout 3306563Sphk } 3316788Sphk exec echo mailed > $CTMlock 3326563Sphk 3336563Sphk # If we did an absolute delta: stop. 3346563Sphk if {$CTMsuff != ""} break 3356563Sphk 3366563Sphk # Make a absolute delta (!) every 100 deltas 3377463Sphk if {$CTMnbr == 0 || ($CTMnbr % 100)} break 3386563Sphk 3396563Sphk # Make an absolute delta too... 3406563Sphk set CTMref $CTMcopy 3416563Sphk set CTMsuff A 3426563Sphk set CTMcopy "" 3436563Sphk set CTMmail "" 3446563Sphk set CTMapply 0 3456777Sphk set CTMspecial 1 3467463Sphk exec rm -f $CTMlock 3475014Sphk} 3486563Sphkputs "done." 3496788Sphkexec rm -f $CTMlock 350