Well, I got Koha up and running! I wrote a script to help me link up all the CVS directories to the installed locations. I had to steal a few files from a Koha installed from the tarball, and update my database, so I added checks for those in the script. Here is my script (link_cvskoha.pl): #!/usr/bin/perl # See http://www.saas.nsw.edu.au/koha_wiki/index.php?page=CVSSymLinkInstallation # for more information about running Koha using symlinks to CVS use Getopt::Long; my %param = (); GetOptions(\%param, 'cvs=s', 'opac=s', 'intranet=s'); sub usage { print qq{Usage: link_cvskoha.pl --cvs SOURCE_DIR --intranet DIR --opac DIR --cvs Directory where Koha CVS is (like sandbox/koha) --intranet Directory where webserver looks for intranet files (defaults to /usr/local/koha/intranet) --opac Directory where webserver looks for opac files (defaults to /usr/local/koha/opac)\n\n}; exit; } my $cvs = $param{cvs} || usage(); my $opac = $param{opac} || '/usr/local/koha/opac'; my $intranet = $param{intranet} || '/usr/local/koha/intranet'; my %map = ( # CVS module => installed location '' => $intranet . '/cgi-bin', 'koha-tmpl/intranet-tmpl' => $intranet . '/htdocs/intranet-tmpl', 'C4' => $intranet . '/modules/C4', 'opac' => $opac . '/cgi-bin', 'koha-tmpl/opac-tmpl' => $opac . '/htdocs/opac-tmpl', 'koha-tmpl/opac.html' => $opac . '/htdocs/index.html', 'koha-tmpl/intranet.html' => $intranet . '/htdocs/index.html', 'z3950' => $intranet . '/scripts/z3950daemon', 'updater' => $intranet . '/scripts/updater', 'misc' => $intranet . '/scripts/misc', 'marc' => $intranet . '/scripts/marc', ); my %necessary_files = ( # filename => description '/etc/koha.conf' => 'Koha configuration file', '/etc/koha-httpd.conf' => 'Koha webserver configuration', $map{z3950} . '/z3950-daemon-options' => 'Z39.50 daemon configuration', ); # make sure opac and intranet directories exist foreach my $dir ($opac, $intranet) { (my $subdir = $dir) =~ s|\/[^/]*$||; unless (-d $subdir) { system("mkdir $subdir"); chmod(0755, $subdir); } unless (-d $dir) { system("mkdir $dir"); chmod(0755, $dir); } } # loop through CVS module names and create links foreach my $dir (keys %map) { my $source = $cvs . '/' . $dir; my $dest = $map{$dir}; # remove previous links if (-e $dest) { local $| = 1; print "$dest already exists. Overwrite? [y/N]: "; my $response = <STDIN>; chomp($response); if (uc($response) eq 'Y') { if (system("rm -rf $dest")) { print " FAILED to remove $dest: $!\n"; } } else { next; } } # ensure directory for storing links exists (my $subdir = $dest) =~ s|\/[^/]*$||; unless (-d $subdir) { system("mkdir $subdir"); chmod(0755, $subdir); } # link from CVS to installed location print "ln -s $source $dest\n"; if (system("ln -s $source $dest")) { print " FAILED to create link: $!\n"; } } # alert user if necessary files are missing foreach my $file (keys %necessary_files) { unless (-e $file) { print "Cannot find $necessary_files{$file}: $file\n"; } } print "Make sure to run " . $map{updater} . "/updatedatabase\n";