mkCTM revision 6563
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
1336563Sphkset max_damage 100
1346563Sphk
1356563Sphkset damage 0
1366563Sphkset changes 0
1376563Sphk
1386563Sphksource $argv
1396563Sphk
1406563Sphkif {$CTMtmp == ""} {
1416563Sphk    set CTMtmp $CTMSW/../tmp/${CTMname}_${CTMsuff}
1426563Sphk}
1436563Sphkif {$CTMcopy == ""} {
1446563Sphk    set CTMcopy $CTMSW/../$CTMname
1456563Sphk}
1466563Sphkif {$CTMdest == ""} {
1476563Sphk    set CTMdest $CTMSW/../CTM-pub/$CTMname
1486563Sphk}
1496563Sphk
1506563Sphkset CTMscratch ${CTMtmp}.tmp
1516563Sphk
1522886Sphkwhile 1 {
1536563Sphk    if { "$CTMcopy" != "" } {
1546563Sphk	set CTMnbr [lindex [exec cat $CTMcopy/.ctm_status] 1]
1552886Sphk
1566563Sphk	if {![find_delta $CTMnbr]} {
1576563Sphk	    puts "$CTMname delta $CTMnbr doesn't exist..."
1586563Sphk	    # exit 0
1596563Sphk	}
1602886Sphk
1616563Sphk	incr CTMnbr
1622886Sphk
1636563Sphk	if {[find_delta $CTMnbr]} {
1646563Sphk	    puts "$CTMname delta $CTMnbr does already exist..."
1656563Sphk	    exit 0
1666563Sphk	}
1672886Sphk
1686563Sphk	set fo [open $CTMref/.ctm_status w]
1696563Sphk	puts $fo "$CTMname $CTMnbr"
1706563Sphk	close $fo
1716563Sphk	incr changes -1
1723833Sphk
1736563Sphk	set f1 [open "| ./ctm_scan $CTMcopy"]
1746563Sphk    } else {
1756563Sphk	set CTMnbr [lindex [exec cat $CTMref/.ctm_status] 1]
1766563Sphk	set f1 [open /dev/null]
1772926Sphk    }
1782926Sphk
1796563Sphk    puts "Doing CTMname $CTMname CTMnbr $CTMnbr CTMdate $CTMdate"
1806563Sphk    flush stdout
1816563Sphk    exec sh -c "rm -f ${CTMtmp}.* ${CTMtmp}:*" >&@ stdout
1822886Sphk
1836563Sphk    set f2 [open "| ./ctm_scan $CTMref"]
1842886Sphk
1856563Sphk    set fo_del   [open $CTMtmp.del w]
1866563Sphk    set fo_rmdir [open $CTMtmp.rmdir w]
1876563Sphk    set fo_mkdir [open $CTMtmp.mkdir w]
1886563Sphk    set fo_files [open $CTMtmp.files w]
1895014Sphk
1906563Sphk    set l1 ""
1916563Sphk    set l2 ""
1925014Sphk
1936563Sphk    while 1 {
1946563Sphk
1956563Sphk	if {$l1 == ""} {gets $f1 l1}
1966563Sphk
1976563Sphk	if {$l2 == ""} {gets $f2 l2}
1986563Sphk	
1996563Sphk	if {$l1 == "" && $l2 == ""} break
2006563Sphk
2016563Sphk	set n1 [lindex $l1 1]
2026563Sphk	set n2 [lindex $l2 1]
2036563Sphk
2046563Sphk	if {[regexp $CTMdont /$n1]} { set l1 "" ; continue }
2056563Sphk	if {[regexp $CTMdont /$n2]} { set l2 "" ; continue }
2066563Sphk
2076563Sphk	# they're all the same...
2086563Sphk	if {$l1 == $l2}  { set l1 "" ; set l2 "" ; continue }
2096563Sphk
2106563Sphk	if {$l1 == "" }   { eval CTMadd $l2 ; set l2 "" ; continue }
2116563Sphk
2126563Sphk	if {$l2 == "" }   { eval CTMdel $l1 ; set l1 "" ; continue }
2136563Sphk
2146563Sphk	# if the name is the same we're safe...
2156563Sphk	if {$n1 == $n2}  { 
2166563Sphk	    eval CTMchg $l1 $l2
2176563Sphk	    set l1 ""
2186563Sphk	    set l2 "" 
2196563Sphk	    continue 
2206563Sphk	}
2216563Sphk
2226563Sphk	# To avoid this anomaly:
2236563Sphk	# A -  d  src/gnu/lib/libreadline/readline/Attic
2246563Sphk	# A 0  f  src/gnu/lib/libreadline/readline/Attic/readline.h,v
2256563Sphk	# A 0  f  src/gnu/lib/libreadline/readline.c,v
2266563Sphk	# D 0  f  src/gnu/lib/libreadline/readline/readline.h,v
2276563Sphk	# D 0  f  src/gnu/lib/libreadline/readline.c,v
2286563Sphk	# we have to make things somewhat complicated...
2296563Sphk
2306563Sphk	# if they have the same number of components...
2316563Sphk	set ll1 [llength [split $n1 /]]
2326563Sphk	set ll2 [llength [split $n2 /]]
2336563Sphk	if {$ll1 == $ll2} {
2346563Sphk	    if {$n1 < $n2 } { 
2356563Sphk		eval CTMdel $l1 ; set l1 "" ; continue 
2366563Sphk	    } else {
2376563Sphk		eval CTMadd $l2 ; set l2 "" ; continue 
2386563Sphk	    }
2396563Sphk	} 
2406563Sphk	if {$ll1 < $ll2} {
2416563Sphk		eval CTMadd $l2 ; set l2 "" ; continue 
2425014Sphk	} else {
2436563Sphk		eval CTMdel $l1 ; set l1 "" ; continue 
2445014Sphk	}
2455014Sphk    }
2465014Sphk
2476563Sphk    close $fo_del
2486563Sphk    close $fo_rmdir
2496563Sphk    close $fo_mkdir
2506563Sphk    close $fo_files
2512886Sphk
2526563Sphk    if {$damage > $max_damage} {
2536563Sphk	puts "Too much damage: $damage deletes"
2546563Sphk	exec sh -c "rm -f ${CTMtmp}.*"
2556563Sphk	exit 0
2566563Sphk    }
2572886Sphk
2586563Sphk    if {!$changes} {
2596563Sphk	puts "no changes"
2606563Sphk	exec sh -c "rm -f ${CTMtmp}.*"
2616563Sphk	exit 0
2626563Sphk    }
2632886Sphk
2646563Sphk    exec echo CTM_BEGIN 2.0 $CTMname $CTMnbr $CTMdate $CTMprefix > $CTMtmp.begin
2652886Sphk
2666563Sphk    puts "Assembling delta"
2676563Sphk    flush stdout
2686563Sphk    set  nm [format "%s.%04d%s" $CTMname $CTMnbr $CTMsuff]
2692886Sphk
2706563Sphk    set fdmd5 [open "|/sbin/md5 >> $CTMtmp.end" w]
2716563Sphk    set fdout [open "| gzip -9 > ${CTMtmp}:${nm}.gz" w]
2723112Sphk
2736563Sphk    foreach i {begin del rmdir mkdir files} {
2746563Sphk	exec cat $CTMtmp.$i >@$fdmd5
2756563Sphk	exec cat $CTMtmp.$i >@$fdout
2766563Sphk    }
2776563Sphk    puts $fdmd5 "CTM_END " nonewline
2786563Sphk    close $fdmd5 ; unset fdmd5
2796563Sphk    puts $fdout "CTM_END " nonewline
2806563Sphk    flush $fdout
2816563Sphk    exec cat $CTMtmp.end >@$fdout
2826563Sphk    close $fdout ; unset fdout
2833112Sphk
2846563Sphk    exec sh -x -c "rm -f ${CTMtmp}.*" >&@ stdout
2855014Sphk
2866563Sphk    if {$CTMtest} {
2876563Sphk	puts "testing, stopping now."
2886563Sphk	exit 0
2896563Sphk    }
2906563Sphk    if {$CTMapply} {
2916563Sphk	    puts "Applying delta"
2926563Sphk	    flush stdout
2936563Sphk	    exec sh -e -x -c "cd $CTMcopy ; $CTMSW/ctm -v -v -v ${CTMtmp}:${nm}.gz" >&@ stdout
2946563Sphk    }
2956563Sphk    puts "Moving delta"
2966563Sphk    flush stdout
2976563Sphk    exec mv ${CTMtmp}:${nm}.gz $CTMdest/.CTMtmp_${nm}.gz >&@ stdout
2986563Sphk    exec mv $CTMdest/.CTMtmp_${nm}.gz $CTMdest/${nm}.gz >&@ stdout
2996563Sphk
3006563Sphk    if {$CTMmail != ""} {
3016563Sphk	puts "Mailing delta"
3026563Sphk	flush stdout
3036563Sphk	exec $CTMSW/ctm_smail -m 50000 -c 300000 $CTMdest/${nm}.gz $CTMmail >&@ stdout
3046563Sphk    }
3056563Sphk
3066563Sphk    # If we did an absolute delta: stop.
3076563Sphk    if {$CTMsuff != ""} break
3086563Sphk
3096563Sphk    # Make a absolute delta (!) every 100 deltas
3106563Sphk    if {$CTMnbr % 100} break
3116563Sphk
3126563Sphk    # Make an absolute delta too...
3136563Sphk    set CTMref $CTMcopy
3146563Sphk    set CTMsuff A
3156563Sphk    set CTMcopy ""
3166563Sphk    set CTMmail ""
3176563Sphk    set CTMapply 0
3185014Sphk}
3196563Sphkputs "done."
320