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