#!/usr/bin/perl

# $USAGI: prepare.pl,v 1.5 2002/04/03 03:18:50 yoshfuji Exp $

# Copyright (C) 2001 USAGI/WIDE Project.
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 3. Neither the name of the project nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

use Getopt::Std;

$DoUnlink = 0;
$Quiet = 0;

sub dig {
	my ($base, $target) = @_;
	my @dir;
	opendir(DIR, "$target") || die("Cannot open directory $target: $!\n");
	@dir = readdir(DIR);
	closedir(DIR);
	foreach $file (@dir) {
		if (-l "$target/$file") {
			next unless ($DoUnlink);
			print "unlink $target/$file" unless ($Quiet);
			unless (unlink("$target/$file")) {
				if ($Quiet) {
					print STDERR "$target/$file: $!\n";
				} else {
					print(": failed, $!\n");
				}
				exit(1);
			}
			print("\n") unless($Quiet);
			next;
		} elsif (-d "$target/$file"){
			next if ($file eq '.' || $file eq '..');
			&dig("../$base", "$target/$file");
		}
	}
	return if ($DoUnlink);
	if (-f "$target/.prepare") {
		open(IN, "<$target/.prepare") || next;
		while ($src = <IN>) {
			my ($basename, $targetfile, $force);
			chomp;
			next if ($src =~ /^\#/);
			$src =~ s/\/+/\//g;
			$src =~ s/\/?\s*$//;
			$src =~ s/^\s+//;
			next unless (length($src));
			if ($src =~ s/^force\s+//) {
				$force = 1;
			}
			if ($src =~ s/^rename\s+(\S+)\s+(\S+)//) {
				($src, $basename) = ($1, $2);
				if ($basename =~ m|/|) {
					die("$basename is invalid\n");
				}
			} else {
				($basename = $src) =~ s/.*\///;
			}
			$srcfile = "$base/$src";
			$targetfile = "$target/$basename";
			unlink $targetfile if (-l $targetfile || ($force && -f $targetfile));
			print "symlink $srcfile $targetfile" unless ($Quiet);
			unless (symlink("$srcfile", "$targetfile")) {
				if ($Quiet) {
					print STDERR "$targetfile: $!\n";
				} else {
					print(": failed, $!\n");
				}
				exit(1);
			}
			print("\n") unless ($Quiet);
		}
		close(IN);
	}
}

getopts('rq');
$DoUnlink = $opt_r;
$Quiet = $opt_q;

if (@ARGV != 2) {
	die("Usage: $0 src dst\n");
}

($src, $dst) = @ARGV;
foreach ($src, $dst){
	s/\/+/\//;
	s/\/$//;
}
die("$dst/$src: directory not found\n") unless (-d "$dst/$src");

&dig($src, $dst);

exit(0);

