| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199 | # ipkg - the itsy package management system## Copyright (C) 2001 Carl D. Worth## 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, 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.#set -xset -e# By default do not do globbing. Any command wanting globbing should# explicitly enable it first and disable it afterwards.set -o noglobipkg_is_upgrade () {  local A B a b       A=$(echo $1 | sed -r "s/([0-9]+)[^[:alnum:]]*/ \1 /g").  B=$(echo $2 | sed -r "s/([0-9]+)[^[:alnum:]]*/ \1 /g").  while [ \! -z "$A" ] && [ \! -z "$B" ]; do {            set $A; a=$1; shift; A=$*    set $B; b=$1; shift; B=$*      [ "$a" -lt "$b" ] 2>&- && return 1 ||:    { [ "$a" -gt "$b" ] 2>&- || [ "$a" ">" "$b" ]; } && return ||:  }; done                                                       return 1}         ipkg_srcs() {	local srcre="$1"	sed -ne "s/^src[[:space:]]\+$srcre[[:space:]]\+//p" < $IPKG_CONF}ipkg_src_names() {	sed -ne "s/^src[[:space:]]\+\([^[:space:]]\+\).*/\1/p" < $IPKG_CONF}ipkg_src_byname() {	local src="$1"	ipkg_srcs $src | head -n 1}ipkg_dests() {	local destre="`echo $1 | ipkg_protect_slashes`"	sed -ne "/^dest[[:space:]]\+$destre/{s/^dest[[:space:]]\+[^[:space:]]\+[[:space:]]\+//s/^/`echo $IPKG_OFFLINE_ROOT | ipkg_protect_slashes`/p}" < $IPKG_CONF}ipkg_dest_names() {	sed -ne "s/^dest[[:space:]]\+\([^[:space:]]\+\).*/\1/p" < $IPKG_CONF}ipkg_dests_all() {	ipkg_dests '.*'}ipkg_state_dirs() {	ipkg_dests_all | sed "s|\$|/$IPKG_DIR_PREFIX|"}ipkg_dest_default() {	ipkg_dests_all | head -n 1}ipkg_dest_default_name() {	ipkg_dest_names | head -n 1}ipkg_dest_byname() {	local dest="$1"	ipkg_dests $dest | head -n 1}ipkg_option() {	local option="$1"	sed -ne "s/^option[[:space:]]\+$option[[:space:]]\+//p" < $IPKG_CONF}ipkg_load_configuration() {	if [ -z "$IPKG_CONF_DIR" ]; then		IPKG_CONF_DIR=/etc	fi	IPKG_CONF="$IPKG_CONF_DIR/ipkg.conf"	if [ -z "$IPKG_OFFLINE_ROOT" ]; then	    IPKG_OFFLINE_ROOT="`ipkg_option offline_root`"	fi	# Export IPKG_OFFLINE_ROOT for use by update-alternatives	export IPKG_OFFLINE_ROOT	if [ -n "$DEST_NAME" ]; then		IPKG_ROOT="`ipkg_dest_byname $DEST_NAME`"		if [ -z "$IPKG_ROOT" ]; then			if [ -d "$IPKG_OFFLINE_ROOT$DEST_NAME" ]; then				IPKG_ROOT="$IPKG_OFFLINE_ROOT$DEST_NAME";			else				echo "ipkg: invalid destination specification: $DEST_NAMEValid destinations are directories or one of the dest names from $IPKG_CONF:" >&2				ipkg_dest_names >&2				return 1			fi		fi	else		IPKG_ROOT="`ipkg_dest_default`"	fi	# Global ipkg state directories	IPKG_DIR_PREFIX=usr/lib/ipkg	IPKG_LISTS_DIR=$IPKG_OFFLINE_ROOT/$IPKG_DIR_PREFIX/lists	IPKG_PENDING_DIR=$IPKG_OFFLINE_ROOT/$IPKG_DIR_PREFIX/pending	if [ -z "$IPKG_TMP" ]; then		IPKG_TMP=$IPKG_ROOT/tmp/ipkg	fi	[ -e "$IPKG_TMP" ] || mkdir -p $IPKG_TMP	# Destination specific ipkg meta-data directory	IPKG_STATE_DIR=$IPKG_ROOT/$IPKG_DIR_PREFIX	# Proxy Support	IPKG_PROXY_USERNAME="`ipkg_option proxy_username`"	IPKG_PROXY_PASSWORD="`ipkg_option proxy_password`"	IPKG_HTTP_PROXY="`ipkg_option http_proxy`"	IPKG_FTP_PROXY="`ipkg_option ftp_proxy`"	IPKG_NO_PROXY="`ipkg_option no_proxy`"	if [ -n "$IPKG_HTTP_PROXY" ]; then 		export http_proxy="$IPKG_HTTP_PROXY"	fi	if [ -n "$IPKG_FTP_PROXY" ]; then 		export ftp_proxy="$IPKG_FTP_PROXY"	fi	if [ -n "$IPKG_NO_PROXY" ]; then 		export no_proxy="$IPKG_NO_PROXY"	fi	IPKG_STATUS_FIELDS='\(Package\|Status\|Essential\|Version\|Conffiles\|Root\)'}ipkg_usage() {	[ $# -gt 0 ] && echo "ipkg: $*" ||:	echo "usage: ipkg [options...] sub-command [arguments...]where sub-command is one of:Package Manipulation:	update  		Update list of available packages	upgrade			Upgrade all installed packages to latest version	install <pkg>		Download and install <pkg> (and dependencies)	install <file.ipk>	Install package <file.ipk>	install <file.deb>	Install package <file.deb>	remove <pkg>		Remove package <pkg>Informational Commands:	list    		List available packages and descriptions	files <pkg>		List all files belonging to <pkg>	search <file>		Search for a packaging providing <file>	info [pkg [<field>]]	Display all/some info fields for <pkg> or all	status [pkg [<field>]]	Display all/some status fields for <pkg> or all	depends <pkg>		Print uninstalled package dependencies for <pkg>Options:	-d <dest_name>          Use <dest_name> as the the root directory for	-dest <dest_name>	package installation, removal, upgrading.				<dest_name> should be a defined dest name from the				configuration file, (but can also be a directory				name in a pinch).        -o <offline_root>       Use <offline_root> as the root for offline installation.        -offline <offline_root> 				Wget Options:	-q			Quiet option for wget	-c			Continue option for wgetForce Options (use when ipkg is too smart for its own good):	-force-depends          Make dependency checks warnings instead of errors	-force-defaults         Use default options for questions asked by ipkg.                                (no prompts). Note that this will not prevent                                package installation scripts from prompting." >&2	exit 1}ipkg_dir_part() {	local dir="`echo $1 | sed -ne 's/\(.*\/\).*/\1/p'`"	if [ -z "$dir" ]; then		dir="./"	fi	echo $dir}ipkg_file_part() {	echo $1 | sed 's/.*\///'}ipkg_protect_slashes() {	sed -e 's/\//\\\//g'}ipkg_download() {	local src="$1"	local dest="$2"	local src_file="`ipkg_file_part $src`"	local dest_dir="`ipkg_dir_part $dest`"	if [ -z "$dest_dir" ]; then		dest_dir="$IPKG_TMP"	fi	local dest_file="`ipkg_file_part $dest`"	if [ -z "$dest_file" ]; then		dest_file="$src_file"	fi	# Proxy support	local proxyuser=""	local proxypassword=""	local proxyoption=""			if [ -n "$IPKG_PROXY_USERNAME" ]; then		proxyuser="--proxy-user=\"$IPKG_PROXY_USERNAME\""		proxypassword="--proxy-passwd=\"$IPKG_PROXY_PASSWORD\""	fi	if [ -n "$IPKG_PROXY_HTTP" -o -n "$IPKG_PROXY_FTP" ]; then		proxyoption="--proxy=on"	fi	echo "Downloading $src ..."	rm -f $IPKG_TMP/$src_file	case "$src" in	http://* | ftp://*)		if ! wget $additional_options --passive-ftp $proxyoption $proxyuser $proxypassword -P $IPKG_TMP $src; then			echo "ipkg_download: ERROR: Failed to retrieve $src, returning $err"			return 1		fi		mv $IPKG_TMP/$src_file $dest_dir/$dest_file 2>/dev/null		;;	file:/* )		ln -s `echo $src | sed 's/^file://'` $dest_dir/$dest_file 2>/dev/null		;;	*)	echo "DEBUG: $src"		;;	esac	echo "Done."	return 0}ipkg_update() {	if [ ! -e "$IPKG_LISTS_DIR" ]; then		mkdir -p $IPKG_LISTS_DIR	fi	local err=	for src_name in `ipkg_src_names`; do		local src="`ipkg_src_byname $src_name`"		if ! ipkg_download $src/Packages $IPKG_LISTS_DIR/$src_name; then			echo "ipkg_update: Error downloading $src/Packages to $IPKG_LISTS_DIR/$src_name" >&2			err=t		else			echo "Updated list of available packages in $IPKG_LISTS_DIR/$src_name"		fi	done	[ -n "$err" ] && return 1 ||:	return 0}ipkg_list() {	for src in `ipkg_src_names`; do		if ipkg_require_list $src; then # black magic...sed -ne "/^Package:/{s/^Package:[[:space:]]*\<\([a-z0-9.+-]*$1[a-z0-9.+-]*\).*/\1/h}/^Description:/{s/^Description:[[:space:]]*\(.*\)/\1/Hgs/\\/ - /p}" $IPKG_LISTS_DIR/$src		fi	done}ipkg_extract_paragraph() {	local pkg="$1"	sed -ne "/Package:[[:space:]]*$pkg[[:space:]]*\$/,/^\$/p"}ipkg_extract_field() {	local field="$1"# blacker magic...	sed -ne ": TOP/^$field:/{pnb FIELD}d: FIELD/^$/b TOP/^[^[:space:]]/b TOPpnb FIELD"}ipkg_extract_value() {	sed -e "s/^[^:]*:[[:space:]]*//"}ipkg_require_list() {	[ $# -lt 1 ] && return 1 ||:	local src="$1"	if [ ! -f "$IPKG_LISTS_DIR/$src" ]; then		echo "ERROR: File not found: $IPKG_LISTS_DIR/$src" >&2		echo "       You probably want to run \`ipkg update'" >&2		return 1	fi	return 0}ipkg_info() {	for src in `ipkg_src_names`; do		if ipkg_require_list $src; then			case $# in			0)				cat $IPKG_LISTS_DIR/$src				;;				1)				ipkg_extract_paragraph $1 < $IPKG_LISTS_DIR/$src				;;			*)				ipkg_extract_paragraph $1 < $IPKG_LISTS_DIR/$src | ipkg_extract_field $2				;;			esac		fi	done}ipkg_status_sd() {	[ $# -lt 1 ] && return 0 ||:	sd="$1"	shift	if [ -f $sd/status ]; then		case $# in		0)			cat $sd/status			;;		1)			ipkg_extract_paragraph $1 < $sd/status			;;		*)			ipkg_extract_paragraph $1 < $sd/status | ipkg_extract_field $2			;;		esac	fi	return 0}ipkg_status_all() {	for sd in `ipkg_state_dirs`; do		ipkg_status_sd $sd $*	done}ipkg_status() {	if [ -n "$DEST_NAME" ]; then		ipkg_status_sd $IPKG_STATE_DIR $*	else		ipkg_status_all $*	fi}ipkg_status_matching_sd() {	local sd="$1"	local re="$2"	if [ -f $sd/status ]; then		sed -ne ": TOP/^Package:/{s/^Package:[[:space:]]*//s/[[:space:]]*$//h}/$re/{gpb NEXT}d: NEXT/^$/b TOPnb NEXT" < $sd/status	fi	return 0}ipkg_status_matching_all() {	for sd in `ipkg_state_dirs`; do		ipkg_status_matching_sd $sd $*	done}ipkg_status_matching() {	if [ -n "$DEST_NAME" ]; then		ipkg_status_matching_sd $IPKG_STATE_DIR $*	else		ipkg_status_matching_all $*	fi}ipkg_status_installed_sd() {	local sd="$1"	local pkg="$2"	ipkg_status_sd $sd $pkg Status | grep -q "Status: install ok installed"}ipkg_status_installed_all() {	local ret=1	for sd in `ipkg_state_dirs`; do		if `ipkg_status_installed_sd $sd $*`; then			ret=0		fi	done	return $ret}ipkg_status_mentioned_sd() {	local sd="$1"	local pkg="$2"	[ -n "`ipkg_status_sd $sd $pkg Status`" ]}ipkg_files() {	local pkg="$1"	if [ -n "$DEST_NAME" ]; then		dests=$IPKG_ROOT	else		dests="`ipkg_dests_all`"	fi	for dest in $dests; do		if [ -f $dest/$IPKG_DIR_PREFIX/info/$pkg.list ]; then			dest_sed="`echo $dest | ipkg_protect_slashes`"			sed -e "s/^/$dest_sed/" < $dest/$IPKG_DIR_PREFIX/info/$pkg.list		fi	done}ipkg_search() {	local pattern="$1"	for dest_name in `ipkg_dest_names`; do		dest="`ipkg_dest_byname $dest_name`"		dest_sed="`echo $dest | ipkg_protect_slashes`"		set +o noglob		local list_files="`ls -1 $dest/$IPKG_DIR_PREFIX/info/*.list 2>/dev/null`"		set -o noglob		for file in $list_files; do			if sed "s/^/$dest_sed/" $file | grep -q $pattern; then				local pkg="`echo $file | sed "s/^.*\/\(.*\)\.list/\1/"`"				[ "$dest_name" != `ipkg_dest_default_name` ] && pkg="$pkg ($dest_name)" ||:				sed "s/^/$dest_sed/" $file | grep $pattern | sed "s/^/$pkg: /"			fi		done	done}ipkg_status_remove_sd() {	local sd="$1"	local pkg="$2"	if [ ! -f $sd/status ]; then		mkdir -p $sd		touch $sd/status	fi	sed -ne "/Package:[[:space:]]*$pkg[[:space:]]*\$/,/^\$/!p" < $sd/status > $sd/status.new	mv $sd/status.new $sd/status}ipkg_status_remove_all() {	for sd in `ipkg_state_dirs`; do		ipkg_status_remove_sd $sd $*	done}ipkg_status_remove() {	if [ -n "$DEST_NAME" ]; then		ipkg_status_remove_sd $IPKG_STATE_DIR $*	else		ipkg_status_remove_all $*	fi}ipkg_status_update_sd() {	local sd="$1"	local pkg="$2"	ipkg_status_remove_sd $sd $pkg	ipkg_extract_field "$IPKG_STATUS_FIELDS" >> $sd/status	echo "" >> $sd/status}ipkg_status_update() {	ipkg_status_update_sd $IPKG_STATE_DIR $*}ipkg_unsatisfied_dependences() {    local pkg=$1    local deps="`ipkg_get_depends $pkg`"    local remaining_deps=    for dep in $deps; do	local installed="`ipkg_get_installed $dep`"	if [ "$installed" != "installed" ] ; then	    remaining_deps="$remaining_deps $dep"	fi    done    ## echo "ipkg_unsatisfied_dependences pkg=$pkg $remaining_deps" > /dev/console    echo $remaining_deps}ipkg_safe_pkg_name() {	local pkg=$1	local spkg="`echo pkg_$pkg | sed -e y/-+./___/`"	echo $spkg}ipkg_set_depends() {	local pkg=$1; shift 	local new_deps="$*"	pkg="`ipkg_safe_pkg_name $pkg`"	## setvar ${pkg}_depends "$new_deps"	echo $new_deps > $IPKG_TMP/${pkg}.depends}ipkg_get_depends() {	local pkg=$1	pkg="`ipkg_safe_pkg_name $pkg`"	cat $IPKG_TMP/${pkg}.depends	## eval "echo \$${pkg}_depends"}ipkg_set_installed() {	local pkg=$1	pkg="`ipkg_safe_pkg_name $pkg`"	echo installed > $IPKG_TMP/${pkg}.installed	## setvar ${pkg}_installed "installed"}ipkg_set_uninstalled() {	local pkg=$1	pkg="`ipkg_safe_pkg_name $pkg`"	### echo ipkg_set_uninstalled $pkg > /dev/console	echo uninstalled > $IPKG_TMP/${pkg}.installed	## setvar ${pkg}_installed "uninstalled"}ipkg_get_installed() {	local pkg=$1	pkg="`ipkg_safe_pkg_name $pkg`"	if [ -f $IPKG_TMP/${pkg}.installed ]; then		cat $IPKG_TMP/${pkg}.installed	fi	## eval "echo \$${pkg}_installed"}ipkg_depends() {	local new_pkgs="$*"	local all_deps=	local installed_pkgs="`ipkg_status_matching_all 'Status:.*[[:space:]]installed'`"	for pkg in $installed_pkgs; do	    ipkg_set_installed $pkg	done	while [ -n "$new_pkgs" ]; do		all_deps="$all_deps $new_pkgs"		local new_deps=		for pkg in $new_pkgs; do			if echo $pkg | grep -q '[^a-z0-9.+-]'; then				echo "ipkg_depends: ERROR: Package name $pkg contains illegal characters (should be [a-z0-9.+-])" >&2				return 1			fi			# TODO: Fix this. For now I am ignoring versions and alternations in dependencies.			new_deps="$new_deps "`ipkg_info $pkg '\(Pre-\)\?Depends' | ipkg_extract_value | sed -e 's/([^)]*)//gs/\(|[[:space:]]*[a-z0-9.+-]\+[[:space:]]*\)\+//gs/,/ /gs/ \+/ /g'`			ipkg_set_depends $pkg $new_deps		done		new_deps=`echo $new_deps | sed -e 's/[[:space:]]\+/\n/g' | sort | uniq`		local maybe_new_pkgs=		for pkg in $new_deps; do			if ! echo $installed_pkgs | grep -q "\<$pkg\>"; then				maybe_new_pkgs="$maybe_new_pkgs $pkg"			fi		done		new_pkgs=		for pkg in $maybe_new_pkgs; do			if ! echo $all_deps | grep -q "\<$pkg\>"; then				if [ -z "`ipkg_info $pkg`" ]; then					echo "ipkg_depends: Warning: $pkg mentioned in dependency but no package found in $IPKG_LISTS_DIR" >&2					ipkg_set_installed $pkg				else					new_pkgs="$new_pkgs $pkg"					ipkg_set_uninstalled $pkg				fi			else				ipkg_set_uninstalled $pkg			fi		done	done	echo $all_deps}ipkg_get_install_dest() {	local dest="$1"	shift	local sd=$dest/$IPKG_DIR_PREFIX	local info_dir=$sd/info        local requested_pkgs="$*"	local pkgs="`ipkg_depends $*`"	mkdir -p $info_dir	for pkg in $pkgs; do		if ! ipkg_status_mentioned_sd $sd $pkg; then			echo "Package: $pkgStatus: install ok not-installed" | ipkg_status_update_sd $sd $pkg		fi	done        ## mark the packages that we were directly requested to install as uninstalled        for pkg in $requested_pkgs; do ipkg_set_uninstalled $pkg; done	local new_pkgs=	local pkgs_installed=0	while [ -n "pkgs" ]; do		curcheck=0		## echo "pkgs to install: {$pkgs}" > /dev/console		for pkg in $pkgs; do			curcheck="`expr $curcheck + 1`"			local is_installed="`ipkg_get_installed $pkg`"			if [ "$is_installed" = "installed" ]; then				echo "$pkg is installed" > /dev/console				continue			fi			local remaining_deps="`ipkg_unsatisfied_dependences $pkg`"			if [ -n "$remaining_deps" ]; then				new_pkgs="$new_pkgs $pkg"				### echo "Dependences not satisfied for $pkg: $remaining_deps"				if [ $curcheck -ne `echo  $pkgs|wc -w` ]; then			        	continue				fi			fi			local filename=			for src in `ipkg_src_names`; do				if ipkg_require_list $src; then					filename="`ipkg_extract_paragraph $pkg < $IPKG_LISTS_DIR/$src | ipkg_extract_field Filename | ipkg_extract_value`"					[ -n "$filename" ] && break ||:				fi			done			if [ -z "$filename" ]; then				echo "ipkg_get_install: ERROR: Cannot find package $pkg in $IPKG_LISTS_DIR"				echo "ipkg_get_install:        Check the spelling and maybe run \`ipkg update'."				ipkg_status_remove_sd $sd $pkg				return 1;			fi			echo ""			local tmp_pkg_file="$IPKG_TMP/"`ipkg_file_part $filename`			if ! ipkg_download `ipkg_src_byname $src`/$filename $tmp_pkg_file; then				echo "ipkg_get_install: Perhaps you need to run \`ipkg update'?"				return 1			fi			if ! ipkg_install_file_dest $dest $tmp_pkg_file; then				echo "ipkg_get_install: ERROR: Failed to install $tmp_pkg_file"				echo "ipkg_get_install: I'll leave it there for you to try a manual installation"				return 1			fi			ipkg_set_installed $pkg			pkgs_installed="`expr $pkgs_installed + 1`"			rm $tmp_pkg_file		done		### echo "Installed $pkgs_installed package(s) this round"		if [ $pkgs_installed -eq 0 ]; then			if [ -z "$new_pkgs" ]; then			    break			fi		fi		pkgs_installed=0		pkgs="$new_pkgs"		new_pkgs=		curcheck=0        done}ipkg_get_install() {	ipkg_get_install_dest $IPKG_ROOT $*}ipkg_install_file_dest() {	local dest="$1"	local filename="$2"	local sd=$dest/$IPKG_DIR_PREFIX	local info_dir=$sd/info	if [ ! -f "$filename" ]; then		echo "ipkg_install_file: ERROR: File $filename not found"		return 1	fi	local pkg="`ipkg_file_part $filename | sed 's/\([a-z0-9.+-]\+\)_.*/\1/'`"	local ext="`echo $filename | sed 's/.*\.//'`"	local pkg_extract_stdout	if [ "$ext" = "ipk" ]; then		pkg_extract_stdout="tar -xzOf"	elif [ "$ext" = "deb" ]; then		pkg_extract_stdout="ar p"	else		echo "ipkg_install_file: ERROR: File $filename has unknown extension $ext (not .ipk or .deb)"		return 1	fi	# Check dependencies	#local depends="`ipkg_depends $pkg | sed -e "s/\<$pkg\>//"`"	# Don't worry about deps that are scheduled for installation	#local missing_deps=	#for dep in $depends; do	#	if ! ipkg_status_all $dep | grep -q 'Status:[[:space:]]install'; then	#		missing_deps="$missing_deps $dep"	#	fi	#done	#if [ ! -z "$missing_deps" ]; then	#	if [ -n "$FORCE_DEPENDS" ]; then	#		echo "ipkg_install_file: Warning: $pkg depends on the following uninstalled programs: $missing_deps"	#	else	#		echo "ipkg_install_file: ERROR: $pkg depends on the following uninstalled programs:	#$missing_deps"	#		echo "ipkg_install_file: You may want to use \`ipkg install' to install these."	#		return 1	#	fi	#fi	mkdir -p $IPKG_TMP/$pkg/control	mkdir -p $IPKG_TMP/$pkg/data	mkdir -p $info_dir	if ! $pkg_extract_stdout $filename ./control.tar.gz|gzip -dc|tar -xf - -C $IPKG_TMP/$pkg/control ; then		echo "ipkg_install_file: ERROR unpacking control.tar.gz from $filename"		return 1	fi	if [ -n "$IPKG_OFFLINE_ROOT" ]; then		if grep -q '^InstallsOffline:[[:space:]]*no' $IPKG_TMP/$pkg/control/control; then			echo "*** Warning: Package $pkg may not be installed in offline mode"			echo "*** Warning: Scheduling $filename for pending installation (installing into $IPKG_PENDING_DIR)"			echo "Package: $pkgStatus: install ok pending" | ipkg_status_update_sd $sd $pkg			mkdir -p $IPKG_PENDING_DIR			cp -f $filename $IPKG_PENDING_DIR			rm -r $IPKG_TMP/$pkg/control			rm -r $IPKG_TMP/$pkg/data			rmdir $IPKG_TMP/$pkg			return 0		fi	fi	echo -n "Unpacking $pkg..."	set +o noglob	for file in $IPKG_TMP/$pkg/control/*; do		local base_file="`ipkg_file_part $file`"		mv $file $info_dir/$pkg.$base_file	done	set -o noglob	rm -r $IPKG_TMP/$pkg/control	if ! $pkg_extract_stdout $filename ./data.tar.gz|gzip -dc|(cd $IPKG_TMP/$pkg/data && $TOOLS_DIR/cpio -iud -H ustar) ; then		echo "ipkg_install_file: ERROR unpacking data.tar.gz from $filename"		return 1	fi	echo "Done."	echo -n "Configuring $pkg..."	export PKG_ROOT=$dest	if [ -x "$info_dir/$pkg.preinst" ]; then		if ! $info_dir/$pkg.preinst install; then			echo "$info_dir/$pkg.preinst failed. Aborting installation of $pkg"			rm -rf $IPKG_TMP/$pkg/data			rmdir $IPKG_TMP/$pkg			return 1		fi	fi	local old_conffiles="`ipkg_status_sd $sd $pkg Conffiles | ipkg_extract_value`"	local new_conffiles=	if [ -f "$info_dir/$pkg.conffiles" ]; then		for conffile in `cat $info_dir/$pkg.conffiles`; do			if [ -f "$dest/$conffile" ] && ! echo " $old_conffiles " | grep -q " $conffile "`md5sum $dest/$conffile | sed 's/ .*//'`; then				local use_maintainers_conffile=				if [ -z "$FORCE_DEFAULTS" ]; then					while true; do						echo -n "Configuration file \`$conffile' ==> File on system created by you or by a script. ==> File also in package provided by package maintainer.   What would you like to do about it ?  Your options are:    Y or I  : install the package maintainer's version    N or O  : keep your currently-installed version      D     : show the differences between the versions (if diff is installed) The default action is to keep your current version.*** `ipkg_file_part $conffile` (Y/I/N/O/D) [default=N] ? "						read response						case "$response" in						[YyIi] | [Yy][Ee][Ss])							use_maintainers_conffile=t							break						;;						[Dd])							echo "diff -u $dest/$conffile $IPKG_TMP/$pkg/data/$conffile"							diff -u $dest/$conffile $IPKG_TMP/$pkg/data/$conffile || true							echo "[Press ENTER to continue]"							read junk						;;						*)							break						;;						esac					done				fi				if [ -n "$use_maintainers_conffile" ]; then					local md5sum="`md5sum $IPKG_TMP/$pkg/data/$conffile | sed 's/ .*//'`"					new_conffiles="$new_conffiles $conffile $md5sum"				else					new_conffiles="$new_conffiles $conffile <custom>"					rm $IPKG_TMP/$pkg/data/$conffile				fi			else				md5sum="`md5sum $IPKG_TMP/$pkg/data/$conffile | sed 's/ .*//'`"				new_conffiles="$new_conffiles $conffile $md5sum"			fi		done	fi	local owd="`pwd`"	(cd $IPKG_TMP/$pkg/data/; find . | $TOOLS_DIR/cpio -o -H ustar | (cd $owd; cd $dest; $TOOLS_DIR/cpio -iud -H ustar))	rm -rf $IPKG_TMP/$pkg/data	rmdir $IPKG_TMP/$pkg	rm -f $info_dir/$pkg.list	$pkg_extract_stdout $filename ./data.tar.gz | gzip -dc | tar tf - | sed -e 's/^\.//' > $info_dir/$pkg.list	if [ -x "$info_dir/$pkg.postinst" ]; then		IPKG_INSTROOT="$IPKG_INSTROOT" $info_dir/$pkg.postinst configure	fi	if [ -n "$new_conffiles" ]; then		new_conffiles='Conffiles: '`echo $new_conffiles | ipkg_protect_slashes`	fi	local sed_safe_offline_root="`echo ${IPKG_OFFLINE_ROOT} | ipkg_protect_slashes`"	local sed_safe_root="`echo $dest | sed -e "s/^${sed_safe_offline_root}//" | ipkg_protect_slashes`"	sed -e "s/\(Package:.*\)/\1\\Status: install ok installed\\Root: ${sed_safe_root}\\${new_conffiles}/" $info_dir/$pkg.control | ipkg_status_update_sd $sd $pkg	rm -f $info_dir/$pkg.control	rm -f $info_dir/$pkg.conffiles	rm -f $info_dir/$pkg.preinst	rm -f $info_dir/$pkg.postinst	echo "Done."}ipkg_install_file() {	ipkg_install_file_dest $IPKG_ROOT $*}ipkg_install() {	while [ $# -gt 0 ]; do		local pkg="$1"		shift			case "$pkg" in		http://* | ftp://*)			local tmp_pkg_file="$IPKG_TMP/"`ipkg_file_part $pkg`			if ipkg_download $pkg $tmp_pkg_file; then				ipkg_install_file $tmp_pkg_file				rm $tmp_pkg_file			fi			;;		file:/*.ipk  | file://*.deb)				local ipkg_filename="`echo $pkg|sed 's/^file://'`"				ipkg_install_file $ipkg_filename			;;		*.ipk  | *.deb)			if [ -f "$pkg" ]; then				ipkg_install_file $pkg			else				echo "File not found $pkg" >&2			fi			;;		*)			ipkg_get_install $pkg || true			;;		esac	done}ipkg_install_pending() {	[ -n "$IPKG_OFFLINE_ROOT" ] && return 0 ||:	if [ -d "$IPKG_PENDING_DIR" ]; then		set +o noglob		local pending="`ls -1d $IPKG_PENDING_DIR/*.ipk 2> /dev/null`" || true		set -o noglob		if [ -n "$pending" ]; then			echo "The following packages in $IPKG_PENDING_DIR will now be installed:"			echo $pending			for filename in $pending; do				if ipkg_install_file $filename; then					rm $filename				fi			done		fi	fi	return 0}ipkg_install_wanted() {	local wanted="`ipkg_status_matching 'Status:[[:space:]]*install.*not-installed'`"	if [ -n "$wanted" ]; then		echo "The following package were previously requested but have not been installed:"		echo $wanted		if [ -n "$FORCE_DEFAULTS" ]; then			echo "Installing them now."		else			echo -n "Install them now [Y/n] ? "			read response			case "$response" in			[Nn] | [Nn][Oo])				return 0				;;			esac		fi		ipkg_install $wanted	fi	return 0}ipkg_upgrade_pkg() {	local pkg="$1"	local avail_ver="`ipkg_info $pkg Version | ipkg_extract_value | head -n 1`"	is_installed=	for dest_name in `ipkg_dest_names`; do		local dest="`ipkg_dest_byname $dest_name`"		local sd=$dest/$IPKG_DIR_PREFIX		local inst_ver="`ipkg_status_sd $sd $pkg Version | ipkg_extract_value`"		if [ -n "$inst_ver" ]; then			is_installed=t			if [ -z "$avail_ver" ]; then				echo "Assuming locally installed package $pkg ($inst_ver) is up to date"				return 0			fi			if [ "$avail_ver" = "$inst_ver" ]; then 				echo "Package $pkg ($inst_ver) installed in $dest_name is up to date"			elif ipkg_is_upgrade "$avail_ver" "$inst_ver"; then				echo "Upgrading $pkg ($dest_name) from $inst_ver to $avail_ver"				ipkg_get_install_dest $dest $pkg			else				echo "Not downgrading package $pkg from $inst_ver to $avail_ver"			fi		fi	done	if [ -z "$is_installed" ]; then		echo "Package $pkg does not appear to be installed"		return 0	fi}ipkg_upgrade() {	if [ $# -lt 1 ]; then		local pkgs="`ipkg_status_matching 'Status:.*[[:space:]]installed'`"	else		pkgs="$*"	fi		for pkg in $pkgs; do		ipkg_upgrade_pkg $pkg	done}ipkg_remove_pkg_dest() {	local dest="$1"	local pkg="$2"	local sd=$dest/$IPKG_DIR_PREFIX	local info_dir=$sd/info	if ! ipkg_status_installed_sd $sd $pkg; then		echo "ipkg_remove: Package $pkg does not appear to be installed in $dest"		if ipkg_status_mentioned_sd $sd $pkg; then			echo "Purging mention of $pkg from the ipkg database"			ipkg_status_remove_sd $sd $pkg		fi		return 1	fi	echo "ipkg_remove: Removing $pkg... "	local files="`cat $info_dir/$pkg.list`"	export PKG_ROOT=$dest	if [ -x "$info_dir/$pkg.prerm" ]; then		$info_dir/$pkg.prerm remove	fi	local conffiles="`ipkg_status_sd $sd $pkg Conffiles | ipkg_extract_value`"	local dirs_to_remove=	for file in $files; do		if [ -d "$dest/$file" ]; then			dirs_to_remove="$dirs_to_remove $dest/$file"		else			if echo " $conffiles " | grep -q " $file "; then				if echo " $conffiles " | grep -q " $file "`md5sum $dest/$file | sed 's/ .*//'`; then					rm -f $dest/$file				fi			else				rm -f $dest/$file			fi		fi	done	local removed_a_dir=t	while [ -n "$removed_a_dir" ]; do		removed_a_dir=		local new_dirs_to_remove=		for dir in $dirs_to_remove; do			if rmdir $dir >/dev/null 2>&1; then				removed_a_dir=t			else				new_dirs_to_remove="$new_dirs_to_remove $dir"			fi		done		dirs_to_remove="$new_dirs_to_remove"	done	if [ -n "$dirs_to_remove" ]; then		echo "ipkg_remove: Warning: Not removing the following directories since they are not empty:" >&2		echo "$dirs_to_remove" | sed -e 's/\/[/]\+/\//g' >&2	fi	if [ -x "$info_dir/$pkg.postrm" ]; then		$info_dir/$pkg.postrm remove	fi	ipkg_status_remove_sd $sd $pkg	set +o noglob	rm -f $info_dir/$pkg.*	set -o noglob	echo "Done."}ipkg_remove_pkg() {	local pkg="$1"	for dest in `ipkg_dests_all`; do		local sd=$dest/$IPKG_DIR_PREFIX		if ipkg_status_mentioned_sd $sd $pkg; then			ipkg_remove_pkg_dest $dest $pkg		fi	done}ipkg_remove() {	while [ $# -gt 0 ]; do		local pkg="$1"		shift		if [ -n "$DEST_NAME" ]; then			ipkg_remove_pkg_dest $IPKG_ROOT $pkg		else			ipkg_remove_pkg $pkg		fi	done}############ ipkg main############ Parse optionswhile [ $# -gt 0 ]; do	arg="$1"	case $arg in	-d | -dest)		[ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"		DEST_NAME="$2"		shift		;;	-o | -offline)		[ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"		IPKG_OFFLINE_ROOT="$2"		shift		;;	-force-depends)		FORCE_DEPENDS=t		;;	-force-defaults)		FORCE_DEFAULTS=t		;;	-c)		additional_options="$additional_options -c "		;;	-q)		additional_options="$additional_options -q "		;;	-*)		ipkg_usage "unknown option $arg"		;;	*)		break		;;	esac	shiftdone[ $# -ge 1 ] || ipkg_usage "ipkg must have one sub-command argument"cmd="$1"shiftipkg_load_configurationmkdir -p /tmp/ipkgcase "$cmd" inupdate|upgrade|list|info|status|install_pending)	;;install|depends|remove|files|search)	[ $# -ge 1 ] || ipkg_usage "ERROR: the \`\`$cmd'' command requires an argument"	;;*)	echo "ERROR: unknown sub-command \`$cmd'"	ipkg_usage	;;esac# Only install pending if we have an interactive sub-commandcase "$cmd" inupgrade|install)	ipkg_install_pending	ipkg_install_wanted	;;esacipkg_$cmd $*for a in `ls $IPKG_TMP`; do	rm -rf $IPKG_TMP/$adone
 |