mkCTM revision 15702
115702Sphk#!/usr/local/bin/tclsh7.4 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 14115702Sphkexec sh -c "date -u '+%y%m%d%H%M%S $argv'" >> /home/ctm/log 1426563Sphksource $argv 1436563Sphk 1446563Sphkif {$CTMtmp == ""} { 1456563Sphk set CTMtmp $CTMSW/../tmp/${CTMname}_${CTMsuff} 1466563Sphk} 1476563Sphkif {$CTMcopy == ""} { 1486563Sphk set CTMcopy $CTMSW/../$CTMname 1496563Sphk} 1506563Sphkif {$CTMdest == ""} { 1516563Sphk set CTMdest $CTMSW/../CTM-pub/$CTMname 1526563Sphk} 1536563Sphk 1546788Sphk# Make sure we only run one at a time... 1556788Sphk 15615702Sphkset CTMlock Lck.${CTMname}.${CTMdate}.[pid] 1576788Sphkexec rm -f ${CTMlock} 1586788Sphkexec echo starting > ${CTMlock} 1597463Sphkif {[catch "exec ln $CTMlock LCK.$CTMname" a]} { 1606788Sphk puts "Not going, lock exists..." 1616788Sphk exec rm -f $CTMlock 1627463Sphk exit 0 1636788Sphk} 1646788Sphkexec rm -f $CTMlock 1656788Sphkset CTMlock LCK.$CTMname 1666788Sphk 1676563Sphkset CTMscratch ${CTMtmp}.tmp 1686563Sphk 1692886Sphkwhile 1 { 1706777Sphk if { ! $CTMspecial} { 1717463Sphk if {$CTMfirst} { 1727463Sphk set CTMnbr 0 1737463Sphk } else { 1747463Sphk set CTMnbr [lindex [exec cat $CTMcopy/.ctm_status] 1] 1757463Sphk } 1762886Sphk 1777463Sphk if {$CTMnbr > 0 && ![find_delta $CTMnbr]} { 1786563Sphk puts "$CTMname delta $CTMnbr doesn't exist..." 1796788Sphk exec rm -f $CTMlock 1806788Sphk exit 0 1816563Sphk } 1822886Sphk 1836563Sphk incr CTMnbr 1842886Sphk 1856563Sphk if {[find_delta $CTMnbr]} { 1866563Sphk puts "$CTMname delta $CTMnbr does already exist..." 1876788Sphk exec rm -f $CTMlock 1886563Sphk exit 0 1896563Sphk } 1902886Sphk 1916563Sphk set fo [open $CTMref/.ctm_status w] 1926563Sphk puts $fo "$CTMname $CTMnbr" 1936563Sphk close $fo 1946563Sphk incr changes -1 1953833Sphk 1966563Sphk } else { 1976563Sphk set CTMnbr [lindex [exec cat $CTMref/.ctm_status] 1] 1986777Sphk } 1996777Sphk 2006777Sphk if {"$CTMcopy" == "" } { 2016563Sphk set f1 [open /dev/null] 2026777Sphk } else { 2037463Sphk set f1 [open "| ./ctm_scan $CTMcopy $CTMscan"] 2042926Sphk } 2052926Sphk 2066777Sphk puts "Doing CTMname $CTMname CTMnbr $CTMnbr$CTMsuff CTMdate $CTMdate" 2076563Sphk flush stdout 2086563Sphk exec sh -c "rm -f ${CTMtmp}.* ${CTMtmp}:*" >&@ stdout 2092886Sphk 2107463Sphk set f2 [open "| ./ctm_scan $CTMref $CTMscan"] 2112886Sphk 2126563Sphk set fo_del [open $CTMtmp.del w] 2136563Sphk set fo_rmdir [open $CTMtmp.rmdir w] 2146563Sphk set fo_mkdir [open $CTMtmp.mkdir w] 2156563Sphk set fo_files [open $CTMtmp.files w] 2165014Sphk 2176563Sphk set l1 "" 2186563Sphk set l2 "" 2195014Sphk 2206563Sphk while 1 { 2216563Sphk 2226563Sphk if {$l1 == ""} {gets $f1 l1} 2236563Sphk 2246563Sphk if {$l2 == ""} {gets $f2 l2} 2256563Sphk 2266563Sphk if {$l1 == "" && $l2 == ""} break 2276563Sphk 2286563Sphk set n1 [lindex $l1 1] 2296563Sphk set n2 [lindex $l2 1] 2306563Sphk 2316563Sphk if {[regexp $CTMdont /$n1]} { set l1 "" ; continue } 2326563Sphk if {[regexp $CTMdont /$n2]} { set l2 "" ; continue } 2336563Sphk 2346563Sphk # they're all the same... 2356563Sphk if {$l1 == $l2} { set l1 "" ; set l2 "" ; continue } 2366563Sphk 2376563Sphk if {$l1 == "" } { eval CTMadd $l2 ; set l2 "" ; continue } 2386563Sphk 2396563Sphk if {$l2 == "" } { eval CTMdel $l1 ; set l1 "" ; continue } 2406563Sphk 2416563Sphk # if the name is the same we're safe... 2426563Sphk if {$n1 == $n2} { 2436563Sphk eval CTMchg $l1 $l2 2446563Sphk set l1 "" 2456563Sphk set l2 "" 2466563Sphk continue 2476563Sphk } 2486563Sphk 2496563Sphk # To avoid this anomaly: 2506563Sphk # A - d src/gnu/lib/libreadline/readline/Attic 2516563Sphk # A 0 f src/gnu/lib/libreadline/readline/Attic/readline.h,v 2526563Sphk # A 0 f src/gnu/lib/libreadline/readline.c,v 2536563Sphk # D 0 f src/gnu/lib/libreadline/readline/readline.h,v 2546563Sphk # D 0 f src/gnu/lib/libreadline/readline.c,v 2556563Sphk # we have to make things somewhat complicated... 2566563Sphk 2576563Sphk # if they have the same number of components... 2586563Sphk set ll1 [llength [split $n1 /]] 2596563Sphk set ll2 [llength [split $n2 /]] 2606563Sphk if {$ll1 == $ll2} { 2616563Sphk if {$n1 < $n2 } { 2626563Sphk eval CTMdel $l1 ; set l1 "" ; continue 2636563Sphk } else { 2646563Sphk eval CTMadd $l2 ; set l2 "" ; continue 2656563Sphk } 2666563Sphk } 2676563Sphk if {$ll1 < $ll2} { 2686563Sphk eval CTMadd $l2 ; set l2 "" ; continue 2695014Sphk } else { 2706563Sphk eval CTMdel $l1 ; set l1 "" ; continue 2715014Sphk } 2725014Sphk } 2735014Sphk 2746563Sphk close $fo_del 2756563Sphk close $fo_rmdir 2766563Sphk close $fo_mkdir 2776563Sphk close $fo_files 2782886Sphk 2796563Sphk if {$damage > $max_damage} { 2806563Sphk puts "Too much damage: $damage deletes" 28115702Sphk exec sh -c "rm -f ${CTMtmp}.*" 28215702Sphk exec rm -f $CTMlock 2836563Sphk exit 0 2846563Sphk } 2852886Sphk 2866563Sphk if {!$changes} { 2876563Sphk puts "no changes" 2886563Sphk exec sh -c "rm -f ${CTMtmp}.*" 2896788Sphk exec rm -f $CTMlock 2906563Sphk exit 0 2916563Sphk } 2922886Sphk 2936563Sphk exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $CTMtmp.begin 2942886Sphk 2956563Sphk puts "Assembling delta" 2966563Sphk flush stdout 2976563Sphk set nm [format "%s.%04d%s" $CTMname $CTMnbr $CTMsuff] 2982886Sphk 2996777Sphk set fdout [open "| /sbin/md5 -p | gzip -9 > ${CTMtmp}:${nm}.gz" w] 3003112Sphk 3016563Sphk foreach i {begin del rmdir mkdir files} { 3026563Sphk exec cat $CTMtmp.$i >@$fdout 3036563Sphk } 3046563Sphk puts $fdout "CTM_END " nonewline 3056563Sphk close $fdout ; unset fdout 3063112Sphk 30715702Sphk exec sh -c "rm -f ${CTMtmp}.*" >&@ stdout 3085014Sphk 3096563Sphk if {$CTMtest} { 3106563Sphk puts "testing, stopping now." 3116788Sphk exec rm -f $CTMlock 3126563Sphk exit 0 3136563Sphk } 3146563Sphk if {$CTMapply} { 3156563Sphk puts "Applying delta" 3166563Sphk flush stdout 3176788Sphk exec echo now applying > $CTMlock 31815702Sphk exec sh -e -c "cd $CTMcopy ; $CTMSW/ctm -v -v -v ${CTMtmp}:${nm}.gz" >&@ stdout 3196788Sphk exec echo did apply > $CTMlock 3206563Sphk } 3216563Sphk puts "Moving delta" 3226563Sphk flush stdout 3236563Sphk exec mv ${CTMtmp}:${nm}.gz $CTMdest/.CTMtmp_${nm}.gz >&@ stdout 3246563Sphk exec mv $CTMdest/.CTMtmp_${nm}.gz $CTMdest/${nm}.gz >&@ stdout 3256788Sphk exec echo moved > $CTMlock 3266563Sphk 3276563Sphk if {$CTMmail != ""} { 3286563Sphk puts "Mailing delta" 3296563Sphk flush stdout 3306777Sphk exec $CTMSW/ctm_smail -m 100000 -c 3000000 $CTMdest/${nm}.gz $CTMmail >&@ stdout 3316563Sphk } 3326788Sphk exec echo mailed > $CTMlock 3336563Sphk 3346563Sphk # If we did an absolute delta: stop. 3356563Sphk if {$CTMsuff != ""} break 3366563Sphk 3376563Sphk # Make a absolute delta (!) every 100 deltas 3387463Sphk if {$CTMnbr == 0 || ($CTMnbr % 100)} break 3396563Sphk 3406563Sphk # Make an absolute delta too... 3416563Sphk set CTMref $CTMcopy 3426563Sphk set CTMsuff A 3436563Sphk set CTMcopy "" 3446563Sphk set CTMmail "" 3456563Sphk set CTMapply 0 3466777Sphk set CTMspecial 1 3477463Sphk exec rm -f $CTMlock 3485014Sphk} 3496563Sphkputs "done." 3506788Sphkexec rm -f $CTMlock 351