#!/bin/bash
#
# apt-cachemove
#
#	move debs from the pointed dir to the apt-proxy backends, generating
#	the correct tree.
#
# Authors:	Guillem Jover <guillem@hadrons.org>
#
# License:
#
#	Copyright (C) 2002 Guillem Jover
#
#	This program is free software; you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation; either version 2 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with this program; if not, write to the Free Software Foundation,
#	Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
#

#
# usage: apt-cachemove destination_proxy_dir cache_dir
#

CACHE_DIR=/var/cache/apt/archives
PROXY_DIR=/var/cache/apt-proxy

PROGNAME=apt-cachemove
PACKAGES_TMP=/tmp/$PROGNAME.$$

PROXY_USER=aptproxy
PROXY_UMASK=022

# Functions

#
# Begin: blatanly ripped from apt-proxy (maybe split a lib functions file)
#

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

# Echo the version compenent of a deb filename.
# deb_version(file)
deb_version ()
{
    b=`basename $1`
    ver=`expr $b : '[^_]*_\([^_]*\)_[^_]*\.deb'`
    [ -n "$ver" ] || ver=`expr $b : '[^_]*_\([^_]*\)\.deb'`
    echo $ver
}

# Echo the architecture compenent of an absolute deb filename.
# deb_arch(file)
deb_arch ()
{
    b=`basename $1`
    arch=`expr $b : '[^_]*_[^_]*_\([^_]*\)\.deb'`
    [ -n "$arch" ] || arch=`expr $1 : '.*/binary-\([^/]*\)/.*'`
    echo $arch
}

# Echo the base part of an absolute deb filename.
# The trailing _ is important, since it acts as an anchor.
# deb_base(file)
deb_base ()
{
    echo `dirname $1`/`basename $1 | cut -d_ -f1`_
}

#
# End of stolen funcitons
#

usage() {
	echo "$PROGNAME [dest_dir [cache_dir]]"
	exit	
}

error() {
	echo "$PROGNAME: error $@"
	exit
}

#
#
make_dirtree() {
	PARTIAL_MIRROR=$1
	PKG_PATH=$2

	if [ ! -d $PARTIAL_MIRROR ]; then
		error "partial mirrors not setup"
	fi

	pushd `pwd` > /dev/null
	cd $PARTIAL_MIRROR

	for d in `directories $PKG_PATH`; do
		if [ ! -d $d ]; then
			mkdir $d
			chown $PROXY_USER $d
		fi
	done

	popd > /dev/null
}

# $1 Packages
# $2 partial_mirror
move_debs() {
	local PACKAGES=$1
	local PARTIAL_MIRROR=$2

	grep "^Filename: " $PACKAGES | sed -e 's/^Filename: //' > $PACKAGES_TMP
	
	for pkg in *.deb; do
		pkg_path_normalized=$(echo $pkg|sed -e 's/_[0-9]*%3a/_/')
		pkg_path=$(grep /$pkg_path_normalized $PACKAGES_TMP)
		if [ -n "$pkg_path" ]; then
			local dest_dir=`echo $pkg_path|sed -e 's:/[^/]*$::'`
			echo "Moving: $pkg to $partial_mirror/$dest_dir"
			make_dirtree $partial_mirror $dest_dir
			mv $pkg $partial_mirror/$dest_dir/
			chown $PROXY_USER $partial_mirror/$pkg_path
		fi
	done
}

clean() {
	echo "Removing $PACKAGES_TMP"
	rm $PACKAGES_TMP
	exit
}

# Program Start

#[ $# -lt 2 ] && echo "error: too few args" && usage

trap clean INT QUIT
umask $PROXY_UMASK
cd $CACHE_DIR

for partial_mirror in $PROXY_DIR/*; do
	if [ ! -d $partial_mirror/dists ]; then continue; fi

	echo "Entering $partial_mirror mirror"
	for distro in $partial_mirror/dists/*; do
		if [ -L $distro ]; then continue; fi

		echo "Entering $distro distribution"
		for component in $distro/* $distro/non-US/* $distro/security/*; do

			echo "Entering $component component"
			for arch in $component/binary-*; do

				if [ ! -f $arch/Packages ]; then 
					if [ ! -f $arch/Packages.gz ]; then
						continue
					else
						zcat $arch/Packages.gz > $arch/Packages
					fi
				fi

				echo "Entering $arch arch"
				move_debs $arch/Packages $partial_mirror
				echo "Exiting $arch arch"
			done
			echo "Exiting $component component"
		done
		echo "Exiting $distro distribution"
	done
	echo "Exiting $partial_mirror mirror"
done

clean
