commit build_farm code from CVS to SVN
authormetze <metze@1e5ffdc8-eadd-0310-9daa-9cb4117fe24b>
Tue, 29 Jun 2004 08:49:48 +0000 (08:49 +0000)
committermetze <metze@1e5ffdc8-eadd-0310-9daa-9cb4117fe24b>
Tue, 29 Jun 2004 08:49:48 +0000 (08:49 +0000)
metze

git-svn-id: file:///home/svn/build-farm/trunk@2 1e5ffdc8-eadd-0310-9daa-9cb4117fe24b

86 files changed:
Isis.fns [new file with mode: 0644]
PCS1.fns [new file with mode: 0644]
README [new file with mode: 0644]
aegis.fns [new file with mode: 0644]
aix1.fns [new file with mode: 0644]
au2.fns [new file with mode: 0644]
belle.fns [new file with mode: 0644]
boiccu.fns [new file with mode: 0644]
build_test [new file with mode: 0755]
build_test.fns [new file with mode: 0644]
cat.fns [new file with mode: 0644]
cvslog.pl [new file with mode: 0755]
cyberone.fns [new file with mode: 0644]
echunga.fns [new file with mode: 0644]
flame.fns [new file with mode: 0644]
g6usr30.fns [new file with mode: 0644]
gc20.fns [new file with mode: 0644]
generic.fns [new file with mode: 0644]
gwen.fns [new file with mode: 0644]
history [new file with mode: 0755]
hpntc9I.fns [new file with mode: 0644]
insure.fns [new file with mode: 0644]
jarret.fns [new file with mode: 0644]
kimchi.fns [new file with mode: 0644]
l390vme1.fns [new file with mode: 0644]
m30.fns [new file with mode: 0644]
manhattan.fns [new file with mode: 0644]
manjra.fns [new file with mode: 0644]
medusa.fns [new file with mode: 0644]
mundroo.fns [new file with mode: 0644]
mungera.fns [new file with mode: 0644]
nessie-rh.fns [new file with mode: 0644]
pandemonium.fns [new file with mode: 0644]
paros.fns [new file with mode: 0644]
previn.fns [new file with mode: 0644]
quango.fns [new file with mode: 0644]
ringo.fns [new file with mode: 0644]
samba-s390.fns [new file with mode: 0644]
sco1.fns [new file with mode: 0644]
sco2.fns [new file with mode: 0644]
sid.fns [new file with mode: 0644]
smartserv1.fns [new file with mode: 0644]
sparc-sarge.fns [new file with mode: 0644]
sparc-sid.fns [new file with mode: 0644]
sparc-woody.fns [new file with mode: 0644]
spe190.fns [new file with mode: 0644]
sun1.fns [new file with mode: 0644]
superego.fns [new file with mode: 0644]
suse71i386.fns [new file with mode: 0755]
suse71ppc.fns [new file with mode: 0755]
svamp.fns [new file with mode: 0644]
tardis.fns [new file with mode: 0644]
taxi.fns [new file with mode: 0644]
us4.fns [new file with mode: 0644]
us5.fns [new file with mode: 0644]
vance.fns [new file with mode: 0644]
vlo.fns [new file with mode: 0644]
web/about.html [new file with mode: 0644]
web/build.pl [new file with mode: 0755]
web/compaq-testdrive.gif [new file with mode: 0644]
web/favicon.ico [new file with mode: 0644]
web/history.pm [new file with mode: 0644]
web/hpntc4m.html [new file with mode: 0644]
web/hpntc9i.html [new file with mode: 0644]
web/icon_hide_16.png [new file with mode: 0644]
web/icon_hide_24.png [new file with mode: 0644]
web/icon_unhide_16.png [new file with mode: 0644]
web/icon_unhide_24.png [new file with mode: 0644]
web/instructions.html [new file with mode: 0644]
web/insure.html [new file with mode: 0644]
web/robots.txt [new file with mode: 0644]
web/ropeable.html [new file with mode: 0644]
web/spe140.html [new file with mode: 0644]
web/spe141.html [new file with mode: 0644]
web/spe148.html [new file with mode: 0644]
web/spe158.html [new file with mode: 0644]
web/spe160.html [new file with mode: 0644]
web/spe161.html [new file with mode: 0644]
web/spe188.html [new file with mode: 0644]
web/spe190.html [new file with mode: 0644]
web/spe222.html [new file with mode: 0644]
web/svamp.html [new file with mode: 0644]
web/util.pm [new file with mode: 0644]
web/vmware.gif [new file with mode: 0644]
yowiee.fns [new file with mode: 0644]
yurok.fns [new file with mode: 0644]

diff --git a/Isis.fns b/Isis.fns
new file mode 100644 (file)
index 0000000..b6cf874
--- /dev/null
+++ b/Isis.fns
@@ -0,0 +1,10 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+
+#test_tree samba source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+config="" test_tree rsync . gcc
diff --git a/PCS1.fns b/PCS1.fns
new file mode 100644 (file)
index 0000000..71ffbe0
--- /dev/null
+++ b/PCS1.fns
@@ -0,0 +1,6 @@
+test_tree samba4 source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..8fe7109
--- /dev/null
+++ b/README
@@ -0,0 +1,15 @@
+This is the build system for build.samba.org
+
+tridge@samba.org, April 2001
+
+To set it up on a new box you need to do this:
+
+1) create an account on the box (I'll assume its called "build")
+2) copy over build_test to ~build/build_farm/
+3) put the right password in ~build/build_farm/.password
+4) arrange for ~build/build_farm/build_test to be run regularly
+   from cron
+5) add the host to build.pl on dp.samba.org
+6) create a HOSTNAME.fns file that defines what gets built on
+   build.samba.org
+
diff --git a/aegis.fns b/aegis.fns
new file mode 100644 (file)
index 0000000..259c01a
--- /dev/null
+++ b/aegis.fns
@@ -0,0 +1,10 @@
+export CFLAGS="-O -Wall"
+
+test_tree samba4 source gcc
+
+export config="--with-utmp --with-pam --with-quotas --with-smbmount"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
+
diff --git a/aix1.fns b/aix1.fns
new file mode 100644 (file)
index 0000000..953a525
--- /dev/null
+++ b/aix1.fns
@@ -0,0 +1,6 @@
+test_tree samba4 source cc
+
+export config="--with-utmp"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+config="" test_tree rsync . cc
diff --git a/au2.fns b/au2.fns
new file mode 100644 (file)
index 0000000..6a56930
--- /dev/null
+++ b/au2.fns
@@ -0,0 +1,13 @@
+test_tree samba4 source cc
+
+export config="--with-acl-support --with-utmp"
+export CFLAGS="-O -64"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+config="" test_tree rsync . cc
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+config="" test_tree rsync . gcc
diff --git a/belle.fns b/belle.fns
new file mode 100644 (file)
index 0000000..05f3649
--- /dev/null
+++ b/belle.fns
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5developer"
+
+test_tree samba source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
diff --git a/boiccu.fns b/boiccu.fns
new file mode 100644 (file)
index 0000000..ae11601
--- /dev/null
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
diff --git a/build_test b/build_test
new file mode 100755 (executable)
index 0000000..a188abb
--- /dev/null
@@ -0,0 +1,37 @@
+#!/bin/bash
+# this is the main build script for build.samba.org
+# it gets run on all the build boxes via cron
+
+# any errors get put in build.log
+
+# we used a fixed path that is a superset of the required paths.
+export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/opt/SUNWspro/bin:/usr/ccs/bin:/sbin:/usr/sbin:/usr/local/sbin
+
+# go to our main directory
+cd ~/build_farm || exit 1
+
+(
+
+    echo
+    date
+
+    # we only want the short name of the host - use cut for portability
+    host=`hostname | cut -d. -f1`
+
+    # make sure the password isn't readable by anyone
+    chmod 600 .password
+
+    # grab the latest versions of the scripts
+    rsync --timeout=200 -q -az samba.org::build_farm/*.fns .
+
+    # load general functions
+    . build_test.fns
+
+    if [ -f $host.fns ]; then
+      # load host specific functions
+      . $host.fns
+    else
+      . generic.fns
+    fi
+
+) >> build.log 2>&1
diff --git a/build_test.fns b/build_test.fns
new file mode 100644 (file)
index 0000000..f799b29
--- /dev/null
@@ -0,0 +1,443 @@
+# -*- mode: shell-script; sh-indentation: 8; indent-tabs-mode: t; -*-
+
+# build_farm -- distributed build/test architecture for samba, rsync, etc
+
+# Copyright (C) 2001 by Andrew Tridgell <tridge@samba.org>
+# Copyright (C) 2001 by Andrew Bartlett <abartlet@samba.org>
+# Copyright (C) 2001, 2003 by Martin Pool <mbp@samba.org>
+
+
+#############################
+# build a signature of a tree, used to see if we
+# need to rebuild 
+sum_tree() {
+        sum_tree_test_root=$1
+       sum_tree_tree=$2
+       sum_tree_testsuite=$3
+       sum_tree_sum=$4
+       find $sum_tree_test_root/$sum_tree_tree -type f -print | grep -v '.svn/' | xargs sum > $sum_tree_sum
+       sum build_test build_test.fns >> $sum_tree_sum
+
+       if [ -f "$host.fns" ]; then
+           sum $host.fns >> $sum_tree_sum
+       fi
+
+       if [ -d "$sum_tree_testsuite" ]; then
+           find $sum_tree_test_root/$sum_tree_testsuite -type f -print | grep -v '.svn/' | xargs sum >> $sum_tree_sum
+       fi
+}
+
+#############################
+# send the logs to the master site
+send_logs() {
+       if [ "$nologreturn" = "yes" ]; then
+               echo "skipping log transfer"
+       else
+               log="$1"
+               err="$2"
+               chmod 0644 "$log" "$err"
+               rsync -q --password-file=.password -atz --timeout=200 \
+                       "$log" "$err" $host@samba.org::build_farm_data/
+       fi
+}
+
+############################
+# fetch the latest copy of the tree
+fetch_tree() {
+       if [ "$norsync" = "yes" ]; then
+               echo "skipping tree transfer"
+       else
+               tree=$1
+               if rsync -q --partial --timeout=200 -az --delete --ignore-errors \
+                       samba.org::ftp/unpacked/$tree $test_root; then
+                       echo "transferred $tree OK"
+               else
+                       echo "transfer of $tree failed code $?"
+                       return 1
+               fi
+       fi
+       return 0
+}
+
+############################
+# grab a lock file. Not atomic, but close :)
+# tries to cope with NFS
+lock_file() {
+       lck="$1"
+       machine=`cat "$lck" 2> /dev/null | cut -d: -f1`
+       pid=`cat "$lck" 2> /dev/null | cut -d: -f2`
+
+       if [ -f "$lck" ] && 
+           ( [ $machine != $host ] || kill -0 $pid ) 2> /dev/null; then
+               echo "lock file $lck is valid for $machine:$pid"
+               return 1
+       fi
+       /bin/rm -f "$lck"
+       echo "$host:$$" > "$lck"
+       return 0
+}
+
+############################
+# unlock a lock file
+unlock_file() {
+       lck="$1"
+       /bin/rm -f "$lck"
+}
+
+############################
+# run make, and print trace
+do_make() {
+  if [ x$MAKE = x ] 
+  then
+    MAKE=make
+  fi 
+    
+  for t in $*; do
+    echo "$MAKE $t"
+    "$MAKE" "$t"
+    status=$?
+    if [ $status != 0 ]; then
+      return $status;
+    fi
+  done
+  return 0
+}      
+
+############################
+# configure the tree
+action_configure() {
+        if [ ! -x configure ]; then
+           ./autogen.sh
+       fi
+       echo "CFLAGS=$CFLAGS"
+       echo configure options: $config_and_prefix
+       echo CC="$compiler" ./configure $config_and_prefix
+       CC="$compiler"
+       export CC
+       ./configure $config_and_prefix
+       cstatus=$?
+       echo "CONFIGURE STATUS: $cstatus"
+       if [ $cstatus != 0 ]; then
+           echo "contents of config.log:"
+           cat config.log
+       fi
+       return $cstatus;
+}
+
+############################
+# build the tree
+action_build() {
+       case "$tree" in
+       samba4)
+               do_make proto everything
+               ;;
+       samba|samba_3_0)
+           do_make proto everything torture
+           ;;
+       samba_2_2)
+           do_make everything bin/smbtorture
+           ;;
+       *)
+           do_make all
+           ;;
+       esac
+
+       bstatus=$?
+       echo "BUILD STATUS: $bstatus"
+       return $bstatus
+}
+
+############################
+# install the tree
+action_install() {
+       if [ -d $prefix ]; then
+               if [ "$noclean" != "yes" ]; then
+                   rm -rf $prefix
+               fi
+       fi
+
+       do_make install
+       istatus=$?
+       echo "INSTALL STATUS: $istatus"
+       return $istatus;
+}
+
+############################
+# run each test, allow for reruns
+each_test() {
+           echo "--==--==--==--==--==--==--==--==--==--==--"
+           echo "Running test $test (level $loglevel stdout)" 
+           echo "--==--==--==--==--==--==--==--==--==--==--"
+           echo "--==--==--==--==--==--==--==--==--==--==--" >> $logfile
+           echo "Running test $test (level $loglevel log)"   >> $logfile
+           echo "--==--==--==--==--==--==--==--==--==--==--" >> $logfile
+           date
+
+           /bin/rm -rf $testdir
+           mkdir $testdir
+
+       case "$tree" in 
+       samba*)
+           /bin/rm -rf $prefix/lib
+           mkdir $prefix/lib
+           ;;
+        esac
+
+           ( 
+               cd $test_root/$tree/$testsuite || exit 1
+               echo "running tests in "`pwd`
+               echo "    test_root=$test_root"
+               echo "    tree=$tree"
+               echo "    testsuite=$testsuite"
+               export prefix
+               export host
+               export testdir
+               export test
+               export whoami
+               export loglevel
+               . $test.test 
+           )
+           tstatus=$?
+
+           echo "==========================================" 
+           echo "==========================================" >> $logfile
+
+           if [ $tstatus != 0 ]; then
+               FAILED_TESTS="$FAILED_TESTS $test"
+               echo "TEST FAILED: $test (status $tstatus)" 
+               echo "TEST FAILED: $test (status $tstatus)" >> $logfile
+           else
+               echo "TEST PASSED: $test" 
+               echo "TEST PASSED: $test" >> $logfile
+           fi
+
+           echo "==========================================" 
+           echo "==========================================" >> $logfile
+
+}
+
+#############################
+# do pre-test cleanup work for samba and samba_2_2 and samba_3_0
+# then run the tests
+action_test_samba() {
+       logfile="$prefix/var/log.smbd"
+
+       LIBSMB_PROG=$prefix/sbin/smbd
+       export LIBSMB_PROG
+
+       if [ \! -d "$prefix/var" ]
+       then
+           mkdir "$prefix/var"
+       fi
+
+       if [ -f "$logfile" ]
+       then
+           rm -f $logfile
+       fi
+
+       testdir="$prefix/testdir"
+
+       runlist_file="$test_root/$tree/$testsuite/runlist"
+       if [ ! -f "$runlist_file" ]; then
+               echo "No testsuite defined in $runlist_file"
+               return 0;
+       fi
+
+       # some special magic for transitioning across to cssified
+       # output
+       echo "*build_farm transition magic*"
+
+       . $test_root/$tree/$testsuite/runlist
+       testhost=TEST_$host
+#      testlist=${!testhost}
+       if [ "$testlist" = "" ]; then
+           testlist=$TEST_ALL
+       fi
+
+       tstatus=0
+       totalfailed=0
+       loglevel=1
+       for test in $testlist; do
+           each_test $test;
+           if [ $tstatus != 0 ]; then
+               totalfailed=`expr $totalfailed + 1`;
+               loglevel=10
+               each_test $test
+               loglevel=1
+           fi
+       done
+       echo "contents of $logfile:"
+       cat $logfile
+       echo "FAILED TESTS: $FAILED_TESTS"
+       echo "TEST STATUS: $totalfailed"
+       return $totalfailed
+}
+
+
+action_test_generic() {
+        CC="$compiler"
+       export CC
+       do_make installcheck
+       totalstatus=$?
+       echo "TEST STATUS: $totalstatus"
+       return "$totalstatus"
+}
+
+
+#############################
+# attempt some basic tests of functionaility
+# starting as basic as possible, and getting incresingly complex
+
+action_test() {
+       # Samba needs crufty code of its own for backward
+       # compatiblity.  I think a better way to do this in the future
+       # is to just call 'make installcheck'.
+       case "$tree" in
+       samba*)
+           action_test_samba
+           ;;
+       *)
+           action_test_generic
+           ;;
+       esac
+}
+
+###########################
+# do a test build of a particular tree
+test_tree() {
+       tree=$1
+       source=$2
+       compiler="$3"
+       shift
+       shift
+       shift
+
+       # limit our resource usage
+       ulimit -t 300
+       ulimit -m 50000
+
+       # Keep stuff private
+       umask 077
+
+       if [ -z "$test_root" ]; then
+               test_root=`pwd`
+       fi
+
+       log="build.$tree.$host.$compiler.log"
+       err="build.$tree.$host.$compiler.err"
+       sum="build.$tree.$host.$compiler.sum"
+       lck="$test_root/build.$tree.lck"
+
+       if ! lock_file "$lck"; then
+               return
+       fi
+
+       # pull the tree
+       if ! fetch_tree "$tree"; then
+           unlock_file "$lck"
+           return
+       fi
+
+       if [ ! $USER = "" ]; then
+           whoami=$USER
+       else 
+           if [ ! $LOGNAME = "" ]; then
+               whoami=$LOGNAME
+           else
+               whoami=build
+           fi
+       fi
+
+       prefix="$test_root/prefix"
+       if [ ! -d $prefix ]; then
+               mkdir $prefix
+       fi
+       prefix="$prefix/$tree"
+
+       case "$tree" in
+       samba|samba_3_0)
+           testsuite=testsuite/build_farm
+           ;;
+       samba_2_2)
+           testsuite=testsuite/build_farm
+           config="$config --with-codepagedir=$prefix/codepages"
+           ;;
+       *)
+           testsuite=testsuite
+           ;;
+       esac
+
+       config_and_prefix="$config --prefix=$prefix"
+
+       # see if we need to rebuild
+       sum_tree $test_root $tree $testsuite $sum
+       echo "CFLAGS=$CFLAGS $config_and_prefix" >> $sum
+
+       if cmp "$sum" "$sum.old" > /dev/null; then
+               echo "skip: $tree.$compiler nothing changed"
+               touch "$log" "$err"
+               send_logs "$log" "$err"
+               unlock_file "$lck"
+               return
+       fi
+
+       # we do need to rebuild - save the old sum
+       /bin/rm -f $sum.old
+       mv $sum $sum.old
+
+       actions="$*"
+       
+       if [ "$actions" = "" ]; then
+           actions="configure build install test"
+       fi
+
+       # start the build
+       (
+               uname -a
+
+               # some special magic for transitioning across to cssified
+               # output
+               echo "*build_farm transition magic*"
+
+               echo "building $tree with CC=$compiler on $host at "`date`
+               for action in $actions; do
+
+                   echo Running action $action
+
+                   date
+                   srcdir=$test_root/$tree/$source
+                   cd $srcdir
+                   export srcdir
+                   df .
+
+                   ( action_$action )
+                   action_status=$?
+                   
+                   if [ $action_status != 0 ]; then
+                       echo "ACTION FAILED: $action";
+                   else
+                       echo "ACTION PASSED: $action";
+                   fi
+                   
+                   if [ $action_status != 0 ]; then 
+                       break;
+                   fi
+
+               done
+
+               if [ "$noclean" = "yes" ]; then
+                   echo cleanup skipped!
+               else
+                   echo cleaning up
+                   do_make clean
+                   /bin/rm -rf $prefix
+               fi
+               date
+       ) > "$log" 2> "$err"
+       
+       # send the logs to the master site
+       send_logs "$log" "$err"
+
+       # cleanup
+       unlock_file "$lck"
+}
diff --git a/cat.fns b/cat.fns
new file mode 100644 (file)
index 0000000..b79e63a
--- /dev/null
+++ b/cat.fns
@@ -0,0 +1,10 @@
+export config="--with-acl-support --with-pam --with-utmp"
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba source gcc
+config="" test_tree samba4 source gcc
+config="" test_tree rsync . gcc
+config="" test_tree ccache . gcc
+
diff --git a/cvslog.pl b/cvslog.pl
new file mode 100755 (executable)
index 0000000..ec41c6a
--- /dev/null
+++ b/cvslog.pl
@@ -0,0 +1,274 @@
+#!/usr/bin/perl -w
+# This CGI script presents the results of the build_farm build
+# tridge@samba.org, April 2001
+
+use strict;
+use util;
+use POSIX;
+use Data::Dumper;
+use File::stat;
+use Date::Parse;
+
+####################################
+# parse a CVS date 
+sub cvs_parse_date($)
+{
+    my $s = shift;
+
+    if (! ($s =~ /@/)) {
+      return str2time($s);
+    }
+
+    if ($s =~ /(.*) (.*) ([0-9]+), ([0-9]+) @ ([0-9]+):([0-9]+)/) {
+       my $day = $1;
+       my $month = $2;
+       my $mday = $3;
+       my $year = $4;
+       my $hour = $5;
+       my $min = $6;
+       my (%months) = ('January' => 1, 'February' => 2, 'March' => 3, 'April' => 4,
+                       'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8, 'September' => 9,
+                       'October' => 10, 'November' => 11, 'December' => 12);
+       my $t = mktime(0, $min, $hour, $mday, $months{$month}-1, $year-1900);
+       return $t;
+    }
+
+    print "ERROR: bad date format $s\n";
+    return 0;
+}
+
+
+####################################
+# push an entry onto the array
+
+# FIXME: This incorrectly handles multiple commits with the same log
+# message.  The cvslog output only shows the revisions for the last
+# commit, but actually we want to either not coalesce, or show the
+# overall delta.
+
+sub push_entry($$$$$)
+{
+  my $entry = shift;
+  my $log = shift;
+  my $days = shift;
+  my $tree = shift;
+  my $tag = shift;
+  my $lastentry = $log->[$#{$log}];
+
+  if ($lastentry->{DATE} && $lastentry->{AUTHOR} &&
+      ($lastentry->{DATE} > $entry->{DATE}-600) &&
+      ($lastentry->{AUTHOR} eq $entry->{AUTHOR}) &&
+      ((!$lastentry->{TAG} && !$entry->{TAG}) ||
+       ($lastentry->{TAG} eq $entry->{TAG})) &&
+      ((!$lastentry->{MESSAGE} && !$entry->{MESSAGE}) ||
+       ($lastentry->{MESSAGE} eq $entry->{MESSAGE}))) {
+
+    if (exists $lastentry->{FILES}) {
+      $lastentry->{FILES} .= " $entry->{FILES}";
+    } else {
+      $lastentry->{FILES} = $entry->{FILES};
+    }
+
+    if (exists $lastentry->{ADDED}) {
+      $lastentry->{ADDED} .= " $entry->{ADDED}";
+    } else {
+      $lastentry->{ADDED} = $entry->{ADDED};
+    }
+
+    if (exists $lastentry->{REMOVED}) {
+      $lastentry->{REMOVED} .= " $entry->{REMOVED}";
+    } else {
+      $lastentry->{REMOVED} = $entry->{REMOVED};
+    }
+
+    if (exists $lastentry->{REVISIONS}) {
+           $lastentry->{REVISIONS} = {%{$lastentry->{REVISIONS}},%{$entry->{REVISIONS}}};
+    } else {
+           $lastentry->{REVISIONS} = $entry->{REVISIONS};
+    }
+  } else {
+    if (($entry->{DATE} > time() - $days*24*60*60) &&
+       ((!$entry->{TAG} && !$tag) || 
+        ($entry->{TAG} eq $tag)) &&
+       ($entry->{TREE} eq $tree)) {
+      push(@{$log}, $entry);
+    }
+  }
+  return $log;
+}
+
+####################################
+# return an array of logfile entries given a cvs log file. 
+# Only return entries newer than $days old
+sub cvs_parse($$$$)
+{
+    my $file = shift;
+    my $days = shift;
+    my $tree = shift;
+    my $tag = shift;
+    my $log;
+    my $entry;
+
+    open(FILE, "< $file");
+    while (<FILE>) {
+       my $line = $_;
+
+       # ignore separator lines
+       if ($line =~ /^[*]+/) { next; }
+
+       if ($line =~ /^Date:\s*(.*)/) {
+           if ($entry->{DATE}) {
+             $log = push_entry($entry, $log, $days, $tree, $tag);
+           }
+           $entry = {};
+           $entry->{DATE} = cvs_parse_date($1);
+           $entry->{DIR} = "";
+           next;
+       }
+
+       if ($line =~ /^Author:\s*(.*)/) {
+           $entry->{AUTHOR} = $1;
+           next;
+       }
+
+       if ($line =~ /^Update of (.*)/) {
+           $entry->{TREE} = $1;
+           if ($entry->{TREE} =~ /\/(data|home)\/cvs\/([^\/]*)\/?(.*)/) {
+               $entry->{TREE} = $2;
+               $entry->{DIR} = $3;
+               if ($entry->{DIR}) { $entry->{DIR} .= "/"; }
+           } elsif ($entry->{TREE} =~ /\/home\/tridge\/cvstest\/([^\/]*)\/?(.*)/) {
+               $entry->{TREE} = $1;
+               $entry->{DIR} = $2;
+               if ($entry->{DIR}) { $entry->{DIR} .= "/"; }
+           } else {
+               print "badly formed tree $entry->{TREE}\n";
+           }
+           if (! $entry->{DIR}) { $entry->{DIR} = ""; }
+           next;
+       }
+
+       if ($line =~ /^Modified Files:/) {
+           while (<FILE>) {
+               $line = $_;
+               if ($line =~ /^[*A-Z]/) { last; }
+
+               if ($line =~ /^\s*Tag: (.*)/) {
+                   $entry->{TAG} = $1;
+                   next;
+               }
+               
+               while ($line =~ /\s*([^\s]+)(.*)/) {
+                 if ($entry->{FILES}) { 
+                     $entry->{FILES} .= " $entry->{DIR}$1";
+                   } else {
+                       $entry->{FILES} = "$entry->{DIR}$1";
+                   }
+                 $line = $2;
+               }
+           }
+       }
+
+       if ($line =~ /^Added Files:/) {
+           while (<FILE>) {
+               $line = $_;
+               if ($line =~ /^[*A-Z]/) { last; }
+
+               if ($line =~ /^\s*Tag: (.*)/) {
+                   $entry->{TAG} = $1;
+                   next;
+               }
+               
+               while ($line =~ /\s*([^\s]+)(.*)/) {
+                   if ($entry->{ADDED}) { 
+                       $entry->{ADDED} .= " $entry->{DIR}$1";
+                   } else {
+                       $entry->{ADDED} = "$entry->{DIR}$1";
+                   }
+                   $line = $2;
+               }
+           }
+       }
+
+       if ($line =~ /^Removed Files:/) {
+           while (<FILE>) {
+               $line = $_;
+               if ($line =~ /^[*A-Z]/) { last; }
+
+               if ($line =~ /^\s*Tag: (.*)/) {
+                   $entry->{TAG} = $1;
+                   next;
+               }
+               
+               while ($line =~ /\s*([^\s]+)(.*)/) {
+                   if ($entry->{REMOVED}) { 
+                       $entry->{REMOVED} .= " $entry->{DIR}$1";
+                   } else {
+                       $entry->{REMOVED} = "$entry->{DIR}$1";
+                   }
+                   $line = $2;
+               }
+           }
+       }
+
+       if ($line =~ /^Log Message:/) {
+           while (<FILE>) {
+               $line = $_;
+               if ($line eq "****************************************\n") { last; }
+               if ($line =~ /^Revisions:/) { last; }
+               $entry->{MESSAGE} .= $line;
+           }
+       }
+
+       if ($line =~ /^Revisions:/) {
+           while (<FILE>) {
+               $line = $_;
+               if ($line =~ /^[*]/) { last; }
+               if ($line =~ /^\s*http/) { next; }
+               if ($line =~ /^\s*(.*?)\s*(NONE|[0-9][0-9.]*) => (NONE|[0-9][0-9.]*)/) { 
+                 my $file = "$entry->{DIR}$1";
+                 my $rev1 = $2;
+                 my $rev2 = $3;
+                 $entry->{REVISIONS}->{$file}->{REV1} = $rev1;
+                 $entry->{REVISIONS}->{$file}->{REV2} = $rev2;
+               }
+           }
+       }
+    }
+
+    if ($entry->{DATE}) {
+      $log = push_entry($entry, $log, $days, $tree, $tag);
+    }
+
+    close(FILE);
+
+    # cleanup the messages
+    for (my $line=0; $line <= $#{$log}; $line++) {
+       $entry = $log->[$line];
+       if ($entry->{MESSAGE}) {
+           while (chomp($entry->{MESSAGE})) { }
+       }
+    }
+    
+    return $log;
+}
+
+
+######################################
+# main program
+if ($#ARGV < 4) {
+    print "
+Usage: cvslog.pl <file> <days> <tree> <tag> <dest>
+}";
+    exit(1);
+}
+
+my $file = $ARGV[0];
+my $days = $ARGV[1];
+my $tree = $ARGV[2];
+my $tag =  $ARGV[3];
+my $dest = $ARGV[4];
+
+my $log = cvs_parse($ARGV[0], $days, $tree, $tag);
+
+util::SaveStructure($dest, $log);
diff --git a/cyberone.fns b/cyberone.fns
new file mode 100644 (file)
index 0000000..31150c7
--- /dev/null
@@ -0,0 +1 @@
+test_tree rsync . gcc
diff --git a/echunga.fns b/echunga.fns
new file mode 100644 (file)
index 0000000..7448301
--- /dev/null
@@ -0,0 +1,7 @@
+export CFLAGS="-O -Wall"
+test_tree samba4 source gcc
+export config="--with-utmp --with-pam"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/flame.fns b/flame.fns
new file mode 100644 (file)
index 0000000..143f3dc
--- /dev/null
+++ b/flame.fns
@@ -0,0 +1,8 @@
+export CFLAGS="-O -Wall"
+
+test_tree samba4 source gcc
+export config="--with-utmp"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/g6usr30.fns b/g6usr30.fns
new file mode 100644 (file)
index 0000000..e77012b
--- /dev/null
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-utmp --with-pam --with-quotas --with-smbmount"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/gc20.fns b/gc20.fns
new file mode 100644 (file)
index 0000000..eabab64
--- /dev/null
+++ b/gc20.fns
@@ -0,0 +1,7 @@
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/generic.fns b/generic.fns
new file mode 100644 (file)
index 0000000..71ffbe0
--- /dev/null
@@ -0,0 +1,6 @@
+test_tree samba4 source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/gwen.fns b/gwen.fns
new file mode 100644 (file)
index 0000000..4fb1718
--- /dev/null
+++ b/gwen.fns
@@ -0,0 +1,7 @@
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+test_tree samba4 source cc
+test_tree rsync . cc
+test_tree distcc . cc
+test_tree ccache . cc
+
diff --git a/history b/history
new file mode 100755 (executable)
index 0000000..d22881e
--- /dev/null
+++ b/history
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# This script converts log files produced by CVS into Perl DataDumper
+# files that can be easily loaded by the buildfarm web interface.
+
+cd $HOME/master || exit 1
+
+(
+
+./cvslog.pl /data/cvs/CVSROOT/samba.updates 60 samba "" cache/history.samba
+./cvslog.pl /data/cvs/CVSROOT/samba.updates 60 samba "SAMBA_2_2" cache/history.samba_2_2
+./cvslog.pl /data/cvs/CVSROOT/samba.updates 60 samba "SAMBA_3_0" cache/history.samba_3_0
+./cvslog.pl /data/cvs/CVSROOT/samba-docs.updates 60 samba-docs "" cache/history.samba-docs
+./cvslog.pl /data/cvs/CVSROOT/samba4.updates 60 samba4 "" cache/history.samba4
+./cvslog.pl /data/cvs/CVSROOT/rsync.updates 60 rsync "" cache/history.rsync
+./cvslog.pl /data/cvs/CVSROOT/distcc.updates 60 distcc "" cache/history.distcc
+./cvslog.pl /data/cvs/CVSROOT/ccache.updates 60 ccache "" cache/history.ccache
+
+) > history.log 2>&1
+
+
+
diff --git a/hpntc9I.fns b/hpntc9I.fns
new file mode 100644 (file)
index 0000000..1a5f6b1
--- /dev/null
@@ -0,0 +1,14 @@
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+test_tree samba4 source cc
+test_tree rsync . cc
+test_tree distcc . cc
+test_tree ccache . cc
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source cc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/insure.fns b/insure.fns
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/jarret.fns b/jarret.fns
new file mode 100644 (file)
index 0000000..b79e63a
--- /dev/null
@@ -0,0 +1,10 @@
+export config="--with-acl-support --with-pam --with-utmp"
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba source gcc
+config="" test_tree samba4 source gcc
+config="" test_tree rsync . gcc
+config="" test_tree ccache . gcc
+
diff --git a/kimchi.fns b/kimchi.fns
new file mode 100644 (file)
index 0000000..143f3dc
--- /dev/null
@@ -0,0 +1,8 @@
+export CFLAGS="-O -Wall"
+
+test_tree samba4 source gcc
+export config="--with-utmp"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/l390vme1.fns b/l390vme1.fns
new file mode 100644 (file)
index 0000000..755a6b3
--- /dev/null
@@ -0,0 +1,7 @@
+test_tree samba source gcc
+test_tree samba4 source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/m30.fns b/m30.fns
new file mode 100644 (file)
index 0000000..2dcd031
--- /dev/null
+++ b/m30.fns
@@ -0,0 +1,9 @@
+export CFLAGS="-D_POSIX_C_SOURCE=199506L -D_SYSV -D__VOS__"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+test_tree rsync . gcc
diff --git a/manhattan.fns b/manhattan.fns
new file mode 100644 (file)
index 0000000..28d3c66
--- /dev/null
@@ -0,0 +1,8 @@
+test_tree samba_2_2 source cc
+test_tree samba4 source cc
+
+config="--with-pam" test_tree samba_3_0 source cc
+
+test_tree rsync . cc
+MAKE=gmake test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/manjra.fns b/manjra.fns
new file mode 100644 (file)
index 0000000..05f3649
--- /dev/null
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5developer"
+
+test_tree samba source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
diff --git a/medusa.fns b/medusa.fns
new file mode 100644 (file)
index 0000000..ba90f01
--- /dev/null
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+export config="--with-quotas --with-smbmount"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+
diff --git a/mundroo.fns b/mundroo.fns
new file mode 100644 (file)
index 0000000..b79e63a
--- /dev/null
@@ -0,0 +1,10 @@
+export config="--with-acl-support --with-pam --with-utmp"
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba source gcc
+config="" test_tree samba4 source gcc
+config="" test_tree rsync . gcc
+config="" test_tree ccache . gcc
+
diff --git a/mungera.fns b/mungera.fns
new file mode 100644 (file)
index 0000000..9e1048d
--- /dev/null
@@ -0,0 +1,9 @@
+test_tree samba4 source gcc
+
+# (vance) added LDFLAGS=-bnoquiet Wed Jun 23 2004
+# to help trouble shoot the compile of 2_2
+export config="--with-utmp LDFLAGS=-bnoquiet"
+test_tree samba_2_2 source gcc
+export config=""
+test_tree samba_3_0 source gcc
+config="" test_tree rsync . gcc
diff --git a/nessie-rh.fns b/nessie-rh.fns
new file mode 100644 (file)
index 0000000..b4d459f
--- /dev/null
@@ -0,0 +1,9 @@
+export CFLAGS="-O -Wall"
+
+test_tree samba4 source gcc
+
+export config="--with-utmp --with-pam --with-syslog  --with-quotas --with-smbmount --with-netatalk --with-ssl --with-sslinc=/usr/include/openssl"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/pandemonium.fns b/pandemonium.fns
new file mode 100644 (file)
index 0000000..f2358da
--- /dev/null
@@ -0,0 +1,6 @@
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+test_tree samba4 source cc
+test_tree rsync . cc
+MAKE=gmake test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/paros.fns b/paros.fns
new file mode 100644 (file)
index 0000000..8078ecc
--- /dev/null
+++ b/paros.fns
@@ -0,0 +1,15 @@
+config="--with-pam --with-pam_smbpass --with-utmp"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+test_tree samba4 source cc
+config="" test_tree rsync . cc
+config="" test_tree distcc . cc
+config="" test_tree ccache . cc
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+config="" test_tree rsync . gcc
+config="" test_tree distcc . gcc
+config="" test_tree ccache . gcc
diff --git a/previn.fns b/previn.fns
new file mode 100644 (file)
index 0000000..b79e63a
--- /dev/null
@@ -0,0 +1,10 @@
+export config="--with-acl-support --with-pam --with-utmp"
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba source gcc
+config="" test_tree samba4 source gcc
+config="" test_tree rsync . gcc
+config="" test_tree ccache . gcc
+
diff --git a/quango.fns b/quango.fns
new file mode 100644 (file)
index 0000000..76ee2c2
--- /dev/null
@@ -0,0 +1,11 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-utmp --with-pam"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
diff --git a/ringo.fns b/ringo.fns
new file mode 100644 (file)
index 0000000..fd50c3b
--- /dev/null
+++ b/ringo.fns
@@ -0,0 +1,8 @@
+export CFLAGS="-O -Wall"
+
+test_tree samba4 source gcc
+export config="--with-utmp --with-pam"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/samba-s390.fns b/samba-s390.fns
new file mode 100644 (file)
index 0000000..c493be2
--- /dev/null
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/sco1.fns b/sco1.fns
new file mode 100644 (file)
index 0000000..25917f0
--- /dev/null
+++ b/sco1.fns
@@ -0,0 +1,10 @@
+export config="--with-utmp"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+config="" test_tree rsync . cc
+
+export CFLAGS="-O -Wall -Wno-comment"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+config="" test_tree rsync . gcc
diff --git a/sco2.fns b/sco2.fns
new file mode 100644 (file)
index 0000000..d2e3215
--- /dev/null
+++ b/sco2.fns
@@ -0,0 +1,10 @@
+export config="--with-utmp"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+config="" test_tree rsync . cc
+
+export CFLAGS="-g -O -Wall -Wno-comment"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+config="" test_tree rsync . gcc
diff --git a/sid.fns b/sid.fns
new file mode 100644 (file)
index 0000000..c493be2
--- /dev/null
+++ b/sid.fns
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/smartserv1.fns b/smartserv1.fns
new file mode 100644 (file)
index 0000000..71ffbe0
--- /dev/null
@@ -0,0 +1,6 @@
+test_tree samba4 source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/sparc-sarge.fns b/sparc-sarge.fns
new file mode 100644 (file)
index 0000000..c9ea98a
--- /dev/null
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5developer"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/sparc-sid.fns b/sparc-sid.fns
new file mode 100644 (file)
index 0000000..c9ea98a
--- /dev/null
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5developer"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/sparc-woody.fns b/sparc-woody.fns
new file mode 100644 (file)
index 0000000..9199587
--- /dev/null
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5developer"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/spe190.fns b/spe190.fns
new file mode 100644 (file)
index 0000000..9f7c77c
--- /dev/null
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5-developer"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/sun1.fns b/sun1.fns
new file mode 100644 (file)
index 0000000..a21bc3a
--- /dev/null
+++ b/sun1.fns
@@ -0,0 +1,15 @@
+test_tree samba4 source cc
+
+export config="--with-acl-support --with-pam --with-utmp"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+config="" test_tree rsync . cc
+config="" test_tree ccache . cc
+
+export CFLAGS="-O -Wall"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+config="" test_tree samba4 source gcc
+config="" test_tree rsync . gcc
+config="" test_tree ccache . gcc
+
diff --git a/superego.fns b/superego.fns
new file mode 100644 (file)
index 0000000..a5320a6
--- /dev/null
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+export MAKEFLAGS="-j 4"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-utmp --with-pam"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/suse71i386.fns b/suse71i386.fns
new file mode 100755 (executable)
index 0000000..247634d
--- /dev/null
@@ -0,0 +1,8 @@
+test_tree ccache . gcc
+test_tree distcc . gcc
+
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+test_tree rsync . cc
+test_tree samba4 source cc
+
diff --git a/suse71ppc.fns b/suse71ppc.fns
new file mode 100755 (executable)
index 0000000..247634d
--- /dev/null
@@ -0,0 +1,8 @@
+test_tree ccache . gcc
+test_tree distcc . gcc
+
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+test_tree rsync . cc
+test_tree samba4 source cc
+
diff --git a/svamp.fns b/svamp.fns
new file mode 100644 (file)
index 0000000..98a1f95
--- /dev/null
+++ b/svamp.fns
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-utmp --with-pam"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/tardis.fns b/tardis.fns
new file mode 100644 (file)
index 0000000..71ffbe0
--- /dev/null
@@ -0,0 +1,6 @@
+test_tree samba4 source gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree rsync . gcc
+test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/taxi.fns b/taxi.fns
new file mode 100644 (file)
index 0000000..ee7cd48
--- /dev/null
+++ b/taxi.fns
@@ -0,0 +1,4 @@
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+test_tree rsync . gcc
diff --git a/us4.fns b/us4.fns
new file mode 100644 (file)
index 0000000..84a1ccd
--- /dev/null
+++ b/us4.fns
@@ -0,0 +1,16 @@
+export PATH="/usr/freeware/bin:$PATH"
+
+test_tree samba4 source cc
+export config="--with-utmp --with-acl-support"
+test_tree samba_2_2 source cc
+test_tree samba_3_0 source cc
+config="" test_tree rsync . cc
+
+export CFLAGS="-O -Wall"
+
+config="" test_tree ccache . gcc
+MAKE=gmake config="" test_tree distcc . gcc
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+test_tree samba4 source gcc
+MAKEFLAGS="-k" config="" test_tree rsync . gcc
diff --git a/us5.fns b/us5.fns
new file mode 100644 (file)
index 0000000..fd50c3b
--- /dev/null
+++ b/us5.fns
@@ -0,0 +1,8 @@
+export CFLAGS="-O -Wall"
+
+test_tree samba4 source gcc
+export config="--with-utmp --with-pam"
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
+config="" test_tree rsync . gcc
diff --git a/vance.fns b/vance.fns
new file mode 100644 (file)
index 0000000..68fa97e
--- /dev/null
+++ b/vance.fns
@@ -0,0 +1,13 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --with-acl-support --enable-krb5developer"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+
diff --git a/vlo.fns b/vlo.fns
new file mode 100644 (file)
index 0000000..c4387dc
--- /dev/null
+++ b/vlo.fns
@@ -0,0 +1,6 @@
+test_tree samba_2_2 source gcc
+test_tree samba4 source gcc
+config="--with-pam" test_tree samba_3_0 source gcc
+test_tree rsync . gcc
+MAKE=gmake test_tree distcc . gcc
+test_tree ccache . gcc
diff --git a/web/about.html b/web/about.html
new file mode 100644 (file)
index 0000000..98e00c1
--- /dev/null
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
+<HTML>
+<HEAD><TITLE>samba.org build farm</TITLE></HEAD>
+<BODY bgcolor="white" TEXT="#000000" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
+<IMG ALT="Samba Banner" BORDER=0 ALIGN=MIDDLE SRC="http://www.samba.org/samba/images/samba_banner.gif">
+<br><p>
+
+<h2>About the build farm</h2>
+
+The samba.org build farm is designed to test the configuration and
+build of some projects hosted on samba.org in real time. Each host in
+the build farm builds each of the projects regularly (currently every
+15 minutes for some hosts) and uploads the results of the configure and
+build to the central site (build.samba.org) for display.
+
+<p>This allows team members to check on the build status on a wide
+variety of operating systems and architectures without the drudgery of
+logging into each machine after each CVS commit.
+
+<p>The build farm pulls the source code from the <a
+href="http://www.samba.org/ftp/unpacked/">unpacked CVS repository</a>
+and does a clean configure and build whenever a change is detected in
+the tree. The results shown give information on the status of the
+configure and build process, plus any error logs.
+
+<p>In future we plan on expanding the build farm to do basic runtime testing as well.
+
+<p>The author of the build farm is <a
+href="mailto:tridge@samba.org">Andrew Tridgell</a>. The source for the
+build farm is available in the build_farm cvs tree on the 
+<a href="http://pserver.samba.org/">samba.org CVS server</a>.
+
+<p>The build farm is now maintained by <a href="mailto:vance@samba.org">Vance
+Lankhaar</a>. He replaces long-time maintainer <a href="mailto:abartlet@samba.org">Andrew
+Bartlett</a>, allowing Andrew to focus more time on Samba development. </p>
+
+<p>If you have a machine that you wish to participate in our build farm
+then please read these <a href="instructions.html">instructions</a>.
+
+</BODY>
+</HTML>
diff --git a/web/build.pl b/web/build.pl
new file mode 100755 (executable)
index 0000000..490ec32
--- /dev/null
@@ -0,0 +1,990 @@
+#!/usr/bin/perl -w
+# This CGI script presents the results of the build_farm build
+#
+# Copyright (C) Andrew Tridgell <tridge@samba.org>     2001
+# Copyright (C) Andrew Bartlett <abartlet@samba.org>   2001
+# Copyright (C) Vance Lankhaar  <vance@samba.org>      2002-2004
+# Copyright (C) Martin Pool <mbp@samba.org>            2001
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#   
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#   
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+# TODO: Allow filtering of the "Recent builds" list to show
+# e.g. only broken builds or only builds that you care about.
+
+
+my $BASEDIR = "/home/build/master";
+my $CACHEDIR = "/home/build/master/cache";
+
+use strict qw{vars};
+use lib "$BASEDIR/web";
+use util;
+use history;
+use POSIX;
+use Data::Dumper;
+use CGI::Form;
+use File::stat;
+
+my $req = new CGI::Form;
+
+my $HEADCOLOR = "#a0a0e0";
+my $OLDAGE = 60*60*4;
+my $DEADAGE = 60*60*24*4;
+
+##############################################
+# this defines what it is possible to build 
+# and what boxes. Should be in a config file
+my $compilers = ['cc', 'gcc', 'gcc3', 'gcc-3.4', 'insure'];
+
+my (%hosts) = ('sun1' => "Solaris 8 UltraSparc", 
+              'Isis' => "Solaris 8 i386",
+              'gc20' => "Solaris 2.6 Sparc",
+#             'sco1' => "SysV 3.2 i386", 
+#             'sco2' => "UnixWare 7.1.0 i386", 
+
+              'aix1' => "AIX 4.3 PPC",
+              'mungera' => "AIX 5.2 IBM POWER4+",
+
+              'us4'  => "IRIX 6.5 MIPS", 
+              'au2'  => "IRIX 6.4 MIPS",
+
+              'smbo2000' => "IRIX 6.5 MIPS",
+
+              'wayne' => "RedHat 6.1 Sparc 10 (Kernel 2.2.18)",
+              'yowiee' => "RedHat 9.0 i386",
+#             'insure' => "RedHat 6.2 vmware (insure)",
+              'svamp' => "RedHat 7.0 i386",
+
+              'rhonwyn'  => "Debian Linux unstable i686",
+              'boiccu'  => "Debian Linux testing/unstable IA64",
+              'yurok' => "Debian Linux 3.0 stable i386",
+              'samba-s390' => "Debian Linux 3.0 stable s390",
+
+              'fusberta' => "Debian Linux 3.0 Alpha",
+
+              'sparc-woody' => "Debian Linux 3.0 (woody) Sparc64",
+              'sparc-sarge' => "Debian Linux sarge/testing Sparc64",
+              'sparc-sid' => "Debian Linux sid/unstable Sparc64",
+
+              'flame'  => "OpenBSD 3.0 Sparc",
+              'pandemonium' => "OpenBSD-current Sparc64",
+
+              'kimchi'  => "NetBSD 1.5 i386",
+
+              'gc8'  => "FreeBSD 3.3-RELEASE i386",
+              'gc4'  => "FreeBSD 4.3-STABLE i386",
+                  'gwalcmai' => "FreeBSD 5.2-RELEASE i586",
+
+              'manhattan' => "FreeBSD 4.8-RELEASE i386",
+
+              'sbf' => "FreeBSD 5.2.1 i386",
+              'smartserv1' => 'FreeBSD 5.2-CURRENT i386',
+
+              'woko'  => "Cray SV1 UNICOS 10.0.0.8",
+
+              'hpntc9I' => "HP-UX 11.11",
+              'gwen' => "HP-UX 11.11",
+
+              'g6usr30' => "RedHat 7.2 IBM s390 (Kernel 2.4.9)",
+
+              'belle' => "RedHat 8.0 i686",
+              'manjra' => "RedHat 8.0 i686",
+
+              'suse71ppc' => "SuSE 7.1 ppc gcc2.95.2",
+              'metze01' => "SuSE 8.2 i386 (athlon)",
+              'metze02' => "SuSE 7.3 i386 (PIII)",
+
+              'l390vme1' => "SuSE SLES 8 (S/390)",
+
+              'PCS1' => "SuSE Linux 9.1  Professional (i586)",
+
+              'cyberone' => "Cygwin i686 (MS WinXP Pro)",
+
+              'trip' => "Mandrake 9.2 i386 GCC 3.3.1",
+
+              'm30' => "Stratus VOS HP PA-RISC",
+              
+#                 'sprinkhaan' => "FreeBSD 4.7-STABLE i386",
+#                 'vlo' => "FreeBSD 5.0-RELEASE i386 #0",
+
+                  'jarret' => "Solaris 8 UltraSparc",
+                  'previn' => "Solaris 8 UltraSparc",
+                  'mundroo' => "Solaris 8 i386",
+                  'cat' => "Solaris 9 i386",
+
+#                 'paros' => "Solaris 9 UltraSparc",
+
+              'superego' => "Debian PPC/64 (Power3)",
+              'quango' => "Debian PPC/32 (Power3)",
+
+#Compaq Test Drive systems (discontinued, for now)
+#             'spe140' => "Debian Linux 2.2R6 i386",
+#             'spe141' => "RedHat Linux 7.3 i386",
+#             'spe148' => "RedHat Linux 7.1 Alpha (ev6)",
+#             'spe149' => "FreeBSD 4.6-RELEASE Alpha",
+#             'spe150' => "SUSE Linux 8.0 i386",
+#             'spe151' => "FreeBSD 4.6-RELEASE i386",
+#             'spe158' => "SuSE Linux 7.1 Alpha",
+#             'spe160' => "Slackware Linux 8.0 i386",
+#             'spe161' => "Debian Linux 2.2R6 Alpha",
+#             'spe188' => "Mandrake ProSuite 8.2 i386",
+#             'spe190' => "RedHat Linux 7.2 ia64",
+#             'spe223' => "Red Hat Linux Advanced Server 2.1AS i386",
+
+              'packetstorm' => "Slackware Linux 9.0 i386",
+
+              'tardis' => "Gentoo i686"
+              );
+
+
+my @hosts = sort { $hosts{$a} cmp $hosts{$b} } keys %hosts;
+
+my (%trees) = (
+#'samba' => "",
+              'samba' => "",
+              'samba4' => "",
+              'samba-docs' => "",
+              'samba_3_0' => "SAMBA_3_0",
+              'samba_2_2' => "SAMBA_2_2",
+              'rsync' => "",
+              'distcc' => "",
+              'ccache' => "");
+
+# this is automatically filled in
+my (@deadhosts) = ();
+
+###############################################
+# work out a URL so I can refer to myself in links
+my $myself = $req->self_url;
+if ($myself =~ /(.*)[?].*/) {
+    $myself = $1;
+}
+if ($myself =~ /http:\/\/.*\/(.*)/) {
+    $myself = $1;
+}
+
+$myself = "http://build.samba.org/";
+
+################################################
+# start CGI headers
+sub cgi_headers() {
+    print "Content-type: text/html\r\n";
+
+    util::cgi_gzip();
+
+    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
+<html>
+<head>
+<link rel="shortcut icon" href="/favicon.ico">
+<style type="text/css">  
+.entry {
+        background-color: #f0f0ff;
+        width: 80%;
+        text-align: left;
+        margin: 15px 0px 15px 0px;
+        border: 1px solid gray;
+}
+.entry TABLE {
+        width: 100%;
+}
+.entry TABLE TD {
+        vertical-align: top;
+       text-align: left;
+}
+.entry TABLE TH {
+        vertical-align: top;
+        width: 5em;
+        text-align: left;
+}
+
+TABLE.header {
+        border: 1px solid black;
+}
+TABLE.header TH {
+        font-weight: normal;
+        width: 12em;
+        text-align: left;
+}
+TABLE.header TD {
+}
+#log .name,.status {
+        display: inline;
+        font-weight: bold;
+        font-family: sans-serif;
+}
+#log .status.failed {
+        color: rgb(153, 0, 0);;
+}
+#log .status.passed {
+        color: rgb(0, 153, 0);
+}
+#log .output {
+        color: rgb(0, 0, 0);
+        font-family: monospace;
+}
+#log div.unit {
+        margin: 5px;
+        padding: 10px;
+        border: 2px solid black;
+}
+#log div.unit.passed {
+        background-color: rgb(180, 255, 180);
+}
+#log div.unit.failed {
+        background-color: rgb(255, 180, 180);
+}
+#log .unit.failed .output {
+        display: block;
+}
+#log .unit.passed .output {
+        display: none;
+}
+#log div.output#output-stderr-0 {
+        display: none;
+}
+
+#log img {
+        border: none;
+}
+#log a {
+        text-decoration: none;
+}
+#log a:hover,a:active {
+        text-decoration: underline;
+}
+</style>
+<script type="text/javascript">
+<!-- begin hiding from browsers
+
+
+function handle(name)
+{
+  action = document.getElementById("output-" + name);
+  img = document.getElementById("img-" + name);
+  old_src = img.getAttribute("src");
+
+  current_display = action.style.display;
+
+  // try to handle the case where the display is not explicitly set
+  if (current_display == "") {
+    if (action.currentStyle) { // ack, IE
+      current_display = action.currentStyle.display;
+    }
+    else if (document.defaultView.getComputedStyle) { // oooh, DOM
+      var style_list = document.defaultView.getComputedStyle(action, "");
+
+      // konqueor has getComputedStyle, but it does not work
+      if (style_list != null) {
+       current_display = style_list.getPropertyValue("display");
+      }
+    }
+    // in the case than neither works, we will do nothing. it just
+    // means the user will have to click twice to do the initial closing
+  }
+
+  if (current_display == "block") {
+    action.style.display = "none";
+    img.setAttribute("src", old_src.replace("hide", "unhide"));
+  }
+  else {
+    action.style.display = "block";
+    img.setAttribute("src", old_src.replace("unhide", "hide"));
+  }
+}
+// -- end hiding from browsers -->
+</script>
+<title>samba.org build farm</title></head>
+<body bgcolor="white" text="#000000" link="#0000EE" vlink="#551A8B" alink="#FF0000">
+<table border=0>
+<tr>
+<td><img alt="Samba Banner" border=0 align="left" src="http://www.samba.org/samba/images/samba_banner.gif"></td>
+<td>
+<ul>
+<li><a href="about.html">About the build farm</a>
+<li><a href="instructions.html">Adding a new machine</a>
+<li><a href="http://pserver.samba.org/">Samba CVS repository</a>
+<li><a href="http://www.samba.org/">Samba Web pages</a>
+</ul>
+</td>
+</tr>
+</table>
+';
+
+}
+
+################################################
+# start CGI headers for diffs
+sub cgi_headers_diff() {
+    print "Content-type: application/x-diff\r\n";
+    print "\n";
+}
+
+################################################
+# end CGI
+sub cgi_footers() {
+    print "</body>";
+    print "</html>\n";
+}
+
+################################################
+# print an error on fatal errors
+sub fatal($) {
+    my $msg=shift;
+    print "ERROR: $msg<br>\n";
+    cgi_footers();
+    exit(0);
+}
+
+##############################################
+# get the age of build from ctime
+sub build_age($$$)
+{
+    my $host=shift;
+    my $tree=shift;
+    my $compiler=shift;
+    my $file="build.$tree.$host.$compiler";
+    my $age = -1;
+    my $st;
+
+    if ($st = stat("$file.log")) {
+       $age = time() - $st->ctime;
+    }
+
+    return $age;
+}
+
+##############################################
+# get the svn revision of build
+sub build_revision($$$)
+{
+    my $host=shift;
+    my $tree=shift;
+    my $compiler=shift;
+    my $file="build.$tree.$host.$compiler";
+    my $log;
+    my $rev = "unknown";
+
+    my $st1 = stat("$file.log");
+    my $st2 = stat("$CACHEDIR/$file.revision");
+
+    if ($st1 && $st2 && $st1->ctime <= $st2->ctime) {
+           return util::FileLoad("$CACHEDIR/$file.revision");
+    }
+
+    $log = util::FileLoad("$file.log");
+
+    if (! $log) { return 0; }
+
+    if ($log =~ /BUILD REVISION:(.*)/) {
+       $rev = $1;
+    }
+
+    util::FileSave("$CACHEDIR/$file.revision", "$rev");
+
+    return $rev;
+}
+
+#############################################
+# get the overall age of a host 
+sub host_age($)
+{
+       my $host = shift;
+       my $ret = -1;
+       for my $compiler (@{$compilers}) {
+               for my $tree (sort keys %trees) {
+                       my $age = build_age($host, $tree, $compiler);
+                       if ($age != -1 && ($age < $ret || $ret == -1)) {
+                               $ret = $age;
+                       }
+               }
+       }
+       return $ret;
+}
+
+#############################################
+# show an age as a string
+sub red_age($)
+{
+       my $age = shift;
+       
+       if ($age > $OLDAGE) { 
+               return sprintf("<font color=\"#b00000\">%s</font>",  util::dhm_time($age));
+       }
+       return util::dhm_time($age);
+}
+
+
+##############################################
+# get status of build
+sub build_status($$$)
+{
+    my $host=shift;
+    my $tree=shift;
+    my $compiler=shift;
+    my $file="build.$tree.$host.$compiler";
+    my $cachefile="$CACHEDIR/build.$tree.$host.$compiler";
+    my $cstatus = "?";
+    my $bstatus = "?";
+    my $istatus = "?";
+    my $tstatus = "?";
+    my $sstatus = "/?";
+
+    my $log;
+    my $ret;
+
+    my $st1 = stat("$file.log");
+    my $st2 = stat("$cachefile.status");
+    
+    if ($st1 && $st2 && $st1->ctime <= $st2->ctime) {
+       return util::FileLoad("$cachefile.status");
+    }
+
+    $log = util::FileLoad("$file.log");
+
+    unlink("$CACHEDIR/FAILED.test.$tree.$host.$compiler");
+    if ($log =~ /TEST STATUS:(.*)/) {
+       if ($1 == 0) {
+           $tstatus = "<font color=green>ok</font>";
+       } else {
+           $tstatus = "<font color=red>$1</font>";
+           system("touch $CACHEDIR/FAILED.test.$tree.$host.$compiler");
+       }
+    }
+    
+    unlink("$CACHEDIR/FAILED.install.$tree.$host.$compiler");
+    if ($log =~ /INSTALL STATUS:(.*)/) {
+       if ($1 == 0) {
+           $istatus = "<font color=green>ok</font>";
+       } else {
+           $istatus = "<font color=red>$1</font>";
+           system("touch $CACHEDIR/FAILED.install.$tree.$host.$compiler");
+       }
+    }
+    
+    unlink("$CACHEDIR/FAILED.build.$tree.$host.$compiler");
+    if ($log =~ /BUILD STATUS:(.*)/) {
+       if ($1 == 0) {
+           $bstatus = "<font color=green>ok</font>";
+       } else {
+           $bstatus = "<font color=red>$1</font>";
+           system("touch $CACHEDIR/FAILED.build.$tree.$host.$compiler");
+       }
+    }
+
+    unlink("$CACHEDIR/FAILED.configure.$tree.$host.$compiler");
+    if ($log =~ /CONFIGURE STATUS:(.*)/) {
+       if ($1 == 0) {
+           $cstatus = "<font color=green>ok</font>";
+       } else {
+           $cstatus = "<font color=red>$1</font>";
+           system("touch $CACHEDIR/FAILED.configure.$tree.$host.$compiler");
+       }
+    }
+    
+    unlink("$CACHEDIR/FAILED.internalerror.$tree.$host.$compiler");
+    if ($log =~ /INTERNAL ERROR:(.*)/ || $log =~ /PANIC:(.*)/) {
+       $sstatus = "/<font color=red><b>PANIC</b></font>";
+       system("touch $CACHEDIR/FAILED.internalerror.$tree.$host.$compiler");
+    } else {
+       $sstatus = "";
+    }
+    
+    $ret = "<a href=\"$myself?function=View+Build&host=$host&tree=$tree&compiler=$compiler\">$cstatus/$bstatus/$istatus/$tstatus$sstatus</a>";
+
+
+    util::FileSave("$CACHEDIR/$file.status", $ret);
+
+    return $ret;
+}
+
+
+##############################################
+# get status of build
+sub err_count($$$)
+{
+    my $host=shift;
+    my $tree=shift;
+    my $compiler=shift;
+    my $file="build.$tree.$host.$compiler";
+    my $err;
+
+    my $st1 = stat("$file.err");
+    my $st2 = stat("$CACHEDIR/$file.errcount");
+
+    if ($st1 && $st2 && $st1->ctime <= $st2->ctime) {
+           return util::FileLoad("$CACHEDIR/$file.errcount");
+    }
+
+    $err = util::FileLoad("$file.err");
+
+    if (! $err) { return 0; }
+
+    my $ret = util::count_lines($err);
+
+    util::FileSave("$CACHEDIR/$file.errcount", "$ret");
+
+    return $ret;
+}
+
+
+
+##############################################
+# view build summary
+sub view_summary() {
+    my $i = 0;
+    my $list = `ls`;
+
+    my $cols = 2;
+
+    my $broken = 0;
+
+    # set up counters
+    my %broken_count;
+    my %panic_count;
+    my %host_count;
+
+    # zero broken and panic counters
+    for my $tree (sort keys %trees) {
+       $broken_count{$tree} = 0;
+       $panic_count{$tree} = 0;
+       $host_count{$tree} = 0;
+    }
+
+    #set up a variable to store the broken builds table's code, so we can output when we want
+    my $broken_table;
+
+    my $host_os;
+    my $last_host = "";
+
+    for my $host (@hosts) {
+       for my $compiler (@{$compilers}) {
+           for my $tree (sort keys %trees) {
+               my $status = build_status($host, $tree, $compiler);
+               my $age = build_age($host, $tree, $compiler);
+               if ($age != -1 && $age < $DEADAGE) {
+                   $host_count{$tree}++;
+               }
+               if ($age < $DEADAGE && $status =~ /color=red/) {
+                   if (!$broken) {
+                       $broken_table .= sprintf "<b>Currently broken builds:</b><p>\n";
+                       $broken_table .= sprintf "<table border=2><tr
+      bgcolor=\"$HEADCOLOR\"><th colspan=3>Target</th><th>Build&nbsp;Age</th><th>Status<br>config/build/install/test</th><th>warnings</th></tr>\n";
+                       $broken = 1;
+                   }
+                   $broken_count{$tree}++;
+                   if ($status =~ /PANIC/) {
+                       $panic_count{$tree}++;
+                   }
+                   my $warnings = err_count($host, $tree, $compiler);
+                   
+                   $broken_table .= sprintf "<tr>";
+                   
+                   $host_os = $hosts{$host};
+                   if ($host eq $last_host) {
+                       $broken_table .= sprintf "<td colspan=2></td>";
+                   } else {
+                       $broken_table .= sprintf "<td>$host_os</td><td><a href=\"#$host\">$host</a></td>";
+                   }
+                   $broken_table .= sprintf "<td><b>$tree</b>/$compiler</td><td align=right>" . red_age($age) . "</td><td align=center>$status</td><td align=center>$warnings</td></tr>\n";
+                   
+                   $last_host = $host;
+                   
+               }
+           }
+       }
+    }
+    
+    if ($broken) {
+       $broken_table .= sprintf("</table><p>\n");
+    }
+
+    print "<b>Build counts:</b><p>";
+    print "<table border=2 width=250><tr bgcolor=\"$HEADCOLOR\"><th>Tree</th><th>Total</th><th>Broken</th><th>Panic</th></tr>\n";
+    for my $tree (sort keys %trees) {
+       print "<tr><td>$tree</td><td align=center>$host_count{$tree}</td><td align=center>$broken_count{$tree}</td><td align=center>";
+       if ($panic_count{$tree}) {
+           print "<font color=red><b>$panic_count{$tree}</b></font>";
+       } else {
+           print "0";
+       }
+       print "</td></tr>\n";
+    }
+    print "</table><p>\n";
+
+
+    print $broken_table;
+
+    print "<b>Build summary:</b>\n\n";
+    
+    print '<table border=0><tr>';
+    for my $host (@hosts) {
+       # make sure we have some data from it
+       if (! ($list =~ /$host/)) { print "\n<!-- skipping $host --!>\n"; next; }
+       
+       if ($i == $cols) {
+           $i = 0;
+           print "</tr><tr>";
+       }
+
+       my $row = 0;
+       
+       for my $compiler (@{$compilers}) {
+           for my $tree (sort keys %trees) {
+               my $age = build_age($host, $tree, $compiler);
+               my $warnings = err_count($host, $tree, $compiler);
+               if ($age != -1 && $age < $DEADAGE) {
+                   my $status = build_status($host, $tree, $compiler);
+                   if ($row == 0) {
+                       print "<td valign=top><br><b><a name=\"$host\">$host</a> - $hosts{$host}</b><br><table border=2>
+<tr bgcolor=\"$HEADCOLOR\"><th>Target</th><th>Build&nbsp;Age</th><th>Status<br>config/build<br>install/test</th><th>warnings</th></tr>
+";
+                   }
+                   print "<tr align=center><td align=left><b>$tree</b>/$compiler</td><td align=right>" . red_age($age) . "</td><td>$status</td><td>$warnings</td></tr>\n";
+                   $row++;
+               }
+           }
+       }
+       if ($row != 0) {
+           print "</table></td>\n";
+           $i++;
+       } else {
+           push(@deadhosts, $host);
+       }
+    }
+    print '</tr></table>';
+
+    draw_dead_hosts(@deadhosts);
+}
+
+##############################################
+# Draw the "recent builds" view
+
+sub view_recent_builds() {
+    my $i = 0;
+    my $list = `ls`;
+
+    my $cols = 2;
+
+    my $broken = 0;
+
+    my $host_os;
+    my $last_host = "";
+    my @all_builds = ();
+    my $tree=$req->param("tree");
+
+    # Convert from the DataDumper tree form to an array that 
+    # can be sorted by time.
+
+    for my $host (@hosts) {
+      for my $compiler (@{$compilers}) {
+         my $status = build_status($host, $tree, $compiler);
+         my $age = build_age($host, $tree, $compiler);
+         my $revision = build_revision($host, $tree, $compiler);
+         push @all_builds, [$age, $hosts{$host}, "<a href=\"$myself?function=Summary&host=$host&tree=$tree&compiler=$compiler#$host\">$host</a>", $compiler, $tree, $status, $revision]
+               unless $age == -1 or $age >= $DEADAGE;
+      }
+  }
+
+  @all_builds = sort {$$a[0] <=> $$b[0]} @all_builds;
+  
+
+    print "<h2>Recent builds of $tree</h2>";
+    print '<table border=2>';
+    print "<tr bgcolor=\"$HEADCOLOR\">";
+    print "<th>Age</th>";
+    print "<th>Revision</th>";
+    print "<th colspan=4>Target</th>";
+    print "<th>Status</th>";
+    print "</tr>\n";
+
+    for my $build (@all_builds) {
+       my $age = $$build[0];
+       my $rev = $$build[6];
+       printf "<tr>";
+       print "<td>" .
+       util::dhm_time($age)."<td>";            # goes straight to stdout
+       print $rev."<td>";
+       print join "<td>", @$build[4, 1, 2, 3, 5];
+       print "</tr>\n";
+    }
+    print "</table>\n";
+}
+
+
+##############################################
+# Draw the "dead hosts" table
+sub draw_dead_hosts() {
+    my @deadhosts = @_;
+    print "<br><b>Dead Hosts:</b><br>\n";
+    print '<table border=2><tr>';
+    print "<tr bgcolor=\"$HEADCOLOR\"><th>Host</th><th>OS</th><th>Min Age</th></tr>
+";
+    for my $host (@deadhosts) {
+       my $age = host_age($host);
+       printf("<tr><td>$host</td><td>$hosts{$host}</td><td align=right>%s</td>\n", util::dhm_time($age));
+    }    
+    print "</table>\n";
+}
+
+
+##############################################
+# view one build in detail
+sub view_build() {
+    my $host=$req->param("host");
+    my $tree=$req->param("tree");
+    my $compiler=$req->param("compiler");
+    my $file="build.$tree.$host.$compiler";
+    my $log;
+    my $err;
+    my $uname="";
+    my $cflags="";
+    my $config="";
+    my $age = build_age($host, $tree, $compiler);
+    my $rev = build_revision($host, $tree, $compiler);
+    my $status = build_status($host, $tree, $compiler);
+
+    util::InArray($host, [keys %hosts]) || fatal("unknown host");
+    util::InArray($compiler, $compilers) || fatal("unknown compiler");
+    util::InArray($tree, [sort keys %trees]) || fatal("unknown tree");
+
+    $log = util::FileLoad("$file.log");
+    $err = util::FileLoad("$file.err");
+    
+    if ($log) {
+       $log = util::cgi_escape($log);
+
+       if ($log =~ /(.*)/) { $uname=$1; }
+       if ($log =~ /CFLAGS=(.*)/) { $cflags=$1; }
+       if ($log =~ /configure options: (.*)/) { $config=$1; }
+    }
+
+    if ($err) {
+       $err = util::cgi_escape($err);
+    }
+
+    print util::FileLoad("../web/$host.html");
+
+    print "
+<table>
+<tr><td>Host:</td><td><a href=\"$myself?function=Summary&host=$host&tree=$tree&compiler=$compiler#$host\">$host</a> - $hosts{$host}</td></tr>
+<tr><td>Uname:</td><td>$uname</td></tr>
+<tr><td>Tree:</td><td>$tree</td></tr>
+<tr><td>Build Revision:</td><td>" . $rev . "</td></tr>
+<tr><td>Build age:</td><td>" . red_age($age) . "</td></tr>
+<tr><td>Status:</td><td>$status</td></tr>
+<tr><td>Compiler:</td><td>$compiler</td></tr>
+<tr><td>CFLAGS:</td><td>$cflags</td></tr>
+<tr><td>configure options:  </td><td>$config</td></tr>
+</table>
+";
+
+    # check the head of the output for our magic string 
+    my $prettyPrintableLogs = ((substr $log, 0, 500) =~ /\*build_farm transition magic\*/);
+
+    if ($prettyPrintableLogs) {
+
+    print "<div id=\"log\">\n";
+    print "<div id=\"actionList\">\n";
+    # These can be pretty wide -- perhaps we need to 
+    # allow them to wrap in some way?
+    if ($err eq "") {
+       print "<b>No error log available</b><br>\n";
+    } else {
+       print "<h2>Error log:</h2>\n";
+       print make_action_html("stderr", $err, "stderr-0");;
+    }
+
+    if ($log eq "") {
+       print "<b>No build log available</b><br>\n";
+    } else {
+       print "<h2>Build log:</h2>\n";
+       print_log_pretty($log);
+    }
+
+    print "<p><small>Some of the above icons derived from the <a href=\"http://www.gnome.org\">Gnome Project</a>'s stock icons.</p>";
+    print "</div>\n";
+    print "</div>\n";
+    }
+    else {
+    if ($err eq "") {
+       print "<b>No error log available</b><br>\n";
+    } else {
+       print "<h2>Error log:</h2>\n";
+       print "<tt><pre>" . join('', $err) . "</pre></tt>\n";
+    }
+    if ($log eq "") {
+       print "<b>No build log available</b><br>\n";
+    }
+    else {
+       print "<h2>Build log:</h2>\n";
+       print "<tt><pre>" . join('', $log) . "</pre></tt><p>\n";
+      }
+    }
+    print "</body>\n";
+}
+
+##############################################
+# prints the log in a visually appealing manner
+sub print_log_pretty() {
+  my $log = shift;
+
+
+  # do some pretty printing for the actions
+  my $id = 1;
+  $log =~ s{   Running\ action\s+([\w\-]+)
+              (.*?)
+              ACTION\ (PASSED|FAILED):\ ([\w\-]+)
+            }{make_action_html($1, $2, $id++, $3)}exgs;
+  
+  $log =~ s{
+             --==--==--==--==--==--==--==--==--==--==--.*?
+             Running\ test\ ([\w-]+)\ \(level\ (\d+)\ (\w+)\).*?
+             --==--==--==--==--==--==--==--==--==--==--
+              (.*?)
+             ==========================================.*?
+             TEST\ (FAILED|PASSED):(\ \(status\ (\d+)\))?.*?
+             ==========================================\s+
+            }{make_test_html($1, $4, $id++, $5)}exgs;
+
+
+       print join('', $log) . "\n";
+}
+
+##############################################
+# generate html for a test section
+sub make_test_html {
+  my $name = shift;
+  my $output = shift;
+  my $id = shift;
+  my $status = shift;
+
+  my $return =  "</pre>" . # don't want the pre openned by action affecting us
+               "<div class=\"test unit \L$status\E\" id=\"test-$id\">" .
+                "<a href=\"javascript:handle('$id');\">" .
+                 "<img id=\"img-$id\" src=\"";
+  if (defined $status && $status eq "PASSED") {
+    $return .= "icon_unhide_16.png";
+  }
+  else {
+    $return .= "icon_hide_16.png";
+  }
+  $return .= "\"> " .
+                 "<div class=\"test name\">$name</div> " .
+                "</a> " .
+               "<div class=\"test status \L$status\E\">$status</div>" .
+               "<div class=\"test output\" id=\"output-$id\">" .
+                "<pre>$output</pre>" .
+               "</div>" .
+              "</div>" .
+              "<pre>";    # open the pre back up
+              
+  return $return;
+}
+
+##############################################
+# generate html for an action section
+sub make_action_html {
+
+  my $name = shift;
+  my $output = shift;
+  my $id = shift;
+  my $status = shift;
+  my $return = "<div class=\"action unit \L$status\E\" id=\"action-$id\">" .
+                "<a href=\"javascript:handle('$id');\">" .
+                 "<img id=\"img-$id\" src=\"";
+
+  if (defined $status && ($status =~ /failed/i)) {
+    $return .= 'icon_hide_24.png';
+  }
+  else {
+    $return .= 'icon_unhide_24.png';
+  }
+
+  $return .= "\"> " .
+                  "<div class=\"action name\">$name</div>" .
+                "</a> ";
+
+  if (defined $status) {
+    $return .= "<div class=\"action status \L$status\E\">$status</div>";
+  }
+
+  $return .= "<div class=\"action output\" id=\"output-$id\">" .
+                 "<pre>Running action $name$output ACTION $status: $name</pre>" .
+                "</div>".
+               "</div>";
+
+  return $return
+}
+
+##############################################
+# main page
+sub main_menu() {
+    print $req->startform("GET");
+    print $req->popup_menu(-name=>'host',
+                          -values=>\@hosts,
+                          -labels=>\%hosts);
+    print $req->popup_menu("tree", [sort keys %trees]);
+    print $req->popup_menu("compiler", $compilers);
+    
+    print $req->submit('function', 'View Build');
+    print "&nbsp;&nbsp;" . $req->submit('function', 'Recent Checkins');
+    print "&nbsp;&nbsp;" . $req->submit('function', 'Summary');
+    print "&nbsp;&nbsp;" . $req->submit('function', 'Recent Builds');
+
+    print $req->endform();
+}
+
+###############################################
+# display top of page
+sub page_top() {
+    cgi_headers();
+    chdir("$BASEDIR/data") || fatal("can't change to data directory");
+    main_menu();
+}
+###############################################
+# main program
+
+if (defined $req->param("function")) {
+    my $fn_name = $req->param("function");
+    if ($fn_name eq "View Build") {
+       page_top();
+       view_build();
+       cgi_footers();
+    } elsif ($fn_name eq "Recent Builds") {
+       page_top();
+       view_recent_builds();
+       cgi_footers();
+    } elsif ($fn_name eq "Recent Checkins") {
+       page_top();
+       history::cvs_history($req->param('tree'));
+       cgi_footers();
+    } elsif ($fn_name eq "diff") {
+       page_top();
+       history::cvs_diff($req->param('author'), $req->param('date'), $req->param('tree'), "html");
+       cgi_footers();
+    } elsif ($fn_name eq "text_diff") {
+       cgi_headers_diff();
+       chdir("$BASEDIR/data") || fatal("can't change to data directory");      
+       history::cvs_diff($req->param('author'), $req->param('date'), $req->param('tree'), "text");     
+    } else {
+       page_top();
+       view_summary();
+       cgi_footers();
+    }
+} else {
+    page_top();
+    view_summary();
+    cgi_footers();
+}
+
diff --git a/web/compaq-testdrive.gif b/web/compaq-testdrive.gif
new file mode 100644 (file)
index 0000000..77762b6
Binary files /dev/null and b/web/compaq-testdrive.gif differ
diff --git a/web/favicon.ico b/web/favicon.ico
new file mode 100644 (file)
index 0000000..ef903ba
Binary files /dev/null and b/web/favicon.ico differ
diff --git a/web/history.pm b/web/history.pm
new file mode 100644 (file)
index 0000000..8d9a3a4
--- /dev/null
@@ -0,0 +1,344 @@
+# Copyright (C) Andrew Tridgell <tridge@samba.org>     2001
+# Copyright (C) Martin Pool <mbp@samba.org>            2003
+# script to show recent checkins in cvs
+
+package history;
+
+my $BASEDIR = "/home/build/master";
+my $HISTORYDIR = "/home/build/master/cache";
+my $TIMEZONE = "PST";
+my $TIMEOFFSET = 0;
+
+use strict qw{vars};
+use util;
+use POSIX;
+use Data::Dumper;
+use CGI::Form;
+use File::stat;
+
+my $req = new CGI::Form;
+
+my $HEADCOLOR = "#a0a0e0";
+my $CVSWEB_BASE = "http://pserver.samba.org/cgi-bin/cvsweb";
+
+my (%tree_base) = ('samba' => "samba",
+                  'samba_2_2' => "samba",
+                  'samba_3_0' => "samba",
+                  'samba-docs' => "samba-docs",
+                  'samba4' => "samba4",
+                  'rsync' => "rsync",
+                  'distcc' => 'distcc',
+                  'ccache' => 'ccache');
+
+my $unpacked_dir = "/home/ftp/pub/unpacked";
+
+###############################################
+# work out a URL so I can refer to myself in links
+my $myself = $req->self_url;
+if ($myself =~ /(.*)[?].*/) {
+    $myself = $1;
+}
+if ($myself =~ /http:\/\/.*\/(.*)/) {
+    $myself = $1;
+}
+
+$myself = "http://build.samba.org/";
+
+################################################
+# start CGI headers
+sub cgi_headers() {
+    print "Content-type: text/html\r\n";
+
+    util::cgi_gzip();
+
+    print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
+<html>
+<head><title>recent checkins</title></head>
+<body bgcolor="white" text="#000000" link="#0000EE" vlink="#551A8B" alink="#FF0000">
+';
+
+}
+
+################################################
+# end CGI
+sub cgi_footers() {
+    print "</body>";
+    print "</html>\n";
+}
+
+################################################
+# print an error on fatal errors
+sub fatal($) {
+    my $msg=shift;
+    print "ERROR: $msg<br>\n";
+    cgi_footers();
+    exit(0);
+}
+
+
+###############################################
+# pretty up a cvs diff -u
+sub cvs_pretty($)
+{
+    my $diff = shift;
+    my $ret = "";
+    my @lines = split(/$/m, $diff);
+
+    my (%colors) = (
+                   '^diff.*' => 'red',
+                   '^=.*' => 'blue',
+                   '^Index:.*' => 'blue',
+                   '^\-.*' => '#a00000',
+                   '^\+.*' => '#00a000'
+                   );
+
+    for (my $i=0; $i <= $#lines; $i++) {
+       my $line = $lines[$i];
+
+       for my $r (keys %colors) {
+           if ($line =~ /$r/m) {
+               $line = "<font color=\"$colors{$r}\">$line</font>";
+               last;
+           }
+       }
+       $ret .= $line;
+    }
+    return $ret;
+}
+
+sub cvsweb_paths($$)
+{
+    my $tree = shift;
+    my $paths = shift;
+    my $ret = "";
+    while ($paths =~ /\s*([^\s]+)(.*)/) {
+       $ret .= "<a href=\"$CVSWEB_BASE/$tree_base{$tree}/$1\">$1</a> ";
+       $paths = $2;
+    }
+    
+    return $ret;
+}
+
+#############################################
+# show one row of history table
+sub history_row($$)
+{
+    my $entry = shift;
+    my $tree = shift;
+    my $msg = util::cgi_escape($entry->{MESSAGE});
+    my $t = POSIX::asctime(POSIX::gmtime($entry->{DATE}));
+    my $age = util::dhm_time(time()-$entry->{DATE});
+
+    $t =~ s/\ /&nbsp;/g;
+
+    print "
+<p><table bgcolor=\"\#f0f0ff\" width=\"80%\" class=\"entry\">
+  <tr>
+    <td>
+     <b>$t</b><br>$age ago<br>
+    </td>
+  </tr>
+  <tr>
+    <td valign=top align=left>
+<b><a href=$myself?function=diff&tree=$tree&date=$entry->{DATE}&author=$entry->{AUTHOR}>show diffs</a></b><br>
+<a href=$myself?function=text_diff&tree=$tree&date=$entry->{DATE}&author=$entry->{AUTHOR}>download diffs</a><br>
+    <pre>$msg</pre>
+    </td>
+  </tr>
+
+  <tr><td><em>Author: </em>$entry->{AUTHOR}</td></tr>";
+
+    if ($entry->{FILES}) {
+       print "<tr><td><em>Modified: </em>";
+       print cvsweb_paths($tree, $entry->{FILES});
+       print "</td></tr>\n";
+    }
+
+    if ($entry->{ADDED}) {
+       print "<tr><td><em>Added:</em> ";
+       print cvsweb_paths($tree, $entry->{ADDED});
+       print "</td></tr>\n";
+    }
+
+    if ($entry->{REMOVED}) {
+       print "<tr><td><em>Removed: </em>";
+       print cvsweb_paths($tree, $entry->{REMOVED});
+       print "</td></tr>\n";
+    }
+
+    print "</table>\n";
+}
+
+
+#############################################
+# show one row of history table
+sub history_row_text($$)
+{
+    my $entry = shift;
+    my $tree = shift;
+    my $msg = util::cgi_escape($entry->{MESSAGE});
+    my $t = POSIX::asctime(POSIX::gmtime($entry->{DATE}));
+    my $age = util::dhm_time(time()-$entry->{DATE});
+
+    print "Author: $entry->{AUTHOR}\n";
+    print "Mofified: $entry->{FILES}\n";
+    print "Added: $entry->{ADDED}\n";
+    print "Removed: $entry->{REMOVED}\n";
+    print "\n\n$msg\n\n\n";
+}
+
+
+###############################################
+# show recent cvs entries
+sub cvs_diff($$$$)
+{
+    my $author = shift;
+    my $date = shift;
+    my $tree = shift;
+    my $text_html = shift;
+    my $cmd;
+    my $module;
+
+    util::InArray($tree, [keys %tree_base]) || fatal("unknown tree");
+
+    my $log = util::LoadStructure("$HISTORYDIR/history.$tree");
+
+    chdir("$unpacked_dir/$tree") || fatal("no tree $unpacked_dir/$tree available");
+
+    $module = $tree_base{$tree};
+
+    for (my $i=0; $i <= $#{$log}; $i++) {
+       my $entry = $log->[$i];
+       if ($author eq $entry->{AUTHOR} &&
+           $date == $entry->{DATE}) {
+           my $t1;
+           my $t2;
+
+           chomp($t1 = POSIX::ctime($date-60+($TIMEOFFSET*60*60)));
+           chomp($t2 = POSIX::ctime($date+60+($TIMEOFFSET*60*60)));
+
+           if ($text_html eq "html") {
+               print "<h2>CVS Diff in $tree for $t1</h2>\n";
+               
+               print "<table border=0><tr>\n";
+               history_row($entry, $tree);
+               print "</tr></TABLE>\n";
+           } else {
+               history_row_text($entry, $tree);
+           }
+
+           if (! ($entry->{TAG} eq "") && !$entry->{REVISIONS}) {
+               print '
+<br>
+<b>sorry, cvs diff on branches not currently possible due to a limitation 
+in cvs</b>
+<br>';
+           }
+
+           $ENV{'CVS_PASSFILE'} = "$BASEDIR/.cvspass";
+
+           if ($entry->{REVISIONS}) {
+                   for my $f (keys %{$entry->{REVISIONS}}) {
+                       my $cmd;
+                       my $diff;
+                       my $fix_diff = 0;
+                       if ($entry->{REVISIONS}->{$f}->{REV1} eq "NONE") {
+                           $cmd = "cvs rdiff -u -r 0 -r $entry->{REVISIONS}->{$f}->{REV2} $module/$f";
+                           $fix_diff = 1;
+                       } elsif ($entry->{REVISIONS}->{$f}->{REV2} eq "NONE") {
+                           $cmd = "cvs rdiff -u -r $entry->{REVISIONS}->{$f}->{REV1} -r 0 $module/$f";
+                           $fix_diff = 1;
+                       } elsif ($text_html eq "html") {
+                           $cmd = "cvs diff -b -u -r $entry->{REVISIONS}->{$f}->{REV1} -r $entry->{REVISIONS}->{$f}->{REV2} $f";
+                       } else {
+                           $cmd = "cvs diff -u -r $entry->{REVISIONS}->{$f}->{REV1} -r $entry->{REVISIONS}->{$f}->{REV2} $f";
+                       }
+
+                       $diff = `$cmd 2> /dev/null`;
+                       if ($fix_diff) {
+                           $diff =~ s/^--- $module\//--- /mg;
+                           $diff =~ s/^\+\+\+ $module\//\+\+\+ /mg;
+                       }
+                       
+                       if ($text_html eq "html") { 
+                           print "<!-- $cmd --!>\n";
+                           $diff = util::cgi_escape($diff);
+                           $diff = cvs_pretty($diff);
+                           print "<pre>$diff</pre>\n";
+                       } else {
+                           print "$diff\n";
+                       }
+                   }
+           } else {
+                   if ($text_html eq "html") { 
+                       my $cmd = "cvs diff -b -u -D \"$t1 $TIMEZONE\" -D \"$t2 $TIMEZONE\" $entry->{FILES}";
+                   } else {
+                       my $cmd = "cvs diff -u -D \"$t1 $TIMEZONE\" -D \"$t2 $TIMEZONE\" $entry->{FILES}";
+                   }
+
+                   my $diff = `$cmd 2> /dev/null`;
+
+                   if ($text_html eq "html") { 
+                       print "<!-- $cmd --!>\n";
+                       $diff = util::cgi_escape($diff);
+                       $diff = cvs_pretty($diff);
+                   }
+                   
+                   print "<pre>$diff</pre>\n";
+           }
+
+           return;
+       }
+    }    
+}
+
+
+###############################################
+# show recent cvs entries
+sub cvs_history($)
+{
+    my $tree = shift;
+    my (%authors) = ('ALL' => 1);
+    my $author;
+
+    util::InArray($tree, [keys %tree_base]) || fatal("unknown tree");
+
+    my $log = util::LoadStructure("$HISTORYDIR/history.$tree");
+
+    for (my $i=$#{$log}; $i >= 0; $i--) {
+       $authors{$log->[$i]->{AUTHOR}} = 1;
+    }
+
+    print $req->startform("GET");
+    print "Select Author: ";
+    print $req->popup_menu("author", [sort keys %authors]);
+    print $req->submit('sub_function', 'Refresh');
+    print $req->hidden('tree', $tree);
+    print $req->hidden('function', 'Recent Checkins');
+    print $req->endform();
+
+    print "<h2>Recent checkins for $tree</h2>\n";
+    
+    print "
+";
+
+    $author = $req->param("author");
+
+    for (my $i=$#{$log}; $i >= 0; $i--) {
+       my $entry = $log->[$i];
+       if (! $author ||
+           ($author eq "ALL") || 
+           ($author eq $entry->{AUTHOR})) {
+           history_row($entry, $tree);
+       }
+    }
+    print '
+';
+}
+
+
+#cvs_diff($req->param('author'), $req->param('date'), $req->param('tree'));
+#cvs_history("trinity");
+
+
+1;
diff --git a/web/hpntc4m.html b/web/hpntc4m.html
new file mode 100644 (file)
index 0000000..dd95d2f
--- /dev/null
@@ -0,0 +1,2 @@
+Many thanks to <a href="http://www.hp.com/">Hewlett-Packard</a> for
+providing and maintaining this machine in the Build Farm.
diff --git a/web/hpntc9i.html b/web/hpntc9i.html
new file mode 100644 (file)
index 0000000..dd95d2f
--- /dev/null
@@ -0,0 +1,2 @@
+Many thanks to <a href="http://www.hp.com/">Hewlett-Packard</a> for
+providing and maintaining this machine in the Build Farm.
diff --git a/web/icon_hide_16.png b/web/icon_hide_16.png
new file mode 100644 (file)
index 0000000..53f56a1
Binary files /dev/null and b/web/icon_hide_16.png differ
diff --git a/web/icon_hide_24.png b/web/icon_hide_24.png
new file mode 100644 (file)
index 0000000..b6c1f5d
Binary files /dev/null and b/web/icon_hide_24.png differ
diff --git a/web/icon_unhide_16.png b/web/icon_unhide_16.png
new file mode 100644 (file)
index 0000000..d51de36
Binary files /dev/null and b/web/icon_unhide_16.png differ
diff --git a/web/icon_unhide_24.png b/web/icon_unhide_24.png
new file mode 100644 (file)
index 0000000..beed4ea
Binary files /dev/null and b/web/icon_unhide_24.png differ
diff --git a/web/instructions.html b/web/instructions.html
new file mode 100644 (file)
index 0000000..75841df
--- /dev/null
@@ -0,0 +1,90 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
+<HTML>
+<HEAD><TITLE>samba.org build farm</TITLE></HEAD>
+<BODY bgcolor="white" TEXT="#000000" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000">
+<p><IMG ALT="Samba Banner" BORDER=0 ALIGN=MIDDLE SRC="http://www.samba.org/samba/images/samba_banner.gif">
+<p>
+
+<br>
+<p>
+<h2>Adding a machine to the build farm</h2>
+
+
+If you have a machine that you wish to add to our build farm then please follow the following instructions:
+
+<ul>
+
+<li>Decide if your machine is suitable for the task:
+<ul>
+<li>Is it a production machine? 
+<li>Is it security-sensitive?  
+<li>Look at the output from the existing machines - would publishing file-system locations and
+IPs be a concern?
+<li>The nature of the task is that executable code is downloaded from
+(a site claiming to be) samba.org, and run on your machine by cron.
+Does this bother you?
+<li>Is this somebody else's machine?
+</ul>
+If you answer yes to any of these these questions, then we probably
+should not include it on the build farm.
+
+<li>See if it is an OS/architecture combination that we already
+have. If it is then we won't need it unless the current machine we
+have covering that combination goes away for some reason.  
+
+<li>Make sure your machine is able to open an outgoing TCP connection
+to build.samba.org on port 873 (the rsync port). Test this by running
+<pre>
+  rsync build.samba.org::
+</pre>
+and seeing if you get back the list of rsync modules.
+
+<li>If all is OK then create an account called "build" on the
+machine. If you can't create accounts then you can use an existing
+account, no special privileges are needed, just change ~build to your
+home directory in the instructions below.
+
+<li>Make sure a recent version of <a href="http://rsync.samba.org/">rsync</a> is installed on the machine
+
+<li>Create a directory ~build/build_farm/. You will need about 120MB of
+free space for this directory.
+
+<li>(optional) Install <a href="http://ccache.samba.org">ccache</a>
+and set a reasonable cache size (300MB would be plenty).  This
+massively reduces the compilation times and system load for certain changes.
+
+<li>Grab the script build_test from cvs or from <a
+href="http://www.samba.org/ftp/unpacked/build_farm/build_test">http://www.samba.org/ftp/unpacked/build_farm/build_test</a>
+and put it in ~build/build_farm/
+
+<li>Edit the script if necessary to update the location of the build_farm directory
+
+<li>Tell <a href="mailto:vance@samba.org">Vance Lankhaar</a> the name of your
+machine (as given by the hostname command) and its OS and architecture
+plus what C compilers are installed. He will send you a
+password. Put that in a file called ".password" in the build_farm
+directory.
+
+<li>Run the script build_test once manually and make sure the build ran OK. Look in build.log for errors.
+
+<li>Setup a cron job to run build_test regularly. You may wish to use
+"nice" to reduce its priority, for example I use the following cron
+entry:
+<pre>
+    0,30 * * * * /bin/nice /home/build/build_farm/build_test 2> /home/build/cron.err
+</pre>
+
+<li>Check that <a href="http://build.samba.org/">build.samba.org</a>
+is showing your new host and that it is being updated regularly. 
+</ul>
+
+Note that only a very small amount of bandwidth is used. 
+Andrew Bartlett reports having seen 6 of the boxes in the farm from behind a
+modem, and it only used a tiny proportion of that modems bandwidth.  
+He also reports having had 2 of the machines behind a modem - dial-up links
+are fine too.
+
+<p>Thanks!
+
+</BODY>
+</HTML>
diff --git a/web/insure.html b/web/insure.html
new file mode 100644 (file)
index 0000000..22c0fb0
--- /dev/null
@@ -0,0 +1,3 @@
+<img src="vmware.gif" align=right><br>
+Many thanks to <a href="http://www.vmware.com/">VMware</a> for
+providing a GSX server license for this machine
diff --git a/web/robots.txt b/web/robots.txt
new file mode 100644 (file)
index 0000000..dc89438
--- /dev/null
@@ -0,0 +1,5 @@
+# Please don't crawl the build farm.. running the cgis takes a lot of 
+# work
+
+User-Agent: *
+Disallow: /
diff --git a/web/ropeable.html b/web/ropeable.html
new file mode 100644 (file)
index 0000000..d4fd605
--- /dev/null
@@ -0,0 +1 @@
+<b>ROPEABLE</b> is a dual PIII/650 in Canberra, Australia.  Kindly provided by <a href="http://www.valinux.com">VA Linux Systems</a><br>
diff --git a/web/spe140.html b/web/spe140.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe141.html b/web/spe141.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe148.html b/web/spe148.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe158.html b/web/spe158.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe160.html b/web/spe160.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe161.html b/web/spe161.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe188.html b/web/spe188.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe190.html b/web/spe190.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/spe222.html b/web/spe222.html
new file mode 100644 (file)
index 0000000..002d7dd
--- /dev/null
@@ -0,0 +1,2 @@
+<img src=compaq-testdrive.gif align=right><br>
+This machine kindly provided by <a href="http://www.testdrive.compaq.com">Compaq Test Drive</a>
\ No newline at end of file
diff --git a/web/svamp.html b/web/svamp.html
new file mode 100644 (file)
index 0000000..15a21ae
--- /dev/null
@@ -0,0 +1 @@
+<b>SVAMP</b> is a dual PIII/550 in Canberra, Australia<br>
diff --git a/web/util.pm b/web/util.pm
new file mode 100644 (file)
index 0000000..0a4e26d
--- /dev/null
@@ -0,0 +1,225 @@
+###################################################
+# utility functions to support pidl
+# Copyright (C) tridge@samba.org, 2001
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#   
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#   
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+package util;
+
+use Data::Dumper;
+
+#####################################################################
+# check if a string is in an array
+sub InArray($$)
+{
+    my $s = shift;
+    my $a = shift;
+    for my $v (@{$a}) {
+       if ($v eq $s) { return 1; }
+    }
+    return 0;
+}
+
+#####################################################################
+# flatten an array of arrays into a single array
+sub FlattenArray($) 
+{ 
+    my $a = shift;
+    my @b;
+    for my $d (@{$a}) {
+       for my $d1 (@{$d}) {
+           push(@b, $d1);
+       }
+    }
+    return \@b;
+}
+
+#####################################################################
+# flatten an array of hashes into a single hash
+sub FlattenHash($) 
+{ 
+    my $a = shift;
+    my %b;
+    for my $d (@{$a}) {
+       for my $k (keys %{$d}) {
+           $b{$k} = $d->{$k};
+       }
+    }
+    return \%b;
+}
+
+
+#####################################################################
+# return the modification time of a file
+sub FileModtime($)
+{
+    my($filename) = shift;
+    return (stat($filename))[9];
+}
+
+
+#####################################################################
+# read a file into a string
+sub FileLoad($)
+{
+    my($filename) = shift;
+    local(*INPUTFILE);
+    open(INPUTFILE, $filename) || return "";
+    my($saved_delim) = $/;
+    undef $/;
+    my($data) = <INPUTFILE>;
+    close(INPUTFILE);
+    $/ = $saved_delim;
+    return $data;
+}
+
+#####################################################################
+# write a string into a file
+sub FileSave($$)
+{
+    my($filename) = shift;
+    my($v) = shift;
+    local(*FILE);
+    open(FILE, ">$filename") || die "can't open $filename";    
+    print FILE $v;
+    close(FILE);
+}
+
+#####################################################################
+# return a filename with a changed extension
+sub ChangeExtension($$)
+{
+    my($fname) = shift;
+    my($ext) = shift;
+    if ($fname =~ /^(.*)\.(.*?)$/) {
+       return "$1.$ext";
+    }
+    return "$fname.$ext";
+}
+
+#####################################################################
+# save a data structure into a file
+sub SaveStructure($$)
+{
+    my($filename) = shift;
+    my($v) = shift;
+    FileSave($filename, Dumper($v));
+}
+
+#####################################################################
+# load a data structure from a file (as saved with SaveStructure)
+sub LoadStructure($)
+{
+    return eval FileLoad(shift);
+}
+
+
+####################################################################
+# setup for gzipped output of a web page if possible. 
+# based on cvsweb.pl method
+# as a side effect this function adds the final line ot the HTTP headers
+sub cgi_gzip()
+{
+    my $paths = ['/usr/bin/gzip', '/bin/gzip'];
+    my $GZIPBIN;
+    my $Browser = $ENV{'HTTP_USER_AGENT'} || "";
+
+#  newer browsers accept gzip content encoding
+# and state this in a header
+# (netscape did always but didn't state it)
+# It has been reported that these
+#  braindamaged MS-Internet Exploders claim that they
+# accept gzip .. but don't in fact and
+# display garbage then :-/
+# Turn off gzip if running under mod_perl. piping does
+# not work as expected inside the server. One can probably
+# achieve the same result using Apache::GZIPFilter.
+    my $maycompress = (($ENV{'HTTP_ACCEPT_ENCODING'} =~ m|gzip|
+                       || $Browser =~ m%^Mozilla/3%)
+                      && ($Browser !~ m/MSIE/)
+                      && !defined($ENV{'MOD_PERL'}));
+    
+    if (!$maycompress) { print "\r\n"; return; }
+
+    for my $p (@{$paths}) {
+       if (stat($p)) { $GZIPBIN = $p; }
+    }
+
+    my $fh = do {local(*FH);};
+
+    if (stat($GZIPBIN) && open($fh, "|$GZIPBIN -1 -c")) {
+       print "Content-encoding: x-gzip\r\n";
+       print "Vary: Accept-Encoding\r\n";  #RFC 2068, 14.43
+       print "\r\n"; # Close headers
+       $| = 1; $| = 0; # Flush header output
+       select ($fh);
+    } else {
+       print "\r\n";
+    }
+}
+
+##########################################
+# escape a string for cgi
+sub cgi_escape($)
+{
+    my $s = shift;
+
+    $s =~ s/&/&amp;/mg;
+    $s =~ s/</&lt;/mg;
+    $s =~ s/>/&gt;/mg;
+    $s =~ s/"/&quot;/mg;
+
+    return $s;
+}
+
+##########################################
+# count the number of lines in a buffer
+sub count_lines($)
+{
+    my $s = shift;
+    my $count;
+    $count = split(/$/m, $s);
+    return $count;
+}
+
+################
+# display a time as days, hours, minutes
+sub dhm_time($)
+{
+       my $sec = shift;
+       my $days = int($sec / (60*60*24));
+       my $hour = int($sec / (60*60)) % 24;
+       my $min = int($sec / 60) % 60;
+
+       my $ret = "";
+
+       if ($sec < 0) { 
+               return "-";
+       }
+
+       if ($days != 0) { 
+               return sprintf("%dd %dh %dm", $days, $hour, $min);
+       }
+       if ($hour != 0) {
+               return sprintf("%dh %dm", $hour, $min);
+       }
+       if ($min != 0) {
+               return sprintf("%dm", $min);
+       }
+       return sprintf("%ds", $sec);
+}
+
+1;
+
diff --git a/web/vmware.gif b/web/vmware.gif
new file mode 100644 (file)
index 0000000..8a3511d
Binary files /dev/null and b/web/vmware.gif differ
diff --git a/yowiee.fns b/yowiee.fns
new file mode 100644 (file)
index 0000000..3feb4f0
--- /dev/null
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount --enable-krb5developer"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
diff --git a/yurok.fns b/yurok.fns
new file mode 100644 (file)
index 0000000..8113feb
--- /dev/null
+++ b/yurok.fns
@@ -0,0 +1,12 @@
+export CFLAGS="-O -Wall"
+
+test_tree ccache . gcc
+test_tree distcc . gcc
+test_tree rsync . gcc
+
+test_tree samba4 source gcc
+export config="--with-quotas --with-pam --with-pam_smbpass --with-smbmount"
+
+test_tree samba_2_2 source gcc
+test_tree samba_3_0 source gcc
+