Fri Jan 11 19:44:12 EST 2008  [EMAIL PROTECTED]
  * darcs.cgi cleanup
  This is in general a cleanup of the cgi tool for darcs.
  
  1: The cgi tool directory now makes sense and has an actual structure
      to it.
  
  2: Everything gets stored in the system's datadir
      (normally this is {$prefix}/share) so that it can be reproduced as
      many times as needed for seperate virtual  hosts without causing
      interference or collisions if desired.
  
  3: The CGI is intellegent enough that if your setup isn't scattered all
      over your file systems, that it requires no modifications to work.
      This is because all references to the files are now relitive to the
      cgi-bin directory. There are no more ".in" files required.
  
  4: The page created has been slightly altered so that the patch button
      is now seperated from the rss feed link, and the rss link is also
      described to actually be what it is. The darcs plug has been also
      moved to a place by it's self, and seperated by a horozontal rule so
      that the link contained in it does not confuse the user into thinking
      it is actually part of the project shown, since that may not be the
      case.
  
  5: The cgi's version number bumpped to 1.1 for these minor changes.
New patches:

[darcs.cgi cleanup
[EMAIL PROTECTED]
 This is in general a cleanup of the cgi tool for darcs.
 
 1: The cgi tool directory now makes sense and has an actual structure
     to it.
 
 2: Everything gets stored in the system's datadir
     (normally this is {$prefix}/share) so that it can be reproduced as
     many times as needed for seperate virtual  hosts without causing
     interference or collisions if desired.
 
 3: The CGI is intellegent enough that if your setup isn't scattered all
     over your file systems, that it requires no modifications to work.
     This is because all references to the files are now relitive to the
     cgi-bin directory. There are no more ".in" files required.
 
 4: The page created has been slightly altered so that the patch button
     is now seperated from the rss feed link, and the rss link is also
     described to actually be what it is. The darcs plug has been also
     moved to a place by it's self, and seperated by a horozontal rule so
     that the link contained in it does not confuse the user into thinking
     it is actually part of the project shown, since that may not be the
     case.
 
 5: The cgi's version number bumpped to 1.1 for these minor changes.
] 
<
> {
adddir ./tools/cgi/cgi-bin
adddir ./tools/cgi/darcs
adddir ./tools/cgi/darcs/config
move ./tools/cgi/xslt/styles.css ./tools/cgi/darcs/config/styles.css
adddir ./tools/cgi/darcs/xslt
move ./tools/cgi/xslt/annotate.xslt ./tools/cgi/darcs/xslt/annotate.xslt
move ./tools/cgi/xslt/browse.xslt ./tools/cgi/darcs/xslt/browse.xslt
move ./tools/cgi/xslt/common.xslt ./tools/cgi/darcs/xslt/common.xslt
move ./tools/cgi/xslt/errors.xml ./tools/cgi/darcs/xslt/errors.xml
move ./tools/cgi/xslt/errors.xslt ./tools/cgi/darcs/xslt/errors.xslt
move ./tools/cgi/xslt/patches.xslt ./tools/cgi/darcs/xslt/patches.xslt
move ./tools/cgi/xslt/repos.xslt ./tools/cgi/darcs/xslt/repos.xslt
move ./tools/cgi/xslt/rss.xslt ./tools/cgi/darcs/xslt/rss.xslt
addfile ./tools/cgi/README
addfile ./tools/cgi/cgi-bin/darcs.cgi
addfile ./tools/cgi/darcs/config/cgi.conf
hunk ./GNUmakefile 197
 	$(INSTALL_DATA) tools/zsh_completion_new $(DESTDIR)$(docdir)/examples/
 	$(INSTALL_DATA) tools/zsh_completion_old $(DESTDIR)$(docdir)/examples/
 
-installserver:	tools/cgi/darcs.cgi
-	test -d $(DESTDIR)$(libexecdir)/cgi-bin || \
-		$(INSTALL) -d $(DESTDIR)$(libexecdir)/cgi-bin
-
-	test -d $(DESTDIR)$(sysconfdir)/darcs || \
-		$(INSTALL) -d $(DESTDIR)$(sysconfdir)/darcs
-	test -e $(DESTDIR)$(sysconfdir)/darcs/cgi.conf || \
-	    $(INSTALL_DATA) tools/cgi/cgi.conf $(DESTDIR)$(sysconfdir)/darcs/cgi.conf
-	$(INSTALL) tools/cgi/darcs.cgi $(DESTDIR)$(libexecdir)/cgi-bin/darcs.cgi
+installserver:
 	test -d $(DESTDIR)$(datadir)/darcs || \
 		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs
hunk ./GNUmakefile 200
-	test -d $(DESTDIR)$(datadir)/darcs/xslt || \
-		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/xslt
-	$(INSTALL_DATA) tools/cgi/xslt/*.xslt $(DESTDIR)$(datadir)/darcs/xslt/
-	$(INSTALL_DATA) tools/cgi/xslt/styles.css $(DESTDIR)$(datadir)/darcs/xslt/styles.css
-
-# Debian policy doesn't allow symlinks as configuration files.
-#	test -e $(DESTDIR)$(sysconfdir)/darcs/styles.css || \
-#	    ln -s $(datadir)/darcs/xslt/styles.css \
-#		$(DESTDIR)$(sysconfdir)/darcs/styles.css
-	$(INSTALL) -m 644 tools/cgi/xslt/styles.css $(DESTDIR)$(sysconfdir)/darcs/styles.css
+	test -d $(DESTDIR)$(datadir)/darcs/cgi-bin || \
+		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/cgi-bin
+	test -d $(DESTDIR)$(datadir)/darcs/darcs || \
+		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/darcs
+	test -d $(DESTDIR)$(datadir)/darcs/darcs/cache || \
+		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/darcs/cache
+	test -d $(DESTDIR)$(datadir)/darcs/darcs/config || \
+		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/darcs/config
+	test -d $(DESTDIR)$(datadir)/darcs/darcs/repos || \
+		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/darcs/repos
+	test -d $(DESTDIR)$(datadir)/darcs/darcs/xslt || \
+		$(INSTALL) -d $(DESTDIR)$(datadir)/darcs/darcs/xslt
+	$(INSTALL_DATA) tools/cgi/cgi-bin/darcs.cgi $(DESTDIR)$(datadir)/darcs/cgi-bin
+	$(INSTALL_DATA) tools/cgi/darcs/config/cgi.conf $(DESTDIR)$(datadir)/darcs/darcs/config
+	$(INSTALL_DATA) tools/cgi/darcs/config/styles.css $(DESTDIR)$(datadir)/darcs/darcs/config
+	$(INSTALL_DATA) tools/cgi/darcs/xslt/*.xslt $(DESTDIR)$(datadir)/darcs/darcs/xslt
+	$(INSTALL_DATA) tools/cgi/darcs/xslt/*.xml $(DESTDIR)$(datadir)/darcs/darcs/xslt
 
 PREDIST_COPY_FILES := \
 	ChangeLog \
hunk ./GNUmakefile 400
 
 clean:
 	rm -f $(foreach dir,$(SRC_DIRS),$(dir)/*.o $(dir)/*.hi)
-	rm -f unit diff darcs darcs_cgi
+	rm -f unit diff darcs
 	rm -f stringify
 	rm -f src/darcs.tex src/darcs.dvi src/darcs.aux
 	rm -f src/patch-theory.tex src/patch-theory.aux src/patch-theory.log
hunk ./GNUmakefile 419
 distclean:	clean
 	rm -rf config.status config.log autoconf.mk config.cache autom4te.cache
 	rm -f doc/manual/darcs.ps doc/manual/darcs.pdf doc/manual/patch-theory.pdf src/Autoconf.lhs Workaround.hs darcs.idv
-	rm -f src/ThisVersion.lhs tools/cgi/README tools/cgi/darcs.cgi tools/cgi/cgi.conf
+	rm -f src/ThisVersion.lhs
 	rm -f config.command
 
 maintainer-clean: distclean
hunk ./GNUmakefile 434
 configure:		configure.ac aclocal.m4
 	autoconf
 
-autoconf.mk src/Autoconf.lhs tools/cgi/darcs.cgi : \
-   config.status autoconf.mk.in src/Autoconf.lhs.in tools/cgi/darcs.cgi.in
+autoconf.mk src/Autoconf.lhs : \
+   config.status autoconf.mk.in src/Autoconf.lhs.in
 	./config.status
 
 config.status:	configure
hunk ./tools/cgi/README 1
+darcs.cgi is the darcs repository viewer.  It provides a web interface
+for viewing darcs repositories, using XSLT to transform darcs' XML
+output into XHTML. It is written in perl and is more featureful than
+the older haskell cgi program darcs_cgi.lhs (seen in URLs as "darcs").
+
+dependencies
+
+  darcs.cgi requires with the following tools and has been tested with
+  the version mentioned:
+
+  darcs-1.0.1           http://www.darcs.net
+  libxslt-1.1.6         http://xmlsoft.org/XSLT/
+  perl-5.8.0            http://www.perl.com
+
+installation
+
+  1) copy darcs.cgi to your webserver's cgi directory, eg
+     /usr/lib/cgi-bin. A symlink probably won't do. Make
+     sure it's executable.
+  2) copy cgi.conf to ${prefix}/etc/darcs/cgi.conf and edit appropriately.
+     You can overwrite the cgi.conf used by the old darcs cgi script.
+     You probably don't need to change anything here.
+  3) copy the xslt directory to ${datarootdir}/darcs/xslt
+  4) copy xslt/styles.css to ${prefix}/etc/darcs/styles.css
+
+  Test by browsing "http://<host>/cgi-bin/darcs.cgi/".
+
+troubleshooting
+
+  if the configuration is incorrect error messages will be printed to
+  the webserver's error log, for example "/var/log/apache/error.log".
+
+  you can also double check the configuration by running darcs.cgi
+  from the command line and supplying a --check argument:
+
+     $ ./darcs.cgi --check
+
+character encodings
+
+  if your repositories contain files with characters encoded in
+  something other than ASCII or UTF-8, change the 'xml_encoding'
+  setting in cgi.conf to the appropriate encoding.
hunk ./tools/cgi/README.in 1
-darcs.cgi is the darcs repository viewer.  It provides a web interface
-for viewing darcs repositories, using XSLT to transform darcs' XML
-output into XHTML. It is written in perl and is more featureful than
-the older haskell cgi program darcs_cgi.lhs (seen in URLs as "darcs").
-
-dependencies
-
-  darcs.cgi requires with the following tools and has been tested with
-  the version mentioned:
-
-  darcs-1.0.1           http://www.darcs.net
-  libxslt-1.1.6         http://xmlsoft.org/XSLT/
-  perl-5.8.0            http://www.perl.com
-
-installation
-
-  1) copy darcs.cgi to your webserver's cgi directory, eg
-     /usr/lib/cgi-bin. A symlink probably won't do. Make
-     sure it's executable.
-  2) copy cgi.conf to @sysconfdir@/darcs/cgi.conf and edit appropriately.
-     You can overwrite the cgi.conf used by the old darcs cgi script.
-     You probably don't need to change anything here.
-  3) copy the xslt directory to @datadir@/darcs/xslt
-  4) copy xslt/styles.css to @sysconfdir@/darcs/styles.css
-
-  Test by browsing "http://<host>/cgi-bin/darcs.cgi/".
-
-troubleshooting
-
-  if the configuration is incorrect error messages will be printed to
-  the webserver's error log, for example "/var/log/apache/error.log".
-
-  you can also double check the configuration by running darcs.cgi
-  from the command line and supplying a --check argument:
-
-     $ ./darcs.cgi --check
-
-character encodings
-
-  if your repositories contain files with characters encoded in
-  something other than ASCII or UTF-8, change the 'xml_encoding'
-  setting in cgi.conf to the appropriate encoding.
rmfile ./tools/cgi/README.in
hunk ./tools/cgi/cgi-bin/darcs.cgi 1
+#!/usr/bin/perl -T
+#
+# darcs.cgi - the darcs repository viewer
+#
+# Copyright (c) 2004 Will Glozer
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+#
+# This program calls darcs (or its own subroutines) to generate XML
+# which is rendered into HTML by XSLT.  It is capable of displaying
+# the files in a repository, various patch histories, annotations, etc.
+#
+
+use strict;
+
+use CGI qw( :standard );
+use CGI::Util;
+use File::Basename;
+use File::stat;
+use IO::File;
+use POSIX;
+
+## the following variables can be customized to reflect your system
+## configuration by defining them appropriately in the file
+## "${prefix}/etc/darcs/cgi.conf".  The syntax accepts equals signs or simply
+## blanks separating values from assignments.
+
+$ENV{'PATH'} = read_conf('PATH', $ENV{'PATH'});
+
+# path to executables, or just the executable if they are in $ENV{'PATH'}
+my $darcs_program    = read_conf("darcs", "darcs");
+my $xslt_program     = read_conf("xsltproc", "xsltproc");
+
+# directory containing repositories
+my $repository_root  = read_conf("reposdir", "/var/www");
+
+# XSLT template locations
+my $template_root = read_conf("xslt_dir", '../darcs/xslt');
+
+my $xslt_annotate = "$template_root/annotate.xslt";
+my $xslt_browse   = "$template_root/browse.xslt";
+my $xslt_patches  = "$template_root/patches.xslt";
+my $xslt_repos    = "$template_root/repos.xslt";
+my $xslt_rss      = "$template_root/rss.xslt";
+
+my $xslt_errors   = "$template_root/errors.xslt";
+
+# CSS stylesheet that XSLT templates refer to.  This is a HTTP request
+# path, not a local file system path. The default will cause darcs.cgi
+# to serve the stylesheet rather than the web server.
+my $stylesheet = read_conf("stylesheet", "/cgi-bin/darcs.cgi/styles.css");
+
+# location of the CSS stylesheet that darcs.cgi will serve if it
+# receives a request for '/styles.css'
+my $css_styles = read_conf("css_styles", '../darcs/config/styles.css');
+
+# location of the favicon that darcs.cgi will serve if it
+# receives a request for '/[\w\-]+/favicon.ico'
+my $favicon = read_conf("favicon", "/favicon.ico");
+
+# XML source for the error pages
+my $xml_errors = "$template_root/errors.xml";
+
+# encoding to include in XML declaration
+my $xml_encoding = read_conf("xml_encoding", "UTF-8");
+
+## end customization
+
+# ----------------------------------------------------------------------
+
+# read a value from the cgi.conf file.
+{
+  my(%conf);
+
+  sub read_conf {
+    my ($flag, $val) = @_;
+    $val = "" if !defined($val);
+    
+    if (!%conf && open(CGI_CONF, '../darcs/config/cgi.conf')) {
+      while (<CGI_CONF>) {
+        chomp;
+	next if /^\s*(?:\#.*)?$/;   # Skip blank lines and comment lines
+        if (/^\s*(\S+)\s*(?:\=\s*)?(\S+)\s*$/) {
+           $conf{$1} = $2;
+	   # print "read_conf: $1 = $2\n";
+        } else {
+           warn "read_conf: $_\n";
+        }
+      }
+      close(CGI_CONF);
+    }
+
+    $val = $conf{$flag} if exists($conf{$flag});
+
+    return $val;
+  }
+}
+
+# open xsltproc to transform and output `xml' with stylesheet file `xslt'
+sub transform {
+    my ($xslt, $args, $content_type) = @_;
+
+    $| = 1;
+    printf "Content-type: %s\r\n\r\n", $content_type || "text/html";
+    my $pipe = new IO::File "| $xslt_program $args $xslt -";
+    $pipe->autoflush(0);
+    return $pipe;
+}
+
+sub pristine_dir {
+    my ($repo) = @_;
+    my $pristine = "current";
+    if (! -d "${repository_root}/${repo}/_darcs/$pristine") {
+        $pristine = "pristine";
+    }
+    return "${repository_root}/${repo}/_darcs/$pristine";
+}
+
+# begin an XML document with a root element and the repository path
+sub make_xml {
+    my ($fh, $repo, $dir, $file) = @_;
+    my ($full_path, $path) = '/';
+
+    printf $fh qq(<?xml version="1.0" encoding="$xml_encoding"?>\n);
+
+    printf $fh qq(<darcs repository="$repo" target="%s/%s%s">\n),
+        $repo, ($dir ? "$dir/" : ''), ($file ? "$file" : '');
+
+    print $fh qq(<path>\n);
+    foreach $path (split('/', "$repo/$dir")) {
+        $full_path .= "$path/";
+        print $fh qq(<directory full-path="$full_path">$path</directory>\n);
+    }
+    if ($file) {
+        print $fh qq(<file full-path="$full_path$file">$file</file>\n) if $file;
+    }
+    print $fh qq(</path>\n\n);
+}
+
+# finish XML output
+sub finish_xml {
+    my ($fh) = @_;
+    print $fh "\n</darcs>\n";
+    $fh->flush;
+}
+
+# run darcs and wrap the output in an XML document
+sub darcs_xml {
+    my ($fh, $repo, $cmd, $args, $dir, $file) = @_;
+
+    make_xml($fh, $repo, $dir, $file);
+
+    push(@$args, '--xml-output');
+    darcs($fh, $repo, $cmd, $args, $dir, $file);
+
+    finish_xml($fh);
+}
+
+# run darcs with output redirected to the specified file handle
+sub darcs {
+    my ($fh, $repo, $cmd, $args, $dir, $file) = @_;
+    my (@darcs_argv) = ($darcs_program, $cmd, @$args);
+
+    # push target only if there is one, otherwise darcs will get an empty param
+    if ($dir || $file) {
+        push(@darcs_argv, sprintf("%s%s%s", $dir, ($dir ? '/' : ''), $file));
+    }
+
+    my($pid) = fork;
+    if ($pid) {
+	# in the parent process
+	my($status) = waitpid($pid, 0);
+	die "$darcs_program exited with status $?\n" if $?;
+    } elsif(defined($pid)) {
+	# in the child process
+	open(STDIN, '/dev/null');
+	if (defined($fh)) {
+	    open(STDOUT, '>&', $fh)
+		|| die "can't dup to stdout: $!\n";
+	}
+	chdir "$repository_root/$repo"
+	    || die "chdir: $repository_root/$repo: $!\n";
+	exec @darcs_argv;
+	die "can't exec ".$darcs_argv[0].": $!\n";
+    } else {
+	# fork failed
+	die "can't fork: $!\n";
+    }
+}
+
+# get a directory listing as XML output
+sub dir_listing {
+    my ($fh, $repo, $dir) = @_;
+    make_xml($fh, $repo, $dir, '');
+
+    print $fh "<files>\n";
+    my $dir_ = pristine_dir ($repo) . "/$dir";
+    opendir(DH, $dir_);
+    while( defined (my $file_ = readdir(DH)) ) {
+        next if $file_ =~ /^\.\.?$/;
+        my $file = "$dir_/$file_";
+        my $secs  = stat($file)->mtime;
+        my $mtime = localtime($secs);
+        my $ts = POSIX::strftime("%Y%m%d%H%M%S", gmtime $secs);
+
+        my ($name, $type);
+
+         if (-d $file) {
+             ($name, $type) = (basename($file) . '/', 'directory');
+         } else {
+             ($name, $type) = (basename($file), 'file');
+         }
+         printf $fh qq(  <$type name="$name" modified="$mtime" ts="$ts" />\n);
+    }
+    closedir(DH);
+    print $fh "</files>\n";
+
+    finish_xml($fh);
+}
+
+# get a repository listing as XML output
+sub repo_listing {
+    my($fh) = @_;
+
+    make_xml($fh, "", "", "");
+
+    print $fh "<repositories>\n";
+    opendir(DH, $repository_root);
+    while( defined (my $name = readdir(DH)) ) {
+        next if $name =~ /^\.\.?$/;
+        if (-d "$repository_root/$name/_darcs") {
+            printf $fh qq(  <repository name="$name" />\n);
+        }
+    }
+    closedir(DH);
+    print $fh "</repositories>\n";
+
+    finish_xml($fh);
+    return $fh;
+}
+
+# show an error page
+sub show_error {
+    my ($type, $code, $message) = @_;
+    my $xml;
+
+    # set the xslt processing arguments
+    my $xslt_args = qq {
+        --stringparam error-type '$type'
+        --stringparam stylesheet '$stylesheet'
+    };
+    $xslt_args =~ s/\s+/ /gm;
+
+    print "Status: $code $message\r\n\r\n";
+    system("$xslt_program $xslt_args $xslt_errors $xml_errors");
+}
+
+# check if the requested resource has been modified since the client last
+# saw it. If not send HTTP status code 304, otherwise set the Last-modified
+# and Cache-control headers.
+sub is_cached {
+    my ($path) = @_;
+    my ($stat) = stat($path);
+
+    # stat may fail because the path was renamed or deleted but still referred
+    # to by older darcs patches
+    if ($stat) {
+        my $last_modified = CGI::expires($stat->mtime);
+
+        if (http('If-Modified-Since') eq $last_modified) {
+            print("Status: 304 Not Modified\r\n\r\n");
+            return 1;
+        }
+
+        print("Cache-control: max-age=0, must-revalidate\r\n");
+        print("Last-modified: $last_modified\r\n");
+    }
+    return 0;
+}
+
+# safely extract a parameter from the http request.  This applies a regexp
+# to the parameter which should group only the appropriate parameter value
+sub safe_param {
+    my ($param, $regex, $default) = @_;
+    my $value = CGI::Util::unescape(param($param));
+    return ($value =~ $regex) ? $1 : $default;
+}
+
+# common regular expressions for validating passed parameters
+my $hash_regex = qr/^([\w\-.]+)$/;
+my $path_regex = [EMAIL PROTECTED]([^\\!\$\^&*()\[\]{}<>~`|';"?\r\n]+)$@;
+
+# respond to a CGI request
+sub respond {
+    # untaint the full URL to this CGI
+    my $cgi_url = CGI::Util::unescape(url());
+    $cgi_url =~ $path_regex or die qq(bad url "$cgi_url");
+    $cgi_url = $1;
+
+    # untaint script_name, reasonable to expect only \w, -, /, and . in the name
+    my $script_name = CGI::Util::unescape(script_name());
+    $script_name =~ qr~^([\w/.\-]+)$~ or die qq(bad script_name "$script_name");
+    $script_name = $1;
+
+    # untaint simple parameters, which can only have chars matching \w+
+    my $cmd  = safe_param('c', '^(\w+)$', 'browse');
+    my $sort = safe_param('s', '^(\w+)$', '');
+
+    # set the xslt processing arguments
+    my $xslt_args = qq {
+        --stringparam cgi-program '$script_name'
+        --stringparam cgi-url '$cgi_url'
+        --stringparam sort-by '$sort'
+        --stringparam stylesheet '$stylesheet'
+    };
+    $xslt_args =~ s/\s+/ /gm;
+
+    my ($path) = CGI::Util::unescape(path_info());
+    # don't allow ./ or ../ in paths
+    $path =~ s|[.]+/||g;
+
+    # check whether we're asking for styles.css
+    if ($path eq '/styles.css') {
+        return if is_cached($css_styles);
+
+        open (STYLES_CSS, $css_styles) or die qq(couldn't open "${css_styles}");
+        my $size = stat($css_styles)->size;
+
+        print "Content-length: $size\r\n";
+        print "Content-type: text/css\r\n\r\n";
+
+        while (<STYLES_CSS>) {
+          print $_;
+        }
+        close (STYLES_CSS);
+        return;
+    }
+
+    # check whether we're asking for favicon.ico
+    if ($path =~ '/[\w\-]+/favicon.ico') {
+        return if is_cached($favicon);
+
+        open (FAVICON, $favicon) or die qq(couldn't open "${favicon}");
+        my $size = stat($favicon)->size;
+
+        print "Content-length: $size\r\n";
+        print "Content-type: image/x-icon\r\n\r\n";
+
+        while (<FAVICON>) {
+          print $_;
+        }
+        close (FAVICON);
+        return;
+    }
+
+    # when no repository is requested display available repositories
+    if (length($path) < 2) {
+        my $fh = transform($xslt_repos, $xslt_args);
+        repo_listing($fh);
+        return;
+    }
+
+    # don't allow any shell meta characters in paths
+    $path =~ $path_regex or die qq(bad path_info "$path");
+    my @path = split('/', substr($1, 1));
+
+    # split the path into a repository, directory, and file
+    my ($repo, $dir, $file, @bits) = ('', '', '');
+    while (@path > 0) {
+        $repo = join('/', @path);
+        # check if remaining path elements refer to a repo
+        if (-d "${repository_root}/${repo}/_darcs") {
+            if (@bits > 1) {
+                $dir  = join('/', @bits[0..$#bits - 1]);
+            }
+            $file = $bits[$#bits];
+            # check if last element of path, stored in $file, is really a dir
+            if (-d (pristine_dir ($repo) . "/${dir}/${file}")) {
+                $dir = ($dir ? "$dir/$file" : $file);
+                $file = '';
+            }
+            last;
+        } else {
+            $repo = '';
+            unshift(@bits, pop @path);
+        }
+    }
+
+    # make sure the repository exists
+    unless ($repo) {
+        show_error('invalid-repository', '404', 'Invalid repository');
+        return;
+    }
+
+    # don't generate output unless the requested path has been
+    # modified since the client last saw it.
+    return if is_cached(pristine_dir ($repo) . "/$dir/$file");
+
+    # untaint patches and tags. Tags can have arbitrary values, so
+    # never pass these unquoted, on pain of pain!
+    my $patch = safe_param('p', $hash_regex);
+    my $tag   = safe_param('t', '^(.+)$');
+
+    my @darcs_args;
+    push(@darcs_args, '--match', "hash $patch") if $patch;
+    push(@darcs_args, '-t', $tag) if $tag;
+
+    # process the requested command
+    if ($cmd eq 'browse') {
+        my $fh = transform($xslt_browse, $xslt_args);
+        dir_listing($fh, $repo, $dir);
+    } elsif ($cmd eq 'patches') {
+        my $fh = transform($xslt_patches, $xslt_args);
+        darcs_xml($fh, $repo, "changes", [EMAIL PROTECTED], $dir, $file);
+    } elsif ($cmd eq 'annotate') {
+        push(@darcs_args, '--summary');
+
+        my $creator_hash  = safe_param('ch', $hash_regex);
+        my $original_path = safe_param('o', $path_regex);
+        my $fh = transform($xslt_annotate, $xslt_args);
+
+        # use the creator hash and original file name when available so
+        # annotations can span renames
+        if ($creator_hash ne '' && $original_path ne '') {
+            push(@darcs_args, '--creator-hash', $creator_hash);
+            darcs_xml($fh, $repo, "annotate", [EMAIL PROTECTED], '', $original_path);
+        } else {
+            darcs_xml($fh, $repo, "annotate", [EMAIL PROTECTED], $dir, $file);
+        }
+    } elsif ($cmd eq 'diff') {
+        push(@darcs_args, '-u');
+        print "Content-type: text/plain\r\n\r\n";
+        darcs(undef, $repo, "diff", [EMAIL PROTECTED], $dir, $file);
+    } elsif ($cmd eq 'rss') {
+        push(@darcs_args, '--last', '25');
+
+        my $fh = transform($xslt_rss, $xslt_args, "application/rss+xml");
+        darcs_xml($fh, $repo, "changes", [EMAIL PROTECTED], $dir, $file);
+    } else {
+        show_error('invalid-command', '400', 'Invalid command');
+    }
+}
+
+# run a self-test when the --check argument is supplied
+if ($ARGV[0] eq '--check') {
+    (read_conf("css_styles", "abc") ne "abc") ||
+        die "cannot read config file: $!\n";
+
+    (`$darcs_program`) ||
+        die "cannot execute darcs as '$darcs_program': $!\n";
+    (`$xslt_program`) ||
+        die "cannot execute xstlproc as '$xslt_program': $!\n";
+
+    (-d $repository_root && -r $repository_root) ||
+        die "cannot read repository root directory '$repository_root': $!\n";
+    (-d $template_root && -r $template_root) ||
+        die "cannot read template root directory '$template_root': $!\n";
+    (-f $css_styles) ||
+        die "cannot read css stylesheet '$css_styles': $!\n";
+    (-f $xml_errors) ||
+        die "cannot read error messages '$xml_errors': $!\n";
+
+    exit 0;
+}
+
+# handle the CGI request
+respond();
+
hunk ./tools/cgi/cgi.conf.in 1
-# This is an example for cgi.conf
-
-# reposdir is the directory containing the repositories
-
-reposdir = /var/www/repos
-
-# cachedir is a directory writable by www-data (or whatever user your cgi
-# scripts run as) which is used to cache the web pages.
-
-cachedir = /var/cache/darcs
-
-# The following are used by darcs.cgi (not darcs_cgi)
-PATH = /bin:/usr/bin:/usr/local/bin
-
-# paths to executables, or just the executables if they are in 'PATH'
-#darcs = darcs
-#xsltproc = xsltproc
-
-# Path to XSLT templates (default is /usr/local/share/darcs/xslt)
-xslt_dir = @datadir@/darcs/xslt
-
-# HTTP request path of the style sheet, the default will magically read 
-# @sysconfdir@/darcs/styles.css
-#stylesheet = /cgi-bin/darcs.cgi/styles.css
-
-css_styles  = @sysconfdir@/darcs/styles.css
-
-# encoding to include in XML declaration.  Set this to the encoding used
-# by the files in your repositories.
-
-xml_encoding = UTF-8
rmfile ./tools/cgi/cgi.conf.in
hunk ./tools/cgi/darcs/config/cgi.conf 1
+# This is an example for cgi.conf
+
+# reposdir is the directory containing the repositories
+
+reposdir = ../docroot/repos
+
+# cachedir is a directory writable by www-data (or whatever user your cgi
+# scripts run as) which is used to cache the web pages.
+
+cachedir = ../darcs/cache
+
+# The following are used by darcs.cgi (not darcs_cgi)
+PATH = /bin:/usr/bin:/usr/local/bin
+
+# paths to executables, or just the executables if they are in 'PATH'
+#darcs = darcs
+#xsltproc = xsltproc
+
+# Path to XSLT templates (default is /usr/local/share/darcs/xslt)
+xslt_dir = ../darcs/xslt
+
+# HTTP request path of the style sheet, the default will magically read 
+# ${prefix}/etc/darcs/styles.css
+#stylesheet = /cgi-bin/darcs.cgi/styles.css
+
+css_styles  = ../darcs/config/styles.css
+
+# encoding to include in XML declaration.  Set this to the encoding used
+# by the files in your repositories.
+
+xml_encoding = UTF-8
+
+favicon = /favicon.ico
+
hunk ./tools/cgi/darcs/config/styles.css 39
 
 span.version {
   color: #9292C9;  
-  margin-left: 75px;
 }
 
 span.comment {
hunk ./tools/cgi/darcs/xslt/common.xslt 41
         <form action="{$command}" method="get">
           <p>
             <input class="patches" type="submit" name="c" value="patches"/>
-            
+            | Subscribe to a live
             <a href="{$command}?c=rss">rss</a>
hunk ./tools/cgi/darcs/xslt/common.xslt 43
-            
+            feed
+          </p>
+          <hr />
+          <p>
             <span class="version">
hunk ./tools/cgi/darcs/xslt/common.xslt 48
-              <a class="home" href="http://darcs.net/";>darcs.cgi</a>
-              v1.0
+              Powered by
+              <a class="home" href="http://darcs.net/";>darcs</a>
+              | darcs.cgi v1.1
             </span>
           </p>
         </form>
hunk ./tools/cgi/darcs.cgi.in 1
-#!/usr/bin/perl -T
-#
-# darcs.cgi - the darcs repository viewer
-#
-# Copyright (c) 2004 Will Glozer
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-#
-# This program calls darcs (or its own subroutines) to generate XML
-# which is rendered into HTML by XSLT.  It is capable of displaying
-# the files in a repository, various patch histories, annotations, etc.
-#
-
-use strict;
-
-use CGI qw( :standard );
-use CGI::Util;
-use File::Basename;
-use File::stat;
-use IO::File;
-use POSIX;
-
-## the following variables can be customized to reflect your system
-## configuration by defining them appropriately in the file
-## "@sysconfdir@/darcs/cgi.conf".  The syntax accepts equals signs or simply
-## blanks separating values from assignments.
-
-$ENV{'PATH'} = read_conf('PATH', $ENV{'PATH'});
-
-# path to executables, or just the executable if they are in $ENV{'PATH'}
-my $darcs_program    = read_conf("darcs", "darcs");
-my $xslt_program     = read_conf("xsltproc", "xsltproc");
-
-# directory containing repositories
-my $repository_root  = read_conf("reposdir", "/var/www");
-
-# XSLT template locations
-my $template_root = read_conf("xslt_dir", '@datadir@/darcs/xslt');
-
-my $xslt_annotate = "$template_root/annotate.xslt";
-my $xslt_browse   = "$template_root/browse.xslt";
-my $xslt_patches  = "$template_root/patches.xslt";
-my $xslt_repos    = "$template_root/repos.xslt";
-my $xslt_rss      = "$template_root/rss.xslt";
-
-my $xslt_errors   = "$template_root/errors.xslt";
-
-# CSS stylesheet that XSLT templates refer to.  This is a HTTP request
-# path, not a local file system path. The default will cause darcs.cgi
-# to serve the stylesheet rather than the web server.
-my $stylesheet = read_conf("stylesheet", "/cgi-bin/darcs.cgi/styles.css");
-
-# location of the CSS stylesheet that darcs.cgi will serve if it
-# receives a request for '/styles.css'
-my $css_styles = read_conf("css_styles", '@sysconfdir@/darcs/styles.css');
-
-# location of the favicon that darcs.cgi will serve if it
-# receives a request for '/[\w\-]+/favicon.ico'
-my $favicon = read_conf("favicon", "/cgi-bin/favicon.ico");
-
-# XML source for the error pages
-my $xml_errors = "$template_root/errors.xml";
-
-# encoding to include in XML declaration
-my $xml_encoding = read_conf("xml_encoding", "UTF-8");
-
-## end customization
-
-# ----------------------------------------------------------------------
-
-# read a value from the cgi.conf file.
-{
-  my(%conf);
-
-  sub read_conf {
-    my ($flag, $val) = @_;
-    $val = "" if !defined($val);
-    
-    if (!%conf && open(CGI_CONF, '@sysconfdir@/darcs/cgi.conf')) {
-      while (<CGI_CONF>) {
-        chomp;
-	next if /^\s*(?:\#.*)?$/;   # Skip blank lines and comment lines
-        if (/^\s*(\S+)\s*(?:\=\s*)?(\S+)\s*$/) {
-           $conf{$1} = $2;
-	   # print "read_conf: $1 = $2\n";
-        } else {
-           warn "read_conf: $_\n";
-        }
-      }
-      close(CGI_CONF);
-    }
-
-    $val = $conf{$flag} if exists($conf{$flag});
-
-    return $val;
-  }
-}
-
-# open xsltproc to transform and output `xml' with stylesheet file `xslt'
-sub transform {
-    my ($xslt, $args, $content_type) = @_;
-
-    $| = 1;
-    printf "Content-type: %s\r\n\r\n", $content_type || "text/html";
-    my $pipe = new IO::File "| $xslt_program $args $xslt -";
-    $pipe->autoflush(0);
-    return $pipe;
-}
-
-sub pristine_dir {
-    my ($repo) = @_;
-    my $pristine = "current";
-    if (! -d "${repository_root}/${repo}/_darcs/$pristine") {
-        $pristine = "pristine";
-    }
-    return "${repository_root}/${repo}/_darcs/$pristine";
-}
-
-# begin an XML document with a root element and the repository path
-sub make_xml {
-    my ($fh, $repo, $dir, $file) = @_;
-    my ($full_path, $path) = '/';
-
-    printf $fh qq(<?xml version="1.0" encoding="$xml_encoding"?>\n);
-
-    printf $fh qq(<darcs repository="$repo" target="%s/%s%s">\n),
-        $repo, ($dir ? "$dir/" : ''), ($file ? "$file" : '');
-
-    print $fh qq(<path>\n);
-    foreach $path (split('/', "$repo/$dir")) {
-        $full_path .= "$path/";
-        print $fh qq(<directory full-path="$full_path">$path</directory>\n);
-    }
-    if ($file) {
-        print $fh qq(<file full-path="$full_path$file">$file</file>\n) if $file;
-    }
-    print $fh qq(</path>\n\n);
-}
-
-# finish XML output
-sub finish_xml {
-    my ($fh) = @_;
-    print $fh "\n</darcs>\n";
-    $fh->flush;
-}
-
-# run darcs and wrap the output in an XML document
-sub darcs_xml {
-    my ($fh, $repo, $cmd, $args, $dir, $file) = @_;
-
-    make_xml($fh, $repo, $dir, $file);
-
-    push(@$args, '--xml-output');
-    darcs($fh, $repo, $cmd, $args, $dir, $file);
-
-    finish_xml($fh);
-}
-
-# run darcs with output redirected to the specified file handle
-sub darcs {
-    my ($fh, $repo, $cmd, $args, $dir, $file) = @_;
-    my (@darcs_argv) = ($darcs_program, $cmd, @$args);
-
-    # push target only if there is one, otherwise darcs will get an empty param
-    if ($dir || $file) {
-        push(@darcs_argv, sprintf("%s%s%s", $dir, ($dir ? '/' : ''), $file));
-    }
-
-    my($pid) = fork;
-    if ($pid) {
-	# in the parent process
-	my($status) = waitpid($pid, 0);
-	die "$darcs_program exited with status $?\n" if $?;
-    } elsif(defined($pid)) {
-	# in the child process
-	open(STDIN, '/dev/null');
-	if (defined($fh)) {
-	    open(STDOUT, '>&', $fh)
-		|| die "can't dup to stdout: $!\n";
-	}
-	chdir "$repository_root/$repo"
-	    || die "chdir: $repository_root/$repo: $!\n";
-	exec @darcs_argv;
-	die "can't exec ".$darcs_argv[0].": $!\n";
-    } else {
-	# fork failed
-	die "can't fork: $!\n";
-    }
-}
-
-# get a directory listing as XML output
-sub dir_listing {
-    my ($fh, $repo, $dir) = @_;
-    make_xml($fh, $repo, $dir, '');
-
-    print $fh "<files>\n";
-    my $dir_ = pristine_dir ($repo) . "/$dir";
-    opendir(DH, $dir_);
-    while( defined (my $file_ = readdir(DH)) ) {
-        next if $file_ =~ /^\.\.?$/;
-        my $file = "$dir_/$file_";
-        my $secs  = stat($file)->mtime;
-        my $mtime = localtime($secs);
-        my $ts = POSIX::strftime("%Y%m%d%H%M%S", gmtime $secs);
-
-        my ($name, $type);
-
-         if (-d $file) {
-             ($name, $type) = (basename($file) . '/', 'directory');
-         } else {
-             ($name, $type) = (basename($file), 'file');
-         }
-         printf $fh qq(  <$type name="$name" modified="$mtime" ts="$ts" />\n);
-    }
-    closedir(DH);
-    print $fh "</files>\n";
-
-    finish_xml($fh);
-}
-
-# get a repository listing as XML output
-sub repo_listing {
-    my($fh) = @_;
-
-    make_xml($fh, "", "", "");
-
-    print $fh "<repositories>\n";
-    opendir(DH, $repository_root);
-    while( defined (my $name = readdir(DH)) ) {
-        next if $name =~ /^\.\.?$/;
-        if (-d "$repository_root/$name/_darcs") {
-            printf $fh qq(  <repository name="$name" />\n);
-        }
-    }
-    closedir(DH);
-    print $fh "</repositories>\n";
-
-    finish_xml($fh);
-    return $fh;
-}
-
-# show an error page
-sub show_error {
-    my ($type, $code, $message) = @_;
-    my $xml;
-
-    # set the xslt processing arguments
-    my $xslt_args = qq {
-        --stringparam error-type '$type'
-        --stringparam stylesheet '$stylesheet'
-    };
-    $xslt_args =~ s/\s+/ /gm;
-
-    print "Status: $code $message\r\n\r\n";
-    system("$xslt_program $xslt_args $xslt_errors $xml_errors");
-}
-
-# check if the requested resource has been modified since the client last
-# saw it. If not send HTTP status code 304, otherwise set the Last-modified
-# and Cache-control headers.
-sub is_cached {
-    my ($path) = @_;
-    my ($stat) = stat($path);
-
-    # stat may fail because the path was renamed or deleted but still referred
-    # to by older darcs patches
-    if ($stat) {
-        my $last_modified = CGI::expires($stat->mtime);
-
-        if (http('If-Modified-Since') eq $last_modified) {
-            print("Status: 304 Not Modified\r\n\r\n");
-            return 1;
-        }
-
-        print("Cache-control: max-age=0, must-revalidate\r\n");
-        print("Last-modified: $last_modified\r\n");
-    }
-    return 0;
-}
-
-# safely extract a parameter from the http request.  This applies a regexp
-# to the parameter which should group only the appropriate parameter value
-sub safe_param {
-    my ($param, $regex, $default) = @_;
-    my $value = CGI::Util::unescape(param($param));
-    return ($value =~ $regex) ? $1 : $default;
-}
-
-# common regular expressions for validating passed parameters
-my $hash_regex = qr/^([\w\-.]+)$/;
-my $path_regex = [EMAIL PROTECTED]([^\\!\$\^&*()\[\]{}<>~`|';"?\r\n]+)$@;
-
-# respond to a CGI request
-sub respond {
-    # untaint the full URL to this CGI
-    my $cgi_url = CGI::Util::unescape(url());
-    $cgi_url =~ $path_regex or die qq(bad url "$cgi_url");
-    $cgi_url = $1;
-
-    # untaint script_name, reasonable to expect only \w, -, /, and . in the name
-    my $script_name = CGI::Util::unescape(script_name());
-    $script_name =~ qr~^([\w/.\-]+)$~ or die qq(bad script_name "$script_name");
-    $script_name = $1;
-
-    # untaint simple parameters, which can only have chars matching \w+
-    my $cmd  = safe_param('c', '^(\w+)$', 'browse');
-    my $sort = safe_param('s', '^(\w+)$', '');
-
-    # set the xslt processing arguments
-    my $xslt_args = qq {
-        --stringparam cgi-program '$script_name'
-        --stringparam cgi-url '$cgi_url'
-        --stringparam sort-by '$sort'
-        --stringparam stylesheet '$stylesheet'
-    };
-    $xslt_args =~ s/\s+/ /gm;
-
-    my ($path) = CGI::Util::unescape(path_info());
-    # don't allow ./ or ../ in paths
-    $path =~ s|[.]+/||g;
-
-    # check whether we're asking for styles.css
-    if ($path eq '/styles.css') {
-        return if is_cached($css_styles);
-
-        open (STYLES_CSS, $css_styles) or die qq(couldn't open "${css_styles}");
-        my $size = stat($css_styles)->size;
-
-        print "Content-length: $size\r\n";
-        print "Content-type: text/css\r\n\r\n";
-
-        while (<STYLES_CSS>) {
-          print $_;
-        }
-        close (STYLES_CSS);
-        return;
-    }
-
-    # check whether we're asking for favicon.ico
-    if ($path =~ '/[\w\-]+/favicon.ico') {
-        return if is_cached($favicon);
-
-        open (FAVICON, $favicon) or die qq(couldn't open "${favicon}");
-        my $size = stat($favicon)->size;
-
-        print "Content-length: $size\r\n";
-        print "Content-type: image/x-icon\r\n\r\n";
-
-        while (<FAVICON>) {
-          print $_;
-        }
-        close (FAVICON);
-        return;
-    }
-
-    # when no repository is requested display available repositories
-    if (length($path) < 2) {
-        my $fh = transform($xslt_repos, $xslt_args);
-        repo_listing($fh);
-        return;
-    }
-
-    # don't allow any shell meta characters in paths
-    $path =~ $path_regex or die qq(bad path_info "$path");
-    my @path = split('/', substr($1, 1));
-
-    # split the path into a repository, directory, and file
-    my ($repo, $dir, $file, @bits) = ('', '', '');
-    while (@path > 0) {
-        $repo = join('/', @path);
-        # check if remaining path elements refer to a repo
-        if (-d "${repository_root}/${repo}/_darcs") {
-            if (@bits > 1) {
-                $dir  = join('/', @bits[0..$#bits - 1]);
-            }
-            $file = $bits[$#bits];
-            # check if last element of path, stored in $file, is really a dir
-            if (-d (pristine_dir ($repo) . "/${dir}/${file}")) {
-                $dir = ($dir ? "$dir/$file" : $file);
-                $file = '';
-            }
-            last;
-        } else {
-            $repo = '';
-            unshift(@bits, pop @path);
-        }
-    }
-
-    # make sure the repository exists
-    unless ($repo) {
-        show_error('invalid-repository', '404', 'Invalid repository');
-        return;
-    }
-
-    # don't generate output unless the requested path has been
-    # modified since the client last saw it.
-    return if is_cached(pristine_dir ($repo) . "/$dir/$file");
-
-    # untaint patches and tags. Tags can have arbitrary values, so
-    # never pass these unquoted, on pain of pain!
-    my $patch = safe_param('p', $hash_regex);
-    my $tag   = safe_param('t', '^(.+)$');
-
-    my @darcs_args;
-    push(@darcs_args, '--match', "hash $patch") if $patch;
-    push(@darcs_args, '-t', $tag) if $tag;
-
-    # process the requested command
-    if ($cmd eq 'browse') {
-        my $fh = transform($xslt_browse, $xslt_args);
-        dir_listing($fh, $repo, $dir);
-    } elsif ($cmd eq 'patches') {
-        my $fh = transform($xslt_patches, $xslt_args);
-        darcs_xml($fh, $repo, "changes", [EMAIL PROTECTED], $dir, $file);
-    } elsif ($cmd eq 'annotate') {
-        push(@darcs_args, '--summary');
-
-        my $creator_hash  = safe_param('ch', $hash_regex);
-        my $original_path = safe_param('o', $path_regex);
-        my $fh = transform($xslt_annotate, $xslt_args);
-
-        # use the creator hash and original file name when available so
-        # annotations can span renames
-        if ($creator_hash ne '' && $original_path ne '') {
-            push(@darcs_args, '--creator-hash', $creator_hash);
-            darcs_xml($fh, $repo, "annotate", [EMAIL PROTECTED], '', $original_path);
-        } else {
-            darcs_xml($fh, $repo, "annotate", [EMAIL PROTECTED], $dir, $file);
-        }
-    } elsif ($cmd eq 'diff') {
-        push(@darcs_args, '-u');
-        print "Content-type: text/plain\r\n\r\n";
-        darcs(undef, $repo, "diff", [EMAIL PROTECTED], $dir, $file);
-    } elsif ($cmd eq 'rss') {
-        push(@darcs_args, '--last', '25');
-
-        my $fh = transform($xslt_rss, $xslt_args, "application/rss+xml");
-        darcs_xml($fh, $repo, "changes", [EMAIL PROTECTED], $dir, $file);
-    } else {
-        show_error('invalid-command', '400', 'Invalid command');
-    }
-}
-
-# run a self-test when the --check argument is supplied
-if ($ARGV[0] eq '--check') {
-    (read_conf("css_styles", "abc") ne "abc") ||
-        die "cannot read config file: $!\n";
-
-    (`$darcs_program`) ||
-        die "cannot execute darcs as '$darcs_program': $!\n";
-    (`$xslt_program`) ||
-        die "cannot execute xstlproc as '$xslt_program': $!\n";
-
-    (-d $repository_root && -r $repository_root) ||
-        die "cannot read repository root directory '$repository_root': $!\n";
-    (-d $template_root && -r $template_root) ||
-        die "cannot read template root directory '$template_root': $!\n";
-    (-f $css_styles) ||
-        die "cannot read css stylesheet '$css_styles': $!\n";
-    (-f $xml_errors) ||
-        die "cannot read error messages '$xml_errors': $!\n";
-
-    exit 0;
-}
-
-# handle the CGI request
-respond();
-
rmfile ./tools/cgi/darcs.cgi.in
rmdir ./tools/cgi/xslt
}

Context:

[resolve conflict.
David Roundy <[EMAIL PROTECTED]>**20080111160045] 
[Conflict backup files are boring.
Trent W. Buck <[EMAIL PROTECTED]>**20080110163822] 
[more boring extensions
[EMAIL PROTECTED]
 Added extensions for CLISP, CMUCL, and "part" files which result in
 failed KDE copy operations.
] 
[resolve conflict in Libwww.
David Roundy <[EMAIL PROTECTED]>**20080110234609] 
[Some error reporting for libwww.
Dmitry Kurochkin <[EMAIL PROTECTED]>**20080110221921] 
[add optional support for using the pure haskell Network.HTTP http implementation
John Meacham <[EMAIL PROTECTED]>**20080110215859] 
[make darcs-2 repositories store patches in more-nicely-formated format
David Roundy <[EMAIL PROTECTED]>**20080110220413] 
[fix filename encoding issue in ShowFiles.
David Roundy <[EMAIL PROTECTED]>**20080110204120] 
[add debug message when grabbing files using libcurl.
David Roundy <[EMAIL PROTECTED]>**20080110202200] 
[make using libwww no longer the default, even if it's present.
David Roundy <[EMAIL PROTECTED]>**20080110195753
 There is a bug in our libwww bindings that I haven't located... if it isn't
 fixed, we should definitely remove this binding before the darcs 2.0
 release.
] 
[make Libwww.copyUrls provide debug output.
David Roundy <[EMAIL PROTECTED]>**20080110195733] 
[test: Exibit a falling test about rollback.
[EMAIL PROTECTED]
 Indeed  the only test about rollback was br0ken by a prior test that creates a
 directory  and  remove  read  permissions  to  it.  The  rollback test do some
 records  that  silently  fail  by lack of permissions, finally the rollback is
 cancelled since the named patch doesn't exist.
 This shows that rollback need some care.
] 
[Canonize Gwern Branwen, Nicolas Pouillard, Eric Kow.
Eric Kow <[EMAIL PROTECTED]>**20080109152727] 
[Eliminate configure test for Text.PrettyPrint.
Eric Kow <[EMAIL PROTECTED]>**20080109152927] 
[Use our own Printer instead of Text.PrettyPrint (make_changelog).
Eric Kow <[EMAIL PROTECTED]>**20080109172910] 
[Add parens functionality to the printer code.
Eric Kow <[EMAIL PROTECTED]>**20080109144956] 
[issue567: regression test for moving a file to the same location as itself
Mark Stosberg <[EMAIL PROTECTED]>**20080109032346] 
[restore behavior where we display conflicts in --summary mode.
David Roundy <[EMAIL PROTECTED]>**20080110004605] 
[regression test for issue406
Mark Stosberg <[EMAIL PROTECTED]>**20080109044500] 
[fix latex bug in docs.
David Roundy <[EMAIL PROTECTED]>**20080108211102] 
[fix latex bug in docs.
David Roundy <[EMAIL PROTECTED]>**20080108205912] 
[fix bug in show_tags.sh cleanup.
David Roundy <[EMAIL PROTECTED]>**20080108204430] 
[doc,typo: some s/darcs commit/darcs record/
[EMAIL PROTECTED] 
[test: Add a test for darcs show tags.
[EMAIL PROTECTED] 
[document the three repo format flags for "darcs init"
Mark Stosberg <[EMAIL PROTECTED]>**20080108041024] 
[improve the one-paragraph docs for "darcs init"
Mark Stosberg <[EMAIL PROTECTED]>**20080108040941] 
[Quit defining inventory format options recursively. Provide user-oriented descriptions.
Mark Stosberg <[EMAIL PROTECTED]>**20080108035256] 
[update partial.sh to show off improved darcs-2/partial functionality
Mark Stosberg <[EMAIL PROTECTED]>**20080108024712] 
[typo and bug fix in partial.sh.
Mark Stosberg <[EMAIL PROTECTED]>**20080108022808
 
 It turned out the call to "darcs optimize" was silently failing to create a checkpoint
 because there was no tag. This caused the remaining tests for --partial to run against 
 a full repo, not a partial one. 
] 
[issue55: document that darcs handles some types of binary files automatically. 
Mark Stosberg <[EMAIL PROTECTED]>**20080108010043] 
[correct apparent typo in test.
Mark Stosberg <[EMAIL PROTECTED]>**20080108005710
     The fix made more sense than the former behavior of comparing a file to itself. 
] 
[issue395: eliminate patches with a single character name from shell scripts in the test suite.
Mark Stosberg <[EMAIL PROTECTED]>**20080106051821] 
[prevent warning in test script and remove mysterious exit(1) call.
Mark Stosberg <[EMAIL PROTECTED]>**20080106052622] 
[issue526: improve Perl test suite.
Mark Stosberg <[EMAIL PROTECTED]>**20080106045548
     - better compatibility when path to darcs includes a space
     - better portability by eliminating some system calls
     - general style improvements
] 
[minor white-space and code style improvements
Mark Stosberg <[EMAIL PROTECTED]>**20080105183641] 
[typo fix on GNUmakefile comment
Mark Stosberg <[EMAIL PROTECTED]>**20080105183027] 
[refactor: improve style and portability of pull.pl test script.
Mark Stosberg <[EMAIL PROTECTED]>**20080105181751
     Many direct system calls were eliminated. No functional changes.  
] 
[issue347 - document that single quotes should be used in .darcs/defaults
Mark Stosberg <[EMAIL PROTECTED]>**20080101164428] 
[add feature requested in issue576.
David Roundy <[EMAIL PROTECTED]>**20080105150125] 
[fix bug in issue576.
David Roundy <[EMAIL PROTECTED]>**20080105144929] 
[add test that triggers bug in issue576.
David Roundy <[EMAIL PROTECTED]>**20080105144812] 
[Make sure we test the 'darcs' we just built and not one in a global path.
Mark Stosberg <[EMAIL PROTECTED]>**20080102002235
     This done by using "$DARCS" instead of 'darcs'.
     However, in my case the updated test FAILS unexplainably with 2.0.0pre3,
     by failing to detect that a file has changed. 
     If I follow along in a shell and run the same commands with Darcs 2, 
     the problem does not appear. 
] 
[add configure support for libwww.
David Roundy <[EMAIL PROTECTED]>**20080104201255] 
[make bug message more explicit.
David Roundy <[EMAIL PROTECTED]>**20080104004253] 
[Initial implementation of HTTP pipelining using libwww.
Dmitry Kurochkin <[EMAIL PROTECTED]>**20071222144902] 
[make indent slightly more concise using lines and unlines.
David Roundy <[EMAIL PROTECTED]>**20080104003953] 
[refactor: replace recursive indent with more concise find-and-replace syntax
Mark Stosberg <[EMAIL PROTECTED]>**20080101200447] 
[simplify (and debug) pending handling.
David Roundy <[EMAIL PROTECTED]>**20071227133618
 Note that this change could lead to performance regressions, but I believe
 that these regressions would be strongly bounded (never worse than a
 whatsnew), and this simplification makes the code much easier to safely
 modify.
] 
[make updating of pending on pull much more efficient.
David Roundy <[EMAIL PROTECTED]>**20071224131059] 
[simplify a bit of code.
David Roundy <[EMAIL PROTECTED]>**20071224131023] 
[fix type-witness bug in HopefullyPrivate.
David Roundy <[EMAIL PROTECTED]>**20071223141149] 
[simplify Get
David Roundy <[EMAIL PROTECTED]>**20071223025108] 
[simplify tentativelyAddPatch by removing unused return value.
David Roundy <[EMAIL PROTECTED]>**20071223024400] 
[simplify away np2prims and nps2prims.
David Roundy <[EMAIL PROTECTED]>**20071223022145] 
[try to avoid rewriting patches that we've just read.
David Roundy <[EMAIL PROTECTED]>**20071222190029] 
[generalize CommandsAux utility functions.
David Roundy <[EMAIL PROTECTED]>**20071222162952] 
[add new instances for PatchInfoAnd.
David Roundy <[EMAIL PROTECTED]>**20071222144439] 
[change tentativelyAddPatch to accept a PatchInfoAnd p.
David Roundy <[EMAIL PROTECTED]>**20071222140517] 
[internal prepration for optimization saving patch writing.
David Roundy <[EMAIL PROTECTED]>**20071222134834] 
[add changelog entry.
David Roundy <[EMAIL PROTECTED]>**20071219162646] 
[add fixme indicating where the code could be simplified.
David Roundy <[EMAIL PROTECTED]>**20071221135649] 
[make reading of hashed inventories lazier.
David Roundy <[EMAIL PROTECTED]>**20071221133453] 
[resolve conflicts in mv_and_remove_tests.sh.
David Roundy <[EMAIL PROTECTED]>**20071219144638] 
[Fix !(...|...) in mv_and_remove_tests.sh.
Dave Love <[EMAIL PROTECTED]>**20071218001826
 Assume the original construct should have been `! ... | ...' and
 replace with a portable version of that.
] 
[[issue571] Redo last HAVE_TERMIO_H fix.
Dave Love <[EMAIL PROTECTED]>**20071218140508
 Not the most direct fix, but simpler.
] 
[Fix configure test for gadt type witnesses.
Dave Love <[EMAIL PROTECTED]>**20071218120139] 
[use --ignore-times in all tests.
David Roundy <[EMAIL PROTECTED]>**20071217225159
 This is because the hashed repository is a bit pickier, in that
 it no longer checks file lengths when the file modification times
 match.
] 
[enable modification time checking on hashed repositories.
David Roundy <[EMAIL PROTECTED]>**20071217220237] 
[Pass two args to `cmp' in tests, following POSIX.
Dave Love <[EMAIL PROTECTED]>**20071216180503
 Fixes some failures on Solaris.
] 
[resolve silly conflict with myself.
David Roundy <[EMAIL PROTECTED]>**20071217200855] 
[clean up SelectChanges (eliminating Bools)
David Roundy <[EMAIL PROTECTED]>**20071217191809] 
[make a few more files compile with type witnesses.
David Roundy <[EMAIL PROTECTED]>**20071217183234] 
[fix bug in revert (in writing the unrevert file).
David Roundy <[EMAIL PROTECTED]>**20071216215225] 
[make a few more files compile with type witnesses.
David Roundy <[EMAIL PROTECTED]>**20071217164815] 
[remove tabs.
David Roundy <[EMAIL PROTECTED]>**20071216224617] 
[bump version number preemptively to 2.0.0pre3.
David Roundy <[EMAIL PROTECTED]>**20071216222823] 
[fix doc bug in show contents.
David Roundy <[EMAIL PROTECTED]>**20071216214002] 
[TAG 2.0.0pre2
David Roundy <[EMAIL PROTECTED]>**20071216201647] 
Patch bundle hash:
6461c6bfbd42ddd13205e5725388200dc8b6fe9c
_______________________________________________
darcs-devel mailing list
darcs-devel@darcs.net
http://lists.osuosl.org/mailman/listinfo/darcs-devel

Reply via email to