📄 ipkg
字号:
#!/bin/sh# 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.## modified by sharp 2001## This version of ipkg is based on revision 1.21 from ## http://cvs.handhelds.org/cgi-bin/viewcvs.cgi/familiar/dist/ipkg/sh/ipkg## It contains the following changes for Qtopia:## * IPKG_CONF_DIR is located in the Qtopia directory by default# * The script works under ash, and with non-GNU tar# * It accepts some common errors in 3rdparty Qtopia packages:# - Uppercase letters in package names# - pre/post scripts without executable permissions# * More testing for error conditions, and cleanups# * Shorter timeout for network install# * Removed warning output -- user cannot do anything about it## Trolltech 2003set -eif [ -z "$QTDIR" ]; then QTDIR=/opt/Qtopiafiif [ -z "$IPKG_CONF_DIR" ]; then IPKG_CONF_DIR=/$QTDIR/etcfi# By default do not do globbing. Any command wanting globbing should# explicitly enable it first and disable it afterwards.set -o noglobipkg_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` local destor=`echo "$IPKG_OFFLINE_ROOT" | ipkg_protect_slashes` sed -ne "/^dest[[:space:]]\+$destre/{s/^dest[[:space:]]\+[^[:space:]]\+[[:space:]]\+//s/^/$destor/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" IPKG_OFFLINE_ROOT=`ipkg_option offline_root` # 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 [ -n "$IPKG_OFFLINE_ROOT" ]; then IPKG_TMP=/tmp/ipkg else IPKG_TMP=$IPKG_ROOT/tmp/ipkg fi # 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` 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 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> 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).Force 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 # retry 2 if ! wget -t1 --timeout=60 --passive-ftp -nd $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 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-zA-Z0-9.+-]*$1[a-zA-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_depends() { local new_pkgs="$*" local all_deps= local installed_pkgs=`ipkg_status_matching_all 'Status:.*[[:space:]]installed'` 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-zA-Z0-9.+-]'; then echo "ipkg_depends: ERROR: Package name $pkg contains illegal characters (should be [a-zA-Z0-9.+-])" >&2 echo "error" 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-zA-Z0-9.+-]\+[[:space:]]*\)\+//gs/,/ /gs/ \+/ /g'` done new_deps=`echo $new_deps | sed -e 's/[[:space:]]\+/\\/g' | sort | uniq` local maybe_new_pkgs=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -