Advertisement
Guest User

Untitled

a guest
Feb 19th, 2016
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.34 KB | None | 0 0
  1. #!/bin/bash
  2. # apt-cyg: install tool for Cygwin similar to debian apt-get
  3. #
  4. # The MIT License (MIT)
  5. #
  6. # Copyright (c) 2013 Trans-code Design
  7. #
  8. # Permission is hereby granted, free of charge, to any person obtaining a copy
  9. # of this software and associated documentation files (the "Software"), to deal
  10. # in the Software without restriction, including without limitation the rights
  11. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. # copies of the Software, and to permit persons to whom the Software is
  13. # furnished to do so, subject to the following conditions:
  14. #
  15. # The above copyright notice and this permission notice shall be included in
  16. # all copies or substantial portions of the Software.
  17. #
  18. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. # THE SOFTWARE.
  25.  
  26. usage="\
  27. NAME
  28. apt-cyg - package manager utility
  29.  
  30. SYNOPSIS
  31. apt-cyg [operation] [options] [targets]
  32.  
  33. DESCRIPTION
  34. apt-cyg is a package management utility that tracks installed packages on a
  35. Cygwin system. Invoking apt-cyg involves specifying an operation with any
  36. potential options and targets to operate on. A target is usually a package
  37. name, file name, URL, or a search string. Targets can be provided as command
  38. line arguments.
  39.  
  40. OPERATIONS
  41. install
  42. Install package(s).
  43.  
  44. remove
  45. Remove package(s) from the system.
  46.  
  47. update
  48. Download a fresh copy of the master package list (setup.ini) from the
  49. server defined in setup.rc.
  50.  
  51. download
  52. Retrieve package(s) from the server, but do not install/upgrade anything.
  53.  
  54. show
  55. Display information on given package(s).
  56.  
  57. depends
  58. Produce a dependency tree for a package.
  59.  
  60. rdepends
  61. Produce a tree of packages that depend on the named package.
  62.  
  63. list
  64. Search each locally-installed package for names that match regexp. If no
  65. package names are provided in the command line, all installed packages will
  66. be queried.
  67.  
  68. listall
  69. This will search each package in the master package list (setup.ini) for
  70. names that match regexp.
  71.  
  72. category
  73. Display all packages that are members of a named category.
  74.  
  75. listfiles
  76. List all files owned by a given package. Multiple packages can be specified
  77. on the command line.
  78.  
  79. search
  80. Search for downloaded packages that own the specified file(s). The path can
  81. be relative or absolute, and one or more files can be specified.
  82.  
  83. searchall
  84. Search cygwin.com to retrieve file information about packages. The provided
  85. target is considered to be a filename and searchall will return the
  86. package(s) which contain this file.
  87.  
  88. mirror
  89. Set the mirror; a full URL to a location where the database, packages, and
  90. signatures for this repository can be found. If no URL is provided, display
  91. current mirror.
  92.  
  93. cache
  94. Set the package cache directory. If a file is not found in cache directory,
  95. it will be downloaded. Unix and Windows forms are accepted, as well as
  96. absolute or regular paths. If no directory is provided, display current
  97. cache.
  98.  
  99. OPTIONS
  100. --nodeps
  101. Specify this option to skip all dependency checks.
  102.  
  103. --version
  104. Display version and exit.
  105. "
  106.  
  107. version="\
  108. apt-cyg version 1
  109.  
  110. The MIT License (MIT)
  111.  
  112. Copyright (c) 2005-9 Stephen Jungels
  113. "
  114.  
  115. function wget {
  116. if command wget -h &>/dev/null
  117. then
  118. command wget "$@"
  119. else
  120. warn wget is not installed, using lynx as fallback
  121. set "${*: -1}"
  122. lynx -source "$1" > "${1##*/}"
  123. fi
  124. }
  125.  
  126. function find-workspace {
  127. # default working directory and mirror
  128.  
  129. # work wherever setup worked last, if possible
  130. cache=$(awk '
  131. BEGIN {
  132. RS = "\n\\<"
  133. FS = "\n\t"
  134. }
  135. $1 == "last-cache" {
  136. print $2
  137. }
  138. ' /etc/setup/setup.rc)
  139.  
  140. mirror=$(awk '
  141. /last-mirror/ {
  142. getline
  143. print $1
  144. }
  145. ' /etc/setup/setup.rc)
  146. mirrordir=$(sed '
  147. s / %2f g
  148. s : %3a g
  149. ' <<< "$mirror")
  150.  
  151. mkdir -p "$cache/$mirrordir/$arch"
  152. cd "$cache/$mirrordir/$arch"
  153. if [ -e setup.ini ]
  154. then
  155. return 0
  156. else
  157. get-setup
  158. return 1
  159. fi
  160. }
  161.  
  162. function get-setup {
  163. touch setup.ini
  164. mv setup.ini setup.ini-save
  165. wget -N $mirror/$arch/setup.bz2
  166. if [ -e setup.bz2 ]
  167. then
  168. bunzip2 setup.bz2
  169. mv setup setup.ini
  170. echo Updated setup.ini
  171. else
  172. echo Error updating setup.ini, reverting
  173. mv setup.ini-save setup.ini
  174. fi
  175. }
  176.  
  177. function check-packages {
  178. if [[ $pks ]]
  179. then
  180. return 0
  181. else
  182. echo No packages found.
  183. return 1
  184. fi
  185. }
  186.  
  187. function warn {
  188. printf '\e[1;31m%s\e[m\n' "$*" >&2
  189. }
  190.  
  191. function apt-update {
  192. if find-workspace
  193. then
  194. get-setup
  195. fi
  196. }
  197.  
  198. function apt-category {
  199. check-packages
  200. find-workspace
  201. for pkg in "${pks[@]}"
  202. do
  203. awk '
  204. $1 == "@" {
  205. pck = $2
  206. }
  207. $1 == "category:" && $0 ~ query {
  208. print pck
  209. }
  210. ' query="$pks" setup.ini
  211. done
  212. }
  213.  
  214. function apt-list {
  215. local sbq
  216. for pkg in "${pks[@]}"
  217. do
  218. let sbq++ && echo
  219. awk 'NR>1 && $1~pkg && $0=$1' pkg="$pkg" /etc/setup/installed.db
  220. done
  221. let sbq && return
  222. awk 'NR>1 && $0=$1' /etc/setup/installed.db
  223. }
  224.  
  225. function apt-listall {
  226. check-packages
  227. find-workspace
  228. local sbq
  229. for pkg in "${pks[@]}"
  230. do
  231. let sbq++ && echo
  232. awk '$1~pkg && $0=$1' RS='\n\n@ ' FS='\n' pkg="$pkg" setup.ini
  233. done
  234. }
  235.  
  236. function apt-listfiles {
  237. check-packages
  238. find-workspace
  239. local pkg sbq
  240. for pkg in "${pks[@]}"
  241. do
  242. (( sbq++ )) && echo
  243. if [ ! -e /etc/setup/"$pkg".lst.gz ]
  244. then
  245. download "$pkg"
  246. fi
  247. gzip -cd /etc/setup/"$pkg".lst.gz
  248. done
  249. }
  250.  
  251. function apt-show {
  252. find-workspace
  253. check-packages
  254. for pkg in "${pks[@]}"
  255. do
  256. (( notfirst++ )) && echo
  257. awk '
  258. $1 == query {
  259. print
  260. fd++
  261. }
  262. END {
  263. if (! fd)
  264. print "Unable to locate package " query
  265. }
  266. ' RS='\n\n@ ' FS='\n' query="$pkg" setup.ini
  267. done
  268. }
  269.  
  270. function apt-depends {
  271. find-workspace
  272. check-packages
  273. for pkg in "${pks[@]}"
  274. do
  275. awk '
  276. @include "join"
  277. $1 == "@" {
  278. apg = $2
  279. }
  280. $1 == "requires:" {
  281. for (z=2; z<=NF; z++)
  282. reqs[apg][z-1] = $z
  283. }
  284. END {
  285. prpg(ENVIRON["pkg"])
  286. }
  287. function smartmatch(small, large, values) {
  288. for (each in large)
  289. values[large[each]]
  290. return small in values
  291. }
  292. function prpg(fpg) {
  293. if (smartmatch(fpg, spath)) return
  294. spath[length(spath)+1] = fpg
  295. print join(spath, 1, length(spath), " > ")
  296. if (isarray(reqs[fpg]))
  297. for (each in reqs[fpg])
  298. prpg(reqs[fpg][each])
  299. delete spath[length(spath)]
  300. }
  301. ' setup.ini
  302. done
  303. }
  304.  
  305. function apt-rdepends {
  306. find-workspace
  307. for pkg in "${pks[@]}"
  308. do
  309. awk '
  310. @include "join"
  311. $1 == "@" {
  312. apg = $2
  313. }
  314. $1 == "requires:" {
  315. for (z=2; z<=NF; z++)
  316. reqs[$z][length(reqs[$z])+1] = apg
  317. }
  318. END {
  319. prpg(ENVIRON["pkg"])
  320. }
  321. function smartmatch(small, large, values) {
  322. for (each in large)
  323. values[large[each]]
  324. return small in values
  325. }
  326. function prpg(fpg) {
  327. if (smartmatch(fpg, spath)) return
  328. spath[length(spath)+1] = fpg
  329. print join(spath, 1, length(spath), " < ")
  330. if (isarray(reqs[fpg]))
  331. for (each in reqs[fpg])
  332. prpg(reqs[fpg][each])
  333. delete spath[length(spath)]
  334. }
  335. ' setup.ini
  336. done
  337. }
  338.  
  339. function apt-download {
  340. check-packages
  341. find-workspace
  342. local pkg sbq
  343. for pkg in "${pks[@]}"
  344. do
  345. (( sbq++ )) && echo
  346. download "$pkg"
  347. done
  348. }
  349.  
  350. function download {
  351. local pkg digest digactual
  352. pkg=$1
  353. # look for package and save desc file
  354.  
  355. awk '$1 == pc' RS='\n\n@ ' FS='\n' pc=$pkg setup.ini > desc
  356. if [ ! -s desc ]
  357. then
  358. echo Unable to locate package $pkg
  359. exit 1
  360. fi
  361.  
  362. # download and unpack the bz2 or xz file
  363.  
  364. # pick the latest version, which comes first
  365. set -- $(awk '$1 == "install:"' desc)
  366. if (( ! $# ))
  367. then
  368. echo 'Could not find "install" in package description: obsolete package?'
  369. exit 1
  370. fi
  371.  
  372. dn=$(dirname $2)
  373. bn=$(basename $2)
  374.  
  375. # check the md5
  376. digest=$4
  377. case ${#digest} in
  378. 32) hash=md5sum ;;
  379. 128) hash=sha512sum ;;
  380. esac
  381. mkdir -p "$cache/$mirrordir/$dn"
  382. cd "$cache/$mirrordir/$dn"
  383. if ! test -e $bn || ! $hash -c <<< "$digest $bn"
  384. then
  385. wget -O $bn $mirror/$dn/$bn
  386. $hash -c <<< "$digest $bn" || exit
  387. fi
  388.  
  389. tar tf $bn | gzip > /etc/setup/"$pkg".lst.gz
  390. cd ~-
  391. mv desc "$cache/$mirrordir/$dn"
  392. echo $dn $bn > /tmp/dwn
  393. }
  394.  
  395. function apt-search {
  396. check-packages
  397. echo Searching downloaded packages...
  398. for pkg in "${pks[@]}"
  399. do
  400. key=$(type -P "$pkg" | sed s./..)
  401. [[ $key ]] || key=$pkg
  402. for manifest in /etc/setup/*.lst.gz
  403. do
  404. if gzip -cd $manifest | grep -q "$key"
  405. then
  406. package=$(sed '
  407. s,/etc/setup/,,
  408. s,.lst.gz,,
  409. ' <<< $manifest)
  410. echo $package
  411. fi
  412. done
  413. done
  414. }
  415.  
  416. function apt-searchall {
  417. cd /tmp
  418. for pkg in "${pks[@]}"
  419. do
  420. printf -v qs 'text=1&arch=%s&grep=%s' $arch "$pkg"
  421. wget -O matches cygwin.com/cgi-bin2/package-grep.cgi?"$qs"
  422. awk '
  423. NR == 1 {next}
  424. mc[$1]++ {next}
  425. /-debuginfo-/ {next}
  426. /^cygwin32-/ {next}
  427. {print $1}
  428. ' FS=-[[:digit:]] matches
  429. done
  430. }
  431.  
  432. function apt-install {
  433. check-packages
  434. find-workspace
  435. local pkg dn bn requires wr package sbq script
  436. for pkg in "${pks[@]}"
  437. do
  438.  
  439. if grep -q "^$pkg " /etc/setup/installed.db
  440. then
  441. echo Package $pkg is already installed, skipping
  442. continue
  443. fi
  444. (( sbq++ )) && echo
  445. echo Installing $pkg
  446.  
  447. download $pkg
  448. read dn bn </tmp/dwn
  449. echo Unpacking...
  450.  
  451. cd "$cache/$mirrordir/$dn"
  452. tar -x -C / -f $bn
  453. # update the package database
  454.  
  455. awk '
  456. ins != 1 && pkg < $1 {
  457. print pkg, bz, 0
  458. ins = 1
  459. }
  460. 1
  461. END {
  462. if (ins != 1) print pkg, bz, 0
  463. }
  464. ' pkg="$pkg" bz=$bn /etc/setup/installed.db > /tmp/awk.$$
  465. mv /etc/setup/installed.db /etc/setup/installed.db-save
  466. mv /tmp/awk.$$ /etc/setup/installed.db
  467.  
  468. [ -v nodeps ] && continue
  469. # recursively install required packages
  470.  
  471. requires=$(awk '$1=="requires", $0=$2' FS=': ' desc)
  472. cd ~-
  473. wr=0
  474. if [[ $requires ]]
  475. then
  476. echo Package $pkg requires the following packages, installing:
  477. echo $requires
  478. for package in $requires
  479. do
  480. if grep -q "^$package " /etc/setup/installed.db
  481. then
  482. echo Package $package is already installed, skipping
  483. continue
  484. fi
  485. apt-cyg install --noscripts $package || (( wr++ ))
  486. done
  487. fi
  488. if (( wr ))
  489. then
  490. echo some required packages did not install, continuing
  491. fi
  492.  
  493. # run all postinstall scripts
  494.  
  495. [ -v noscripts ] && continue
  496. find /etc/postinstall -name '*.sh' | while read script
  497. do
  498. echo Running $script
  499. $script
  500. mv $script $script.done
  501. done
  502. echo Package $pkg installed
  503.  
  504. done
  505. }
  506.  
  507. function apt-remove {
  508. check-packages
  509. cd /etc
  510. cygcheck awk bash bunzip2 grep gzip mv sed tar xz > setup/essential.lst
  511. for pkg in "${pks[@]}"
  512. do
  513.  
  514. if ! grep -q "^$pkg " setup/installed.db
  515. then
  516. echo Package $pkg is not installed, skipping
  517. continue
  518. fi
  519.  
  520. if [ ! -e setup/"$pkg".lst.gz ]
  521. then
  522. warn Package manifest missing, cannot remove $pkg. Exiting
  523. exit 1
  524. fi
  525. gzip -dk setup/"$pkg".lst.gz
  526. awk '
  527. NR == FNR {
  528. if ($NF) ess[$NF]
  529. next
  530. }
  531. $NF in ess {
  532. exit 1
  533. }
  534. ' FS='[/\\\\]' setup/{essential,$pkg}.lst
  535. esn=$?
  536. if [ $esn = 0 ]
  537. then
  538. echo Removing $pkg
  539. if [ -e preremove/"$pkg".sh ]
  540. then
  541. preremove/"$pkg".sh
  542. rm preremove/"$pkg".sh
  543. fi
  544. mapfile dt < setup/"$pkg".lst
  545. for each in ${dt[*]}
  546. do
  547. [ -f /$each ] && rm /$each
  548. done
  549. for each in ${dt[*]}
  550. do
  551. [ -d /$each ] && rmdir --i /$each
  552. done
  553. rm -f setup/"$pkg".lst.gz postinstall/"$pkg".sh.done
  554. awk -i inplace '$1 != ENVIRON["pkg"]' setup/installed.db
  555. echo Package $pkg removed
  556. fi
  557. rm setup/"$pkg".lst
  558. if [ $esn = 1 ]
  559. then
  560. warn apt-cyg cannot remove package $pkg, exiting
  561. exit 1
  562. fi
  563.  
  564. done
  565. }
  566.  
  567. function apt-mirror {
  568. if [ "$pks" ]
  569. then
  570. awk -i inplace '
  571. 1
  572. /last-mirror/ {
  573. getline
  574. print "\t" pks
  575. }
  576. ' pks="$pks" /etc/setup/setup.rc
  577. echo Mirror set to "$pks".
  578. else
  579. awk '
  580. /last-mirror/ {
  581. getline
  582. print $1
  583. }
  584. ' /etc/setup/setup.rc
  585. fi
  586. }
  587.  
  588. function apt-cache {
  589. if [ "$pks" ]
  590. then
  591. vas=$(cygpath -aw "$pks")
  592. awk -i inplace '
  593. 1
  594. /last-cache/ {
  595. getline
  596. print "\t" vas
  597. }
  598. ' vas="${vas//\\/\\\\}" /etc/setup/setup.rc
  599. echo Cache set to "$vas".
  600. else
  601. awk '
  602. /last-cache/ {
  603. getline
  604. print $1
  605. }
  606. ' /etc/setup/setup.rc
  607. fi
  608. }
  609.  
  610. if [ -p /dev/stdin ]
  611. then
  612. mapfile -t pks
  613. fi
  614.  
  615. # process options
  616. until [ $# = 0 ]
  617. do
  618. case "$1" in
  619.  
  620. --nodeps)
  621. nodeps=1
  622. shift
  623. ;;
  624.  
  625. --noscripts)
  626. noscripts=1
  627. shift
  628. ;;
  629.  
  630. --version)
  631. printf "$version"
  632. exit
  633. ;;
  634.  
  635. update)
  636. command=$1
  637. shift
  638. ;;
  639.  
  640. list | cache | remove | depends | listall | download | listfiles |\
  641. show | mirror | search | install | category | rdepends | searchall )
  642. if [[ $command ]]
  643. then
  644. pks+=("$1")
  645. else
  646. command=$1
  647. fi
  648. shift
  649. ;;
  650.  
  651. *)
  652. pks+=("$1")
  653. shift
  654. ;;
  655.  
  656. esac
  657. done
  658.  
  659. set -a
  660.  
  661. if type -t apt-$command | grep -q function
  662. then
  663. readonly arch=${HOSTTYPE/i6/x}
  664. apt-$command
  665. else
  666. printf "$usage"
  667. fi
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement