#!/bin/bash

# A simple tool to grab and extract debian-installer netboot images.
#
# Copyright (C) 2008 Frank Lin PIAT <fpiat@klabs.be>
# latest version is available from:
#     http://www.klabs.be/~fpiat/linux/debian/di-netboot-assistant/
#
# This file 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., 51 Franklin St - Suite 330, Boston, MA 02110, USA.

# Initialize some variables.
PACKAGE_NAME=di-netboot-assistant
PACKAGE_VERSION=0.36b
OFFLINE=
DEBUG=
DISOURCELIST=/etc/di-netboot-assistant/di-sources.list
SYSLINUXMENU=menu.c32
SYSLINUX=/usr/lib/syslinux/
ELILO=/usr/lib/elilo/
DL_CACHE=/var/cache/di-netboot-assistant/
TFTP_ROOT=/var/lib/tftpboot
REWRITEPKGPATH='\(debian\|ubuntu\)-installer'
UMASKOLD=`umask -p`
EXTRA_DL_FILES="MD5SUMS"
#MIRROR_REGEXPS=# Not defined on purpose, so user can pass the variable
umask 0022

if [ -f /etc/di-netboot-assistant/di-netboot-assistant.conf ]; then
	. /etc/di-netboot-assistant/di-netboot-assistant.conf
fi

# Declare some functions
usage () {
	cat <<XXX
Usage: $PACKAGE_NAME [options] install DI-DIST [--offline] [--arch=ARCH]
       $PACKAGE_NAME [options] purge DI-DIST [--arch=ARCH]
       $PACKAGE_NAME [options] rebuild-menu
       $PACKAGE_NAME [--help|--version|--rebuild-menu]

A simple tool to grab and extract debian-installer netboot images.

DI-DIST 
	The name of a debian-installer repository (as listed in
	the file '$DISOURCELIST')

Commands:
    install - download and extract a netboot image.
    purge - remove a previously installed netboot image.
    rebuild-menu - rebuild the top level menu.

Options:
  -h, --help      Print this message and exit
  -v, --version   Print script version and exit
  --verbose       Verbose messages
  --offline       Don't download the file (simply re-extract and build menu)
  --arch=ARCH     A comma separated list of architecture to Install/Purge,
                  or the keyword "all". It use the current machine's
                  architecture by default (APT::Architecture).

See the $PACKAGE_NAME(1) manual page for more information.
XXX
}

check_di_source_list() {
	if [ ! -f "$DISOURCELIST" ]; then
		echo "E: Debian Installer source file missing ($DISOURCELIST)" 1>&2
		echo "" 1>&2
		exit 1;
	fi

	if grep -vEl '^(#.*|[[:blank:]]*|[[:alnum:]_\.-]+[	][[:alnum:]_\.-]+[	][^	]+([	][^" ]+)+)$'  "$DISOURCELIST" > /dev/null ; then
		echo -n "E: Syntax error lines #"  1>&2
		grep -vnE '^(#.*|[[:blank:]]*|[[:alnum:]_\.-]+[	][[:alnum:]_\.-]+[	][^	]+([	][^" ]+)+)$' "$DISOURCELIST" | cut -d ":" -f 1 | tr "\n" "," 1>&2
		echo " in file '$DISOURCELIST'." 1>&2
		echo "" 1>&2
		exit 1;
	fi
}

list_declared_arch_for_repo() {
	echo -n "I: Declared architecures for $1 are: " 1>&2
	grep -E "^$1[[:blank:]]" "$DISOURCELIST" | cut -f 2 | sort -u | tr '\n' ' ' 1>&2
	echo "" 1>&2
}

print_do-not-edit_header() {
	echo "##"
	echo "## DO NOT EDIT THIS FILE"
	echo "##"
	echo "## It is automatically generated by $PACKAGE_NAME using templates"
	echo "## from $1 "
	echo "##"
}

update_menu() {
	update_pxelinux_menu
	update_elilo_menu
}

update_pxelinux_menu() {

	[ ! -d "pxelinux.cfg" ] && mkdir "pxelinux.cfg"
	echo "I: Building PXE-Linux' top-menu"
	print_do-not-edit_header "/etc/di-netboot-assistant/pxelinux.HEAD" > pxelinux.cfg/default
	if [ -n "$(find "$TFTP_ROOT/debian-installer" -type d -name pxelinux.cfg.serial-9600 2>/dev/null)" ]; then
		cp pxelinux.cfg/default pxelinux.cfg/default.serial-9600
	else
		[ -f "pxelinux.cfg/default.serial-9600" ] && rm pxelinux.cfg/default.serial-9600
	fi
	[ -f /etc/di-netboot-assistant/pxelinux.HEAD ] && grep -Ev "^##" /etc/di-netboot-assistant/pxelinux.HEAD >> pxelinux.cfg/default

	i=0
	for x in $(ls /var/lib/di-netboot-assistant/*.pxelinux.menu.fragment 2>/dev/null ); do
		i=$(($i + 1))
		grep -Ev "^##" $x >> pxelinux.cfg/default
		echo "" >> pxelinux.cfg/default
	done
	[ $i -eq 0 ] && rm pxelinux.cfg/default

	i=0
	if [ -f "pxelinux.cfg/default.serial-9600" ]; then
		i=$(($i + 1))
		[ -f /etc/di-netboot-assistant/pxelinux.HEAD ] && cat /etc/di-netboot-assistant/pxelinux.HEAD >> pxelinux.cfg/default.serial-9600
		for x in /var/lib/di-netboot-assistant/*pxelinux.menu.serial-9600.fragment ; do
			grep -Ev "^##" "$x" >> pxelinux.cfg/default.serial-9600
			echo "" >> pxelinux.cfg/default.serial-9600
		done
		[ $i -eq 0 ] && rm pxelinux.cfg/default.serial-9600
	fi

	[ -d pxelinux.cfg ] && rmdir --ignore-fail-on-non-empty pxelinux.cfg
	if [ -d pxelinux.cfg ]; then
		if [ -f "$SYSLINUX/$SYSLINUXMENU" -a -f "$SYSLINUX/pxelinux.0" ]; then
			cp "$SYSLINUX/$SYSLINUXMENU" pxelinux.cfg/
			cp "$SYSLINUX/pxelinux.0" ./
		else
			echo "W: couldn't copy '$SYSLINUX/$SYSLINUXMENU' and/or '$SYSLINUX/pxelinux.0' to $PWD. Install the package syslinux." 1>&2
		fi
	fi
}

update_elilo_menu() {
	echo "I: Building Elilo's top-menu"
	print_do-not-edit_header "/etc/di-netboot-assistant/elilo.HEAD" > elilo.conf
	[ -f /etc/di-netboot-assistant/elilo.HEAD ] && grep -Ev "^##" /etc/di-netboot-assistant/elilo.HEAD >> elilo.conf

	i=0
	for x in $(ls /var/lib/di-netboot-assistant/*.elilo.conf.fragment 2>/dev/null ); do
		i=$(($i + 1))
		grep -Ev "^##" $x >> elilo.conf
		echo "" >> elilo.conf
	done

	if [ $i -eq 0 ]; then
		rm elilo.conf
	else
		if [ -f "$ELILO/elilo.efi" ]; then
			cp "$ELILO/elilo.efi" ./
		else
			echo "W: couldn't copy '$ELILO/elilo.efi' to $PWD. Install the package elilo." 1>&2
		fi
	fi
}

check_tftp_root() {
	if [ -z "$TFTP_ROOT" -o "$TFTP_ROOT" = "." -o "$TFTP_ROOT" = "/" ]; then
		echo "E: Invalid TFTP root specified ($TFTP_ROOT)" 1>&2
		echo "" 1>&2
		exit 1;
	fi

	if [ ! -d "$TFTP_ROOT" ]; then
		echo "E: TFTP root directory doesn't exists ($TFTP_ROOT)" 1>&2
		echo "I: Make sure you installed a tftp server like tftpd-hpa or atftpd." 1>&2
		echo "" 1>&2
		exit 1;
	fi

	[ ! -d "$TFTP_ROOT/debian-installer" ] && mkdir "$TFTP_ROOT/debian-installer"
	if [ ! -w "$TFTP_ROOT/debian-installer" ]; then
		echo "E: Can't write to DI directory ($TFTP_ROOT/debian-installer)" 1>&2
		echo "" 1>&2
		exit 1;
	fi
}

#This function should be kept in sync with function "purge_repo" in debian/postrm
purge_repo() {
	dist="$1"
	metadatabasename="$(echo $dist | sed -e 's/\.conf$//' )"

	tarfile="$(grep -E "^[[:blank:]]*dl_file=" "$dist" | sed -e 's/^[[:blank:]]*dl_file=//')"
	[ -f "$tarfile" ] && rm "$tarfile"

	expand_dir="$(grep -E "^[[:blank:]]*expand_dir=" "$dist" | sed -e 's/^[[:blank:]]*expand_dir=//')"
	[ "$expand_dir" != "/" -a -d "$expand_dir" ] && rm -Rf "$expand_dir"

	dist_dir="$(echo  "$expand_dir" | sed -e 's,/[^/]\+$,,')"
	rmdir --ignore-fail-on-non-empty "$dist_dir"

	di_dir="$(echo  "$dist_dir" | sed -e 's,/[^/]\+$,,')"
	[ -f "$di_dir/pxelinux.cfg/default" ] && grep -q "## DO NOT EDIT THIS FILE" "$di_dir/pxelinux.cfg/default" && rm "$di_dir/pxelinux.cfg/default"
	[ -f "$di_dir/pxelinux.cfg/default.serial-9600" ] && grep -q "## DO NOT EDIT THIS FILE" "$di_dir/pxelinux.cfg/default.serial-9600" && rm "$di_dir/pxelinux.cfg/default.serial-9600"
	[ -f "$di_dir/elilo.conf" ] && grep -q "## DO NOT EDIT THIS FILE" "$di_dir/elilo.conf" && rm "$di_dir/elilo.conf"

	[ ! -e "$di_dir/pxelinux.cfg/default" -a ! -e "$di_dir/pxelinux.cfg/default.serial-9600" -a -f "$di_dir/pxelinux.cfg/$SYSLINUXMENU" ] && rm "$di_dir/pxelinux.cfg/$SYSLINUXMENU"
	[ -d "$di_dir/pxelinux.cfg" ] && rmdir --ignore-fail-on-non-empty "$di_dir/pxelinux.cfg"
	[ ! -e "$di_dir/pxelinux.cfg" -a -f "$di_dir/pxelinux.0" ] && rm "$di_dir/pxelinux.0"
	rmdir --ignore-fail-on-non-empty "$di_dir"
	[ ! -e "$di_dir/elilo.conf" -a -f "$di_dir/elilo.efi" ] && rm "$di_dir/elilo.efi"

	pxemenufragment="$metadatabasename.pxelinux.menu.fragment"
	[ -f "$pxemenufragment" ] && rm "$pxemenufragment"

	pxemenufragment_serial9600="$metadatabasename.pxelinux.menu.serial-9600.fragment"
	[ -f "$pxemenufragment_serial9600" ] && rm "$pxemenufragment_serial9600"

	elilomenufragment="$metadatabasename.elilo.conf.fragment"
	[ -f "$elilomenufragment" ] && rm "$elilomenufragment"

	rm "$dist"
}


purge_repos() {
	[ "$DEBUG" ] && set -x
	del_repo="$1"
	current_repos="$(find  /var/lib/di-netboot-assistant/  -name $del_repo--\*.conf | sed -e 's/^.*--//' -e 's/\.conf//')"

	if [ "$(echo $ARCH | grep -E "\<all\>")" ]; then
		archs="$current_repos"
	else
		archs="$(echo $ARCH | tr ',' ' ')"
	fi

	for a in $archs ; do
		if [ -f "/var/lib/di-netboot-assistant/$del_repo--$a.conf" ]; then
			purge_repo "/var/lib/di-netboot-assistant/$del_repo--$a.conf"
		else
			echo "E: Repository '$del_repo' for architecture '$a' doesn't exists." 1>&2
			echo "I: (current repository are: $current_repos)" 1>&2
			echo "" 1>&2
			exit 1
		fi
	done

	[ -d "$TFTP_ROOT/debian-installer" ] && update_menu
	[ "$DEBUG" ] && set +x
}

fetch_files() {
	local baseurl="$1"
	local repo_loc="$2"
	shift 2
	local files="$@"
	[ "$DEBUG" ] && set -x

	if [ ! "$OFFLINE" ]; then
		if which wget > /dev/null ; then
			GETTER="wget -c -x $WGET_VERBOSITY -O"
		elif which curl > /dev/null ; then
			GETTER="curl --fail $CURL_VERBOSITY -o"
		else
			echo "E: Can't download file. no download tool detected (wget or curl)." 1>&2
			echo "" 1>&2
			exit 2
		fi
		echo "I: Downloading..."
	fi

	SUCCEED="true"
	for givenfile in $EXTRA_DL_FILES $files ; do
		f=$(echo $givenfile | sed -e 's#^\./##' -e 's#^/##' -e 's#//#/#g')
		url="$baseurl/$f"
		file="${DL_CACHE}/$(echo ${repo_loc}/$f | sed -e 's#/#_#g')"

		[ -e $file.tmp ] && rm $file.tmp

		if [ ! "$OFFLINE" ]; then
			if $GETTER "$file.tmp" -- "$url" ; then
				fetch_date="$(date -R)"
			else
				echo "$EXTRA_DL_FILES" | tr " " "\n" | grep -qx $f || SUCCEED="failed"
				echo "E: Download has Failed." 1>&2
				[ "$WGET_VERBOSITY" != "--quiet" ] && echo "E: Can't download '$release' for '$arch' ($url)." 1>&2
				[ -f "$file.tmp" ] && rm $RM_VERBOSITY "$file.tmp"
				if [ -f "$file" ]; then
					echo "I: You have a previous version in your cache (see --offline option)." 1>&2
				fi
			fi
		else
			if [ ! -f "$file" ]; then
				SUCCEED="failed"
				echo "E: Can't process '$release' in offline mode, the file is missing:" 1>&2
				echo "E: (expecting '$file' from '$url')" 1>&2
				echo "" 1>&2
				exit 1
			else
				echo "I: Reusing previously downloaded file... " 1>&2
				fetch_date="$( grep "fetch_date" $metadatafile | cut -d "=" -f 2- )"
			fi
		fi
	done

	csum="${DL_CACHE}/$(echo ${repo_loc}/MD5SUMS.tmp | sed -e 's#/#_#g')"
	if [ -f "$csum" -a "$SUCCEED" = "true" ] ; then
		echo -n "I: Computing checksums... " 1>&2
		for givenfile in $EXTRA_DL_FILES $files ; do
			f=$(echo $givenfile | sed -e 's#^\./##' -e 's#^/##' -e 's#//#/#g')
			file="${DL_CACHE}/$(echo ${repo_loc}/$f | sed -e 's#/#_#g')"
			md5=$(md5sum $file.tmp | cut -d " " -f 1)
			if [ "$givenfile" == "MD5SUMS" ]; then
				continue;
			fi
			echo -n "$givenfile " 1>&2
			if ! grep -qiE "[[:blank:]]+(\./|)$givenfile[[:blank:]]*$" $csum ; then
				echo -n " (No checksum)" 1>&2
				continue;
			fi
			if ! grep -qiE "^$md5[[:blank:]]+(\./|)$givenfile[[:blank:]]*$" $csum ; then
				echo "FAILED" 1>&2
				echo "E: Checksum verification failed (the file got corrupted somewhere)." 1>&2
				SUCCEED="failed"
				break;
			fi
		done
		[ "$SUCCEED" = "true" ] && echo "... done." 1>&2
	else
		[ ! "$OFFLINE" ] && echo "I: No checksum found." 1>&2
	fi	


	if [ ! "$OFFLINE" ]; then
		echo "I: Moving/Removing temporary files." 1>&2		
		for givenfile in $EXTRA_DL_FILES $files ; do
			f=$(echo $givenfile | sed -e 's#^\./##' -e 's#^/##' -e 's#//#/#g')
			file="${DL_CACHE}/$(echo ${repo_loc}/$f | sed -e 's#/#_#g')"
			if [ "$SUCCEED" = "true" ]; then
				[ -f "$file.tmp" -a -f "$file" ] && rm $RM_VERBOSITY "$file"
				[ -f "$file.tmp" ] && mv $MV_VERBOSITY "$file.tmp" "$file"
			else
				[ -f "$file.tmp" ] && rm $RM_VERBOSITY "$file.tmp"
			fi
		done
	fi

	if [ "$SUCCEED" = "true" ]; then
		return 0
	else
		exit 1
	fi
	[ "$DEBUG" ] && set +x
}

pxelinux_version() {
	bin="$1"
	tr -c '[:print:] ' '\n' < $1 | sed -n -r "/PXELINUX [.0-9]+/ s/^[^ ]* ([0-9^.]+).*/\1/ p" | sort -r | head -n 1
}

install_repo() {
	local pxelinuxbin
	[ "$DEBUG" ] && set -x
	release="$1"
	if [ -z "$release" ]; then
		echo "E: No repository specified (valid repositories are: $releases)" 1>&2
		echo "";
		exit 1;
	fi

	if ! grep -Eq "^$release\>" "$DISOURCELIST" ; then
		echo "E: Invalid repository name specified ($release)" 1>&2
		echo "I: Declared repositories are: $releases" 1>&2
		echo "" 1>&2
		exit 1
	fi


	if [ "$(echo $ARCH | grep -E "\<all\>")" ]; then
		archs="$(grep -E "^$release\>" "$DISOURCELIST" | cut -f 2)"
	else
		archs="$(echo $ARCH | tr ',' ' ')"
	fi

	
	if [ -z "$( echo "$archs" | sed -e 's/[[:blank:]\?]*//g' )" ]; then
		echo "E: No architecture specified." 1>&2
		list_declared_arch_for_repo "$release"
		echo "" 1>&2
		exit 1
	fi

	for arch in $archs ; do
		echo "I: Processing $release/$arch ... "

		metadatabasename="/var/lib/di-netboot-assistant/${release}--${arch}"
		metadatafile="$metadatabasename.conf"

		repo_orig="$(grep -E "^$release[[:blank:]]$arch\>" "$DISOURCELIST")"
		repo_mirror="$repo_orig"
		for reg in $MIRROR_REGEXPS "s=/$==" ; do
			repo_mirror="$(echo "$repo_mirror" | sed -e "$reg")"
		done

		repo="$(echo "$repo_orig" | cut -f 3 | sed -e 's#\([^:]/\)/#\1#g' -e 's#/$##' )"
		repo_mirror="$(echo "$repo_mirror" | cut -f 3 | sed -e 's#\([^:]/\)/#\1#g' -e 's#/$##' )"

		if [ -z "$repo" ]; then
			echo "E: There is no entry declared for architecture '$arch' for " 1>&2
			echo "E: repository '$release' in $DISOURCELIST" 1>&2
			list_declared_arch_for_repo "$release"
			echo "" 1>&2
			exit 1
		fi

		repo_proto="$(echo $repo | cut -d ":" -f 1 )"
		repo_loc="$(echo $repo | sed -e 's#^[^:]\+://##')"
		expand_dir="$TFTP_ROOT/debian-installer/$release/$arch"

		file=$(grep -E "^$release[[:blank:]]$arch" "$DISOURCELIST" | cut -f 4- )
		fetch_date=""
		fetch_files "$repo_mirror" "$repo_loc" $file
		if [ -z "$fetch_date" ]; then
			exit 1
		fi
		f=$(echo $givenfile | sed -e 's#^\./##' -e 's#^/##' -e 's#//#/#g')
		dl_file="${DL_CACHE}/$(echo ${repo_loc}/$f | sed -e 's#/#_#g')"

		echo "#$PACKAGE_NAME for '$release' ($arch)" > $metadatafile
		echo "fetch_date=$fetch_date" >> $metadatafile
		echo "expand_dir=$expand_dir" >> $metadatafile
		echo "dist=$release" >> $metadatafile
		echo "repo=$repo" >> $metadatafile
		echo "dl_file=$dl_file" >> $metadatafile
	
		echo "I: Extracting... " 1>&2
			
		if [ -d "$expand_dir" ]; then
			rm -Rf "$expand_dir/*"
		else
			mkdir -p "$expand_dir"
		fi

		case "$(echo "$dl_file" | sed -e 's#^.*/##' )" in
			*.tar.gz)
				tar $TAR_VERBOSITY -zxf "$dl_file" --directory "$expand_dir" --strip-components 3 --exclude "./pxelinux.0" --exclude "./pxelinux.cfg"
				tar $TAR_VERBOSITY -zxf "$dl_file" --directory "$expand_dir" ./version.info 2>/dev/null || true
				;;			
			*.tar.bz2)
				tar $TAR_VERBOSITY -jxf "$dl_file" --directory "$expand_dir" --strip-components 3 --exclude "./pxelinux.0" --exclude "./pxelinux.cfg"
				tar $TAR_VERBOSITY -jxf "$dl_file" --directory "$expand_dir" ./version.info 2>/dev/null || true
				;;			
			*.img)
				cp $CP_VERBOSITY "$dl_file" "$expand_dir/$(basename "$f")"
				;;
			*)
				echo "E: Don't know how to handle (unpack...) the file: $dl_file" 1>&2
				;;
		esac

		# PXELINUX MENUs (i386, amd64)
		pxelinuxbin="$(find "$expand_dir" -type f -name "pxelinux.0" 2>/dev/null )"

		if [ ! -z "$pxelinuxbin" ]; then
			PXE_NEW_VER="$(pxelinux_version "$pxelinuxbin")"
			PXE_CUR_VER="$(pxelinux_version "$TFTP_ROOT/debian-installer/pxelinux.0")"
			if dpkg --compare-versions "$PXE_NEW_VER" ">>" "$PXE_CUR_VER" ; then
				echo "I: Upgrading $TFTP_ROOT/debian-installer/pxelinux.0 ($PXE_CUR_VER to $PXE_NEW_VER)" 1>&2
				cp -f "$pxelinuxbin" "$TFTP_ROOT/debian-installer/pxelinux.0"
				for x in $(find "$expand_dir" -type f -name "$SYSLINUXMENU" | head -n 1) ; do
					cp "$x" "$TFTP_ROOT/debian-installer/pxelinux.cfg/"
				done
			fi
			for x in $(find "$expand_dir" -type f -a \( -name "default" -o -name "boot.txt" -o -name '*.cfg' \) ); do
				mv "$x" "$x.ORIG"
				print_do-not-edit_header "$release" > "$x"
				sed -e "s#${REWRITEPKGPATH}/$arch/#debian-installer/$release/$arch/#" < "$x.ORIG" >> "$x"
			done
			menufragment="$metadatabasename.pxelinux.menu.fragment"
			menufragment_serial9600="$metadatabasename.pxelinux.menu.serial-9600.fragment"
			echo "## This is a fragment of syslinux/pxelinux menu file." > $menufragment
			echo "##" >> $menufragment
			echo "## DO NOT EDIT THIS FILE" >> $menufragment
			echo "##" >> $menufragment
			echo "## It is automatically generated by $PACKAGE_NAME" >> $menufragment
			echo "##" >> $menufragment

			if [ ! -z "$(find $expand_dir -type d -name pxelinux.cfg.serial-9600 2>/dev/null)" ]; then
				cp $menufragment $menufragment_serial9600
			else
				[ -f "$menufragment_serial9600" ] && rm "$menufragment_serial9600"
			fi

			echo  "LABEL $release-$arch" >> $menufragment
			printf "	MENU LABEL Debian Installer %-20s       [SUB-MENU]\n" "($release, $arch)" >> $menufragment

			if [ ! -z "$(grep -Eiq "^[[:blank:]]*prompt[[:blank:]]+0" "$expand_dir/pxelinux.cfg/default" && grep -Eiq "^[[:blank:]]*default[[:blank:]].*/vesamenu.c32" "$expand_dir/pxelinux.cfg/default" && echo ok)" ]; then

				echo -n  "	KERNEL " >> $menufragment
				grep -Ei "^[[:blank:]]*default[[:blank:]].*/vesamenu.c32" $expand_dir/pxelinux.cfg/default | sed -e 's/^[[:blank:]]*default[[:blank:]]//' >> $menufragment
				echo -n  "	APPEND " >> $menufragment
				if grep -qEi "^[[:blank:]]*include[[:blank:]]" $expand_dir/pxelinux.cfg/default ; then
					grep -Ei "^[[:blank:]]*include[[:blank:]]" $expand_dir/pxelinux.cfg/default | sed -e 's/^[[:blank:]]*include[[:blank:]]//' >> $menufragment
				else
					echo   "	APPEND debian-installer/$release/$arch/pxelinux.cfg/default" >> $menufragment
				fi

			else
				echo   "	KERNEL debian-installer/pxelinux.cfg/$SYSLINUXMENU" >> $menufragment
				echo   "	APPEND debian-installer/$release/$arch/pxelinux.cfg/default" >> $menufragment
			fi

			echo   "" >> $menufragment
	
			if [ -f "$menufragment_serial9600" ]; then
				echo   "LABEL $release-$arch" >> $menufragment_serial9600
				printf "	MENU LABEL Debian Installer %-20s       [SUB-MENU]\n" "($release, $arch)" >> $menufragment_serial9600
				echo   "	KERNEL debian-installer/pxelinux.cfg/$SYSLINUXMENU" >> $menufragment_serial9600
				echo   "	APPEND debian-installer/$release/$arch/pxelinux.cfg.serial-9600/default" >> $menufragment_serial9600
				echo   "" >> $menufragment_serial9600
			fi
		fi

		# ELILO MENU (ia64)
		if [ ! -z "$(find "$expand_dir" -type f -name 'elilo.conf' )" ]; then
			for x in $(find "$expand_dir" -type f -name 'elilo.conf' ); do
				mv "$x" "$x.ORIG"
				print_do-not-edit_header "release" > "$x"
				sed -e "s#^\([[:blank:]]*\(image\|initrd\|message\|f[0-9]\+\)=\)#\1debian-installer/$release/$arch/#" < "$x.ORIG" >> "$x"
			done

			menufragment="$metadatabasename.elilo.conf.fragment"
			echo "## This is a fragment of elilo menu file." > $menufragment
			echo "##" >> $menufragment
			echo "## DO NOT EDIT THIS FILE" >> $menufragment
			echo "##" >> $menufragment
			echo "## It is automatically generated by $PACKAGE_NAME" >> $menufragment
			echo "##" >> $menufragment

			echo "# ### $release $arch ### " >> $menufragment
			awk '/^image=/,/^$/' "${expand_dir}/elilo.conf" | sed -e "s/^[[:blank:]]*label=.*$/\0-$release-$arch/" | sed -e "s/^\([[:blank:]]*description\)=\"\([^\"]\+\)\"/\1=\"\2 (Lenny AMD64)\"/" >> $menufragment
			echo "" >> $menufragment
		fi

		update_menu
	done;	
	[ "$DEBUG" ] && set +x
}


WGET_VERBOSITY="--quiet"
CURL_VERBOSITY="--silent"
RM_VERBOSITY=
MV_VERBOSITY=
CP_VERBOSITY=
TAR_VERBOSITY=
ARCH=

if which apt-config > /dev/null 2>&1 ; then
	ARCH=
	eval $(apt-config shell ARCH APT::Architecture )
fi

for option in "$@"; do
    case "$option" in
    -h | --help)
	usage
	exit 0 ;;
    -v | --version)
	echo "$PACKAGE_NAME $PACKAGE_VERSION"
	exit 0 ;;
    --arch| --arch=*)
	ARCH="$(echo $option | sed -e 's/--arch[=]\?//' -e 's/,,/,/' -e 's/^,\+//' -e 's/,\+$//' )"
	#Note:
	if [ "$(echo $ARCH | grep -E '^[[:alnum:]_,]\+$')" ]; then
		echo "E: Invalid architecture specified ($ARCH)" 1>&2
		echo "" 1>&2
		exit 1
	fi ;;
    --offline)
	OFFLINE=yes ;;
    --verbose)
	WGET_VERBOSITY=""
	CURL_VERBOSITY=""
	RM_VERBOSITY="-v"
	MV_VERBOSITY="-v"
	CP_VERBOSITY="-v"
	TAR_VERBOSITY="-v"
	;;
    --debug)
	# This is an undocumented feature...
	DEBUG=yes ;;
    -*)
	echo "E: Unrecognized option ($option)" 1>&2
	echo "" 1>&2
	exit 1
	;;
    esac
done

check_tftp_root
cd "$TFTP_ROOT/debian-installer"

check_di_source_list
releases="$(grep -vE '^#' "$DISOURCELIST" | cut -f 1 | sort -u | tr "\n" " " | sed -e 's/^[[:blank:]]\+//' )"

ACTION=
COUNT=0
for option in "$@"; do
    case "$option" in
    -*)
    	# Ignore options on this pass
    	;;
    install|purge)
    	if [ "$ACTION" ]; then
		echo "E: Unexpected command '$option'. '$ACTION' was already specified." 1>&2
		echo "" 1>&2
		exit 1
	fi

	ACTION=$option
	;;
    rebuild-menu)
	ACTION=$option
        update_menu
        ;;
    *)
	case "$ACTION" in
		install)
			install_repo "$option"
			;;
		purge)
			purge_repos "$option"
			;;
		rebuild-menu)
			echo "W: Argument '$option' ignored ($ACTION expects no argument)." 1>&2
			echo "" 1>&2
			;;
		*)
			echo "E: Unexpected keyword: '$option'. No action were specified." 1>&2
			echo "" 1>&2
			exit 1
			;;
	esac
	COUNT=$(( $COUNT + 1 ))
    esac
done

if [ "$ACTION" = "" ]; then
	usage 1>&2
	exit 1
fi

case "$ACTION" in
    rebuild-menu)
        ;;
    *)
        if [ $COUNT -eq 0 ]; then
        	echo "E: No repository name was passed for '$ACTION'." 1>&2
        	[ ! "$OFFLINE" -a "$ACTION" = "install" ] && echo "I: Declared repositories are: $releases" 1>&2
        	[ "$ACTION" = "purge" ] && echo "I: Installed repositories are: $( cd /var/lib/di-netboot-assistant/ ; ls | sed -e 's/--.*//' | sort -u | tr "\n" " " )" 1>&2
        	echo "" 1>&2
        	exit 1
        fi
        ;;
esac

$UMASKOLD
export UMASKOLD=


