#!/usr/bin/perl -w

# KDE-enhanced version of the mv, cp, and rm commands
# By Scott Pakin <pakin@uiuc.edu>
#
# If any arguments look like a URL, defer to kfmclient.  Otherwise, defer
# to mv/cp/rm.

###########################################################################
# Copyright (c) 2000, Scott Pakin					  #
# 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. Scott Pakin's name may be used to endorse or promote products	  #
# 	 derived from this software without specific prior written	  #
# 	 permission.							  #
# 									  #
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``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 REGENTS 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.				  #
###########################################################################

require 5.0;
use Cwd 'abs_path';
use Getopt::Long;
use File::Basename;

# Determine which command to emulate.
if ($0 =~ /mv/) {
    $unixcmd = "mv";
    $kfmcmd = "move";
    $helpstr = "Usage: $0 [OPTION]... SOURCE DEST
  or:  $0 [OPTION]... SOURCE... DIRECTORY
  or:  $0 SOURCE|URL... DEST|DIRECTORY|URL\n";
}
elsif ($0 =~ /cp/) {
    $unixcmd = "cp";
    $kfmcmd = "copy";
    $helpstr = "Usage: $0 [OPTION]... SOURCE DEST
  or:  $0 [OPTION]... SOURCE... DIRECTORY
  or:  $0 SOURCE|URL... DEST|DIRECTORY|URL\n";
}
elsif ($0 =~ /rm/) {
    $unixcmd = "rm";
    $kfmcmd = "move";       # NOTE: "Remove" means "move to trash".
    $helpstr = "Usage: $0 FILE|URL...\n";
}
else {
    die "${0}: Do not run this program directly.
${0}: Instead, access it through links named kmv, kcp, and krm.\n";
}


# Process the --help option specially.
my $help = 0;
my @oldARGV = @ARGV;
GetOptions ("help", \$help);
if ($help) {
    print $helpstr;
    exit 0;
}
@ARGV = @oldARGV;

# Take different actions depending on whether any argument is a URL.
if (scalar(grep(m|:/|,@ARGV)) ||
    $unixcmd eq "rm") {       # URL or "rm" command -- use kfmclient.
    # kfmclient doesn't take any options; complain if the user gave us some.
    Getopt::Long::Configure ("permute", "pass_through");
    my @arguments;
    GetOptions ("help" => \$help,      # GetOptions needs at least one option.
		"<>" => sub {
		    die "${0}: all options are forbidden in KDE mode\n" if $_[0]=~/^-/;
		    push @arguments, $_[0];
		});
    push @arguments, @ARGV;
    push @arguments, "trash:/" if $unixcmd eq "rm";

    # "kfmclient move" and "kfmclient copy" behave differently from mv/cp
    # when the destination is a directory and there is only one source
    # argument.  mv/cp put the source *into* the destination, while
    # "kfmclient move/copy" try to move the source *onto* the destination
    # (and fail if the destination already exists.  Our kludgy workaround
    # is to add an extra, empty filename to move/copy to the source list if
    # the target looks like a directory.  This tricks KFM into moving
    # *into* the destination, but when it comes time to do so, it doesn't
    # see the empty argument.  The problem with this technique -- besides
    # relying on behavior that's apt to change someday -- is that we can't
    # test for existence of URLs besides "file:/" URLs.
    my $destination = $arguments[$#arguments];
    $destination =~ s|^file:||;
    my $emptyarg = ($#arguments == 1 &&
		    ($destination=~m|/$| || -d $destination));

    # Convert all non-URLs to absolute paths.
    foreach (@arguments) {
	next if m|:/| || m|^/$|;       # URL or root directory
	$_ = abs_path(dirname($_)) . "/" . basename($_);
    }

    # Perform the move/copy.
    splice (@arguments, $#arguments, 1, ("", $arguments[$#arguments])) if $emptyarg;
    exec 'kfmclient', $kfmcmd, @arguments;
}
else {                                 # No URL -- use mv/cp/rm.
    exec {$unixcmd} ($0, @ARGV);
}
