#!/bin/sh
# $Id: apt-proxy-import,v 1.16.2.2 2002/11/15 15:39:19 haggai Exp $
# Import package files from incoming directories
#
# Copyright 2002 Chris Halls <halls@debian.org>
#                Manuel Estrada Sainz <ranty@debian.org>
#           GPLv2 or higher
#
# Use: apt-proxy-import directory-name ...
#
PROGNAME=apt-proxy-import
VERSION=0.4
CONFIG_FILE=/etc/apt-proxy/apt-proxy.conf
EXACT_MOVING=on
FUZZY_MATCHING="packages fuzzy_packages"
echo=/bin/echo
DPKG_NAME=/usr/bin/dpkg-name

usage()
{
  echo "Usage: $PROGNAME [OPTIONS] <directory> ..."
  echo
  echo "apt-proxy-import imports .deb files into the apt-proxy cache."
  echo
  echo "$PROGNAME should be run as the aptproxy user, or as " \
	"root  so  that  it  can  set  the  file permissions on the " \
	"imported files in the cache directory."
  echo
  echo "apt-proxy-import's command option summary:"
  echo
  $echo -e "  <directory>\t\t\t directory containing files to import."
  echo
  $echo -e "             \t\t\t e.g.: /var/cache/apt/archives"
  echo
  $echo -e "  -c, --config-file=config_file  set location of apt-proxy " \
  	   "configuration file\n" \
	   "                                where backend directories" \
	   " are defined.\n\n"\
	   "                                (default: $CONFIG_FILE)" 
  echo
  $echo -e "  -d, --verbose\t\t\t give verbose output"
  $echo -e "  -D, --debug\t\t\t debug mode (don't delete link dir, implies -v)"
  $echo -e "  -h, --help\t\t\t show this help, then exit"
  $echo -e "  -v, --version\t\t\t print version number, then exit"
  echo
  echo 
  echo "Report bugs to Debian's Bug Tracking System:"
  echo 
  echo "First checkout reported bugs at http://bugs.debian.org/apt-proxy"
  echo "and then if you still wish to report a bug  in  apt-proxy, please"
  echo "see /usr/share/doc/debian/bug-reporting.txt or the reportbug(1)"
  echo "command."
}

line_feedback()
{
	local LINE
	while read LINE
	do
		if [ -n "$VERBOSE" ] ;then
			echo "$LINE"
		else
			echo -n "."
		fi
	done
	echo
}

mirrorpaths_packages()
{
	local filename="$1"
	grep -h "/$filename " $BACKENDS* | cut -f1 -d' ' | uniq
}

mirrorpaths_fuzzy_packages()
{
	local filename="$1"
	local packagename=$(expr $filename : '\([^_]*\)_')
	local rest=$(expr $filename : '[^_]*\(_.*\)$')

	grep -h "/${packagename}_[^ ]*\.deb " $BACKENDS* | cut -f1 -d' ' \
		| uniq | sed -e "s/_[^/]*\.deb/$rest/" 
}

mirrorpaths_deb()
{
	#This funcion is not finished
	local $filename="$1"
	unset SECTION VERSION SOURCE NAME ARCH
	eval $( dpkg --info $filename | \
		sed \
			-e's/^ Section: */SECTION=/p' \
			-e's/^ Version: *\(.*:\)\?/VERSION=/p' \
			-e's/^ Source: *\([^ ]*\).*$/SOURCE=\1/p' \
			-e's/^ Package: */NAME=/p' \
			-e's/^ Architecture: */ARCH=/p' \
			-n \
		)

	[ "$SOURCE" ] || SOURCE=$NAME
	case $SOURCE in
		lib*) HASH=`expr $SOURCE : '\(....\)'` ;;
		*) HASH=`expr $SOURCE : '\(.\)'` ;;
	esac
	case $SECTION in
		contrib*)	SECTION=contrib ;;
		non-free*)	SECTION=non-free ;;
		non-US*|non-us*)SECTION=non-US/main ;;
		*) SECTION=main;;
	esac
	echo "pool/$SECTION/$HASH/$SOURCE/$filename"
}
mirrorpaths()
{
	local filename="$1"
	if [ "$EXACT_MOVING" != "off" ] ;then
		mirrorpaths_packages "$filename"
		return
	else
		for method in $FUZZY_MATCHING
		do
			MIRRORPATHS=$(mirrorpaths_$method $filename)
			if [ -n "$MIRRORPATHS" ] ;then
				echo "$MIRRORPATHS"
				return
			fi
		done
	fi

}

add_backend()
{
    if [ -n "`ls $2.apt-proxy-filelists/* 2>/dev/null`" ] ;then
        BACKENDS="$BACKENDS $2.apt-proxy-filelists/*"
    else
        info "Backend $2 does not have filelists - skipped"
    fi
}

# Given a directory, print out all the parents in forwards order.
# (taken from apt-proxy)
#	directories(pathname)
directories()
{
    DR_TOTAL=""
    for dr_d in `echo $1 | tr / ' '`; do
	DR_TOTAL="$DR_TOTAL/$dr_d"
	echo "$DR_TOTAL"
    done
}

info()
{
    [ -n "$VERBOSE" ] && echo "$@"
}

unset VERBOSE

# Parse command line
ARGS=`getopt -o e:c:hvdD --long \
	exact:,config-file:,help,version,verbose,debug \
	-n "$0" -- "$@"`
if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
eval set -- "$ARGS"
while true ; do
	case "$1" in
	  '-c'|'--config-file')
		CONFIG_FILE="$2"
		shift 2
		;;
	  '--version'|'-v')
  		echo "$PROGNAME $VERSION"
                exit 1
                ;;
	  '-h'|'--help')
                usage
                exit 1
                ;;
	  '-d'|'--verbose')
		VERBOSE=1
		shift
		;;
	  '-D'|'--debug')
	        VERBOSE=1
	  	DEBUG=1
		shift
		;;
	  '-e'|'--exact')
	  	EXACT_MOVING="$2"
		shift 2
		;;
	  '--')
 		# end of options
                shift
                break
		;;
	  *)
	  	echo "Internal error!"
		exit 1
		;;
	esac
done

[ $# -eq 0 ] && usage && exit 1

. $CONFIG_FILE

if [ ! -x "$DPKG_NAME" ];then
  echo "$PROGNAME: $DPKG_NAME not found - please install package dpkg-dev"
  exit 1
fi

if [ -z "$BACKENDS" ]; then
  echo "$PROGNAME: No backend filelists found."
  exit 1
fi

for directory in $@; do

    if [ ! -d "$directory" ]; then
        echo "directory not found:$@" 
	continue
    elif [ "`echo $directory/*.deb`" = "$directory/*.deb" ]; then
	# no .debs in directory
	info $directory: no files 
	continue
    fi

    info Clearing temporary directory "$APT_PROXY_CACHE/dpkg-name.links"
    rm -rf "$APT_PROXY_CACHE/dpkg-name.links/"
    mkdir "$APT_PROXY_CACHE/dpkg-name.links/"
    echo -n "$directory: "

    #Make sure that we use the correct names
    #about dpkg-name:
    #	The best we could get out of dpkg-name, without renaming the files on
    #	place, was making symlinks with the right name on a certain directory,
    #	and that is the reason for creating "$APT_PROXY_CACHE/dpkg-name.links/"
    #   Unfortunately, dpkg-name from potato does not support the -k option, so
    #   we have to copy the files instead before renaming
    if ($DPKG_NAME -k 2>&1) | grep -q "can't find \`-k'"; then
        # dpkg-name from potato does not support -k
	info Copying debs to temporary directory
	cp "$directory"/*.deb "$APT_PROXY_CACHE/dpkg-name.links"
        $DPKG_NAME "$APT_PROXY_CACHE/dpkg-name.links"/*.deb | line_feedback
    else
        # Use dpkg-name to create links
	info Creating links with correct names with dpkg-name

	if ! expr "$directory" : '/' > /dev/null; then
		# dpkg-name doesn't handle relative pathnames, so we make sure
		# that $directory is an absolute pathname
		directory="$PWD/$directory"
	fi
        $DPKG_NAME -k -s "$APT_PROXY_CACHE/dpkg-name.links" "$directory"/*.deb \
	    | line_feedback
    fi

    if [ -n "$DEBUG" ]; then
        echo Contents of $APT_PROXY_CACHE/dpkg-name.links:
	ls -l "$APT_PROXY_CACHE"/dpkg-name.links
    fi

    for file in "$APT_PROXY_CACHE"/dpkg-name.links/*; do

    	filename=`basename $file`
	
	case "$filename" in
	*.deb)
	    cachepaths=`mirrorpaths "$filename"`

	    if [ -n "$cachepaths" ]; then

		for f in $cachepaths; do

		    dirname=`dirname $f`
		    if [ ! -d "$dirname" ]; then
			info "Making directory $dirname"
			unset DR_LAST
			for DR in `directories $dirname`; do
			  if [ -d "$DR_LAST" -a ! -d "$DR" ]; then
			    mkdir "$DR" &&
			    chown --reference "$DR_LAST" "$DR" ||
				  echo "mkdir+chown $DR FAILED"
			  fi
			  DR_LAST="$DR"
			done
		    fi

		    if [ -f $f ]; then
			info "Skipping $filename - already in directory $dirname"
		    else
			echo "importing $filename"
			cp -p "$file" "$f" &&
			  chown --reference "$dirname" "$f" ||
			      echo "cp+chown $file $f FAILED"
		    fi
		done
	    else
		echo "skipped $filename"
	    fi
	    ;;
	 *)
	    info "Skipping $filename - unsupported type"
	 esac
    done
    # remove directory if not debugging
    [ -z "$DEBUG" ] && rm -rf "$APT_PROXY_CACHE/dpkg-name.links/"
done

exit 0

        


