Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # apt-cyg: install tool for Cygwin similar to debian apt-get
- #
- # The MIT License (MIT)
- #
- # Copyright (c) 2013 Trans-code Design
- #
- # Permission is hereby granted, free of charge, to any person obtaining a copy
- # of this software and associated documentation files (the "Software"), to deal
- # in the Software without restriction, including without limitation the rights
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- # copies of the Software, and to permit persons to whom the Software is
- # furnished to do so, subject to the following conditions:
- #
- # The above copyright notice and this permission notice shall be included in
- # all copies or substantial portions of the Software.
- #
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- # THE SOFTWARE.
- usage="\
- NAME
- apt-cyg - package manager utility
- SYNOPSIS
- apt-cyg [operation] [options] [targets]
- DESCRIPTION
- apt-cyg is a package management utility that tracks installed packages on a
- Cygwin system. Invoking apt-cyg involves specifying an operation with any
- potential options and targets to operate on. A target is usually a package
- name, file name, URL, or a search string. Targets can be provided as command
- line arguments.
- OPERATIONS
- install
- Install package(s).
- remove
- Remove package(s) from the system.
- update
- Download a fresh copy of the master package list (setup.ini) from the
- server defined in setup.rc.
- download
- Retrieve package(s) from the server, but do not install/upgrade anything.
- show
- Display information on given package(s).
- depends
- Produce a dependency tree for a package.
- rdepends
- Produce a tree of packages that depend on the named package.
- list
- Search each locally-installed package for names that match regexp. If no
- package names are provided in the command line, all installed packages will
- be queried.
- listall
- This will search each package in the master package list (setup.ini) for
- names that match regexp.
- category
- Display all packages that are members of a named category.
- listfiles
- List all files owned by a given package. Multiple packages can be specified
- on the command line.
- search
- Search for downloaded packages that own the specified file(s). The path can
- be relative or absolute, and one or more files can be specified.
- searchall
- Search cygwin.com to retrieve file information about packages. The provided
- target is considered to be a filename and searchall will return the
- package(s) which contain this file.
- mirror
- Set the mirror; a full URL to a location where the database, packages, and
- signatures for this repository can be found. If no URL is provided, display
- current mirror.
- cache
- Set the package cache directory. If a file is not found in cache directory,
- it will be downloaded. Unix and Windows forms are accepted, as well as
- absolute or regular paths. If no directory is provided, display current
- cache.
- OPTIONS
- --nodeps
- Specify this option to skip all dependency checks.
- --version
- Display version and exit.
- "
- version="\
- apt-cyg version 1
- The MIT License (MIT)
- Copyright (c) 2005-9 Stephen Jungels
- "
- function wget {
- if command wget -h &>/dev/null
- then
- command wget "$@"
- else
- warn wget is not installed, using lynx as fallback
- set "${*: -1}"
- lynx -source "$1" > "${1##*/}"
- fi
- }
- function find-workspace {
- # default working directory and mirror
- # work wherever setup worked last, if possible
- cache=$(awk '
- BEGIN {
- RS = "\n\\<"
- FS = "\n\t"
- }
- $1 == "last-cache" {
- print $2
- }
- ' /etc/setup/setup.rc)
- mirror=$(awk '
- /last-mirror/ {
- getline
- print $1
- }
- ' /etc/setup/setup.rc)
- mirrordir=$(sed '
- s / %2f g
- s : %3a g
- ' <<< "$mirror")
- mkdir -p "$cache/$mirrordir/$arch"
- cd "$cache/$mirrordir/$arch"
- if [ -e setup.ini ]
- then
- return 0
- else
- get-setup
- return 1
- fi
- }
- function get-setup {
- touch setup.ini
- mv setup.ini setup.ini-save
- wget -N $mirror/$arch/setup.bz2
- if [ -e setup.bz2 ]
- then
- bunzip2 setup.bz2
- mv setup setup.ini
- echo Updated setup.ini
- else
- echo Error updating setup.ini, reverting
- mv setup.ini-save setup.ini
- fi
- }
- function check-packages {
- if [[ $pks ]]
- then
- return 0
- else
- echo No packages found.
- return 1
- fi
- }
- function warn {
- printf '\e[1;31m%s\e[m\n' "$*" >&2
- }
- function apt-update {
- if find-workspace
- then
- get-setup
- fi
- }
- function apt-category {
- check-packages
- find-workspace
- for pkg in "${pks[@]}"
- do
- awk '
- $1 == "@" {
- pck = $2
- }
- $1 == "category:" && $0 ~ query {
- print pck
- }
- ' query="$pks" setup.ini
- done
- }
- function apt-list {
- local sbq
- for pkg in "${pks[@]}"
- do
- let sbq++ && echo
- awk 'NR>1 && $1~pkg && $0=$1' pkg="$pkg" /etc/setup/installed.db
- done
- let sbq && return
- awk 'NR>1 && $0=$1' /etc/setup/installed.db
- }
- function apt-listall {
- check-packages
- find-workspace
- local sbq
- for pkg in "${pks[@]}"
- do
- let sbq++ && echo
- awk '$1~pkg && $0=$1' RS='\n\n@ ' FS='\n' pkg="$pkg" setup.ini
- done
- }
- function apt-listfiles {
- check-packages
- find-workspace
- local pkg sbq
- for pkg in "${pks[@]}"
- do
- (( sbq++ )) && echo
- if [ ! -e /etc/setup/"$pkg".lst.gz ]
- then
- download "$pkg"
- fi
- gzip -cd /etc/setup/"$pkg".lst.gz
- done
- }
- function apt-show {
- find-workspace
- check-packages
- for pkg in "${pks[@]}"
- do
- (( notfirst++ )) && echo
- awk '
- $1 == query {
- print
- fd++
- }
- END {
- if (! fd)
- print "Unable to locate package " query
- }
- ' RS='\n\n@ ' FS='\n' query="$pkg" setup.ini
- done
- }
- function apt-depends {
- find-workspace
- check-packages
- for pkg in "${pks[@]}"
- do
- awk '
- @include "join"
- $1 == "@" {
- apg = $2
- }
- $1 == "requires:" {
- for (z=2; z<=NF; z++)
- reqs[apg][z-1] = $z
- }
- END {
- prpg(ENVIRON["pkg"])
- }
- function smartmatch(small, large, values) {
- for (each in large)
- values[large[each]]
- return small in values
- }
- function prpg(fpg) {
- if (smartmatch(fpg, spath)) return
- spath[length(spath)+1] = fpg
- print join(spath, 1, length(spath), " > ")
- if (isarray(reqs[fpg]))
- for (each in reqs[fpg])
- prpg(reqs[fpg][each])
- delete spath[length(spath)]
- }
- ' setup.ini
- done
- }
- function apt-rdepends {
- find-workspace
- for pkg in "${pks[@]}"
- do
- awk '
- @include "join"
- $1 == "@" {
- apg = $2
- }
- $1 == "requires:" {
- for (z=2; z<=NF; z++)
- reqs[$z][length(reqs[$z])+1] = apg
- }
- END {
- prpg(ENVIRON["pkg"])
- }
- function smartmatch(small, large, values) {
- for (each in large)
- values[large[each]]
- return small in values
- }
- function prpg(fpg) {
- if (smartmatch(fpg, spath)) return
- spath[length(spath)+1] = fpg
- print join(spath, 1, length(spath), " < ")
- if (isarray(reqs[fpg]))
- for (each in reqs[fpg])
- prpg(reqs[fpg][each])
- delete spath[length(spath)]
- }
- ' setup.ini
- done
- }
- function apt-download {
- check-packages
- find-workspace
- local pkg sbq
- for pkg in "${pks[@]}"
- do
- (( sbq++ )) && echo
- download "$pkg"
- done
- }
- function download {
- local pkg digest digactual
- pkg=$1
- # look for package and save desc file
- awk '$1 == pc' RS='\n\n@ ' FS='\n' pc=$pkg setup.ini > desc
- if [ ! -s desc ]
- then
- echo Unable to locate package $pkg
- exit 1
- fi
- # download and unpack the bz2 or xz file
- # pick the latest version, which comes first
- set -- $(awk '$1 == "install:"' desc)
- if (( ! $# ))
- then
- echo 'Could not find "install" in package description: obsolete package?'
- exit 1
- fi
- dn=$(dirname $2)
- bn=$(basename $2)
- # check the md5
- digest=$4
- case ${#digest} in
- 32) hash=md5sum ;;
- 128) hash=sha512sum ;;
- esac
- mkdir -p "$cache/$mirrordir/$dn"
- cd "$cache/$mirrordir/$dn"
- if ! test -e $bn || ! $hash -c <<< "$digest $bn"
- then
- wget -O $bn $mirror/$dn/$bn
- $hash -c <<< "$digest $bn" || exit
- fi
- tar tf $bn | gzip > /etc/setup/"$pkg".lst.gz
- cd ~-
- mv desc "$cache/$mirrordir/$dn"
- echo $dn $bn > /tmp/dwn
- }
- function apt-search {
- check-packages
- echo Searching downloaded packages...
- for pkg in "${pks[@]}"
- do
- key=$(type -P "$pkg" | sed s./..)
- [[ $key ]] || key=$pkg
- for manifest in /etc/setup/*.lst.gz
- do
- if gzip -cd $manifest | grep -q "$key"
- then
- package=$(sed '
- s,/etc/setup/,,
- s,.lst.gz,,
- ' <<< $manifest)
- echo $package
- fi
- done
- done
- }
- function apt-searchall {
- cd /tmp
- for pkg in "${pks[@]}"
- do
- printf -v qs 'text=1&arch=%s&grep=%s' $arch "$pkg"
- wget -O matches cygwin.com/cgi-bin2/package-grep.cgi?"$qs"
- awk '
- NR == 1 {next}
- mc[$1]++ {next}
- /-debuginfo-/ {next}
- /^cygwin32-/ {next}
- {print $1}
- ' FS=-[[:digit:]] matches
- done
- }
- function apt-install {
- check-packages
- find-workspace
- local pkg dn bn requires wr package sbq script
- for pkg in "${pks[@]}"
- do
- if grep -q "^$pkg " /etc/setup/installed.db
- then
- echo Package $pkg is already installed, skipping
- continue
- fi
- (( sbq++ )) && echo
- echo Installing $pkg
- download $pkg
- read dn bn </tmp/dwn
- echo Unpacking...
- cd "$cache/$mirrordir/$dn"
- tar -x -C / -f $bn
- # update the package database
- awk '
- ins != 1 && pkg < $1 {
- print pkg, bz, 0
- ins = 1
- }
- 1
- END {
- if (ins != 1) print pkg, bz, 0
- }
- ' pkg="$pkg" bz=$bn /etc/setup/installed.db > /tmp/awk.$$
- mv /etc/setup/installed.db /etc/setup/installed.db-save
- mv /tmp/awk.$$ /etc/setup/installed.db
- [ -v nodeps ] && continue
- # recursively install required packages
- requires=$(awk '$1=="requires", $0=$2' FS=': ' desc)
- cd ~-
- wr=0
- if [[ $requires ]]
- then
- echo Package $pkg requires the following packages, installing:
- echo $requires
- for package in $requires
- do
- if grep -q "^$package " /etc/setup/installed.db
- then
- echo Package $package is already installed, skipping
- continue
- fi
- apt-cyg install --noscripts $package || (( wr++ ))
- done
- fi
- if (( wr ))
- then
- echo some required packages did not install, continuing
- fi
- # run all postinstall scripts
- [ -v noscripts ] && continue
- find /etc/postinstall -name '*.sh' | while read script
- do
- echo Running $script
- $script
- mv $script $script.done
- done
- echo Package $pkg installed
- done
- }
- function apt-remove {
- check-packages
- cd /etc
- cygcheck awk bash bunzip2 grep gzip mv sed tar xz > setup/essential.lst
- for pkg in "${pks[@]}"
- do
- if ! grep -q "^$pkg " setup/installed.db
- then
- echo Package $pkg is not installed, skipping
- continue
- fi
- if [ ! -e setup/"$pkg".lst.gz ]
- then
- warn Package manifest missing, cannot remove $pkg. Exiting
- exit 1
- fi
- gzip -dk setup/"$pkg".lst.gz
- awk '
- NR == FNR {
- if ($NF) ess[$NF]
- next
- }
- $NF in ess {
- exit 1
- }
- ' FS='[/\\\\]' setup/{essential,$pkg}.lst
- esn=$?
- if [ $esn = 0 ]
- then
- echo Removing $pkg
- if [ -e preremove/"$pkg".sh ]
- then
- preremove/"$pkg".sh
- rm preremove/"$pkg".sh
- fi
- mapfile dt < setup/"$pkg".lst
- for each in ${dt[*]}
- do
- [ -f /$each ] && rm /$each
- done
- for each in ${dt[*]}
- do
- [ -d /$each ] && rmdir --i /$each
- done
- rm -f setup/"$pkg".lst.gz postinstall/"$pkg".sh.done
- awk -i inplace '$1 != ENVIRON["pkg"]' setup/installed.db
- echo Package $pkg removed
- fi
- rm setup/"$pkg".lst
- if [ $esn = 1 ]
- then
- warn apt-cyg cannot remove package $pkg, exiting
- exit 1
- fi
- done
- }
- function apt-mirror {
- if [ "$pks" ]
- then
- awk -i inplace '
- 1
- /last-mirror/ {
- getline
- print "\t" pks
- }
- ' pks="$pks" /etc/setup/setup.rc
- echo Mirror set to "$pks".
- else
- awk '
- /last-mirror/ {
- getline
- print $1
- }
- ' /etc/setup/setup.rc
- fi
- }
- function apt-cache {
- if [ "$pks" ]
- then
- vas=$(cygpath -aw "$pks")
- awk -i inplace '
- 1
- /last-cache/ {
- getline
- print "\t" vas
- }
- ' vas="${vas//\\/\\\\}" /etc/setup/setup.rc
- echo Cache set to "$vas".
- else
- awk '
- /last-cache/ {
- getline
- print $1
- }
- ' /etc/setup/setup.rc
- fi
- }
- if [ -p /dev/stdin ]
- then
- mapfile -t pks
- fi
- # process options
- until [ $# = 0 ]
- do
- case "$1" in
- --nodeps)
- nodeps=1
- shift
- ;;
- --noscripts)
- noscripts=1
- shift
- ;;
- --version)
- printf "$version"
- exit
- ;;
- update)
- command=$1
- shift
- ;;
- list | cache | remove | depends | listall | download | listfiles |\
- show | mirror | search | install | category | rdepends | searchall )
- if [[ $command ]]
- then
- pks+=("$1")
- else
- command=$1
- fi
- shift
- ;;
- *)
- pks+=("$1")
- shift
- ;;
- esac
- done
- set -a
- if type -t apt-$command | grep -q function
- then
- readonly arch=${HOSTTYPE/i6/x}
- apt-$command
- else
- printf "$usage"
- fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement