ipkg 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198
  1. # ipkg - the itsy package management system
  2. #
  3. # Copyright (C) 2001 Carl D. Worth
  4. #
  5. # This program is free software; you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation; either version 2, or (at your option)
  8. # any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. set -e
  15. # By default do not do globbing. Any command wanting globbing should
  16. # explicitly enable it first and disable it afterwards.
  17. set -o noglob
  18. ipkg_is_upgrade () {
  19. local A B a b
  20. A=$(echo $1 | sed -r "s/([0-9]+)[^[:alnum:]]*/ \1 /g").
  21. B=$(echo $2 | sed -r "s/([0-9]+)[^[:alnum:]]*/ \1 /g").
  22. while [ \! -z "$A" ] && [ \! -z "$B" ]; do {
  23. set $A; a=$1; shift; A=$*
  24. set $B; b=$1; shift; B=$*
  25. [ "$a" -lt "$b" ] 2>&- && return 1 ||:
  26. { [ "$a" -gt "$b" ] 2>&- || [ "$a" ">" "$b" ]; } && return ||:
  27. }; done
  28. return 1
  29. }
  30. ipkg_srcs() {
  31. local srcre="$1"
  32. sed -ne "s/^src[[:space:]]\+$srcre[[:space:]]\+//p" < $IPKG_CONF
  33. }
  34. ipkg_src_names() {
  35. sed -ne "s/^src[[:space:]]\+\([^[:space:]]\+\).*/\1/p" < $IPKG_CONF
  36. }
  37. ipkg_src_byname() {
  38. local src="$1"
  39. ipkg_srcs $src | head -n 1
  40. }
  41. ipkg_dests() {
  42. local destre="`echo $1 | ipkg_protect_slashes`"
  43. sed -ne "/^dest[[:space:]]\+$destre/{
  44. s/^dest[[:space:]]\+[^[:space:]]\+[[:space:]]\+//
  45. s/^/`echo $IPKG_OFFLINE_ROOT | ipkg_protect_slashes`/
  46. p
  47. }" < $IPKG_CONF
  48. }
  49. ipkg_dest_names() {
  50. sed -ne "s/^dest[[:space:]]\+\([^[:space:]]\+\).*/\1/p" < $IPKG_CONF
  51. }
  52. ipkg_dests_all() {
  53. ipkg_dests '.*'
  54. }
  55. ipkg_state_dirs() {
  56. ipkg_dests_all | sed "s|\$|/$IPKG_DIR_PREFIX|"
  57. }
  58. ipkg_dest_default() {
  59. ipkg_dests_all | head -n 1
  60. }
  61. ipkg_dest_default_name() {
  62. ipkg_dest_names | head -n 1
  63. }
  64. ipkg_dest_byname() {
  65. local dest="$1"
  66. ipkg_dests $dest | head -n 1
  67. }
  68. ipkg_option() {
  69. local option="$1"
  70. sed -ne "s/^option[[:space:]]\+$option[[:space:]]\+//p" < $IPKG_CONF
  71. }
  72. ipkg_load_configuration() {
  73. if [ -z "$IPKG_CONF_DIR" ]; then
  74. IPKG_CONF_DIR=/etc
  75. fi
  76. IPKG_CONF="$IPKG_CONF_DIR/ipkg.conf"
  77. if [ -z "$IPKG_OFFLINE_ROOT" ]; then
  78. IPKG_OFFLINE_ROOT="`ipkg_option offline_root`"
  79. fi
  80. # Export IPKG_OFFLINE_ROOT for use by update-alternatives
  81. export IPKG_OFFLINE_ROOT
  82. if [ -n "$DEST_NAME" ]; then
  83. IPKG_ROOT="`ipkg_dest_byname $DEST_NAME`"
  84. if [ -z "$IPKG_ROOT" ]; then
  85. if [ -d "$IPKG_OFFLINE_ROOT$DEST_NAME" ]; then
  86. IPKG_ROOT="$IPKG_OFFLINE_ROOT$DEST_NAME";
  87. else
  88. echo "ipkg: invalid destination specification: $DEST_NAME
  89. Valid destinations are directories or one of the dest names from $IPKG_CONF:" >&2
  90. ipkg_dest_names >&2
  91. return 1
  92. fi
  93. fi
  94. else
  95. IPKG_ROOT="`ipkg_dest_default`"
  96. fi
  97. # Global ipkg state directories
  98. IPKG_DIR_PREFIX=usr/lib/ipkg
  99. IPKG_LISTS_DIR=$IPKG_OFFLINE_ROOT/$IPKG_DIR_PREFIX/lists
  100. IPKG_PENDING_DIR=$IPKG_OFFLINE_ROOT/$IPKG_DIR_PREFIX/pending
  101. if [ -z "$IPKG_TMP" ]; then
  102. IPKG_TMP=$IPKG_ROOT/tmp/ipkg
  103. fi
  104. [ -e "$IPKG_TMP" ] || mkdir -p $IPKG_TMP
  105. # Destination specific ipkg meta-data directory
  106. IPKG_STATE_DIR=$IPKG_ROOT/$IPKG_DIR_PREFIX
  107. # Proxy Support
  108. IPKG_PROXY_USERNAME="`ipkg_option proxy_username`"
  109. IPKG_PROXY_PASSWORD="`ipkg_option proxy_password`"
  110. IPKG_HTTP_PROXY="`ipkg_option http_proxy`"
  111. IPKG_FTP_PROXY="`ipkg_option ftp_proxy`"
  112. IPKG_NO_PROXY="`ipkg_option no_proxy`"
  113. if [ -n "$IPKG_HTTP_PROXY" ]; then
  114. export http_proxy="$IPKG_HTTP_PROXY"
  115. fi
  116. if [ -n "$IPKG_FTP_PROXY" ]; then
  117. export ftp_proxy="$IPKG_FTP_PROXY"
  118. fi
  119. if [ -n "$IPKG_NO_PROXY" ]; then
  120. export no_proxy="$IPKG_NO_PROXY"
  121. fi
  122. IPKG_STATUS_FIELDS='\(Package\|Status\|Essential\|Version\|Conffiles\|Root\)'
  123. }
  124. ipkg_usage() {
  125. [ $# -gt 0 ] && echo "ipkg: $*" ||:
  126. echo "
  127. usage: ipkg [options...] sub-command [arguments...]
  128. where sub-command is one of:
  129. Package Manipulation:
  130. update Update list of available packages
  131. upgrade Upgrade all installed packages to latest version
  132. install <pkg> Download and install <pkg> (and dependencies)
  133. install <file.ipk> Install package <file.ipk>
  134. install <file.deb> Install package <file.deb>
  135. remove <pkg> Remove package <pkg>
  136. Informational Commands:
  137. list List available packages and descriptions
  138. files <pkg> List all files belonging to <pkg>
  139. search <file> Search for a packaging providing <file>
  140. info [pkg [<field>]] Display all/some info fields for <pkg> or all
  141. status [pkg [<field>]] Display all/some status fields for <pkg> or all
  142. depends <pkg> Print uninstalled package dependencies for <pkg>
  143. Options:
  144. -d <dest_name> Use <dest_name> as the the root directory for
  145. -dest <dest_name> package installation, removal, upgrading.
  146. <dest_name> should be a defined dest name from the
  147. configuration file, (but can also be a directory
  148. name in a pinch).
  149. -o <offline_root> Use <offline_root> as the root for offline installation.
  150. -offline <offline_root>
  151. Wget Options:
  152. -q Quiet option for wget
  153. -c Continue option for wget
  154. Force Options (use when ipkg is too smart for its own good):
  155. -force-depends Make dependency checks warnings instead of errors
  156. -force-defaults Use default options for questions asked by ipkg.
  157. (no prompts). Note that this will not prevent
  158. package installation scripts from prompting.
  159. " >&2
  160. exit 1
  161. }
  162. ipkg_dir_part() {
  163. local dir="`echo $1 | sed -ne 's/\(.*\/\).*/\1/p'`"
  164. if [ -z "$dir" ]; then
  165. dir="./"
  166. fi
  167. echo $dir
  168. }
  169. ipkg_file_part() {
  170. echo $1 | sed 's/.*\///'
  171. }
  172. ipkg_protect_slashes() {
  173. sed -e 's/\//\\\//g'
  174. }
  175. ipkg_download() {
  176. local src="$1"
  177. local dest="$2"
  178. local src_file="`ipkg_file_part $src`"
  179. local dest_dir="`ipkg_dir_part $dest`"
  180. if [ -z "$dest_dir" ]; then
  181. dest_dir="$IPKG_TMP"
  182. fi
  183. local dest_file="`ipkg_file_part $dest`"
  184. if [ -z "$dest_file" ]; then
  185. dest_file="$src_file"
  186. fi
  187. # Proxy support
  188. local proxyuser=""
  189. local proxypassword=""
  190. local proxyoption=""
  191. if [ -n "$IPKG_PROXY_USERNAME" ]; then
  192. proxyuser="--proxy-user=\"$IPKG_PROXY_USERNAME\""
  193. proxypassword="--proxy-passwd=\"$IPKG_PROXY_PASSWORD\""
  194. fi
  195. if [ -n "$IPKG_PROXY_HTTP" -o -n "$IPKG_PROXY_FTP" ]; then
  196. proxyoption="--proxy=on"
  197. fi
  198. echo "Downloading $src ..."
  199. rm -f $IPKG_TMP/$src_file
  200. case "$src" in
  201. http://* | ftp://*)
  202. if ! wget $additional_options --passive-ftp $proxyoption $proxyuser $proxypassword -P $IPKG_TMP $src; then
  203. echo "ipkg_download: ERROR: Failed to retrieve $src, returning $err"
  204. return 1
  205. fi
  206. mv $IPKG_TMP/$src_file $dest_dir/$dest_file 2>/dev/null
  207. ;;
  208. file:/* )
  209. ln -s `echo $src | sed 's/^file://'` $dest_dir/$dest_file 2>/dev/null
  210. ;;
  211. *)
  212. echo "DEBUG: $src"
  213. ;;
  214. esac
  215. echo "Done."
  216. return 0
  217. }
  218. ipkg_update() {
  219. if [ ! -e "$IPKG_LISTS_DIR" ]; then
  220. mkdir -p $IPKG_LISTS_DIR
  221. fi
  222. local err=
  223. for src_name in `ipkg_src_names`; do
  224. local src="`ipkg_src_byname $src_name`"
  225. if ! ipkg_download $src/Packages $IPKG_LISTS_DIR/$src_name; then
  226. echo "ipkg_update: Error downloading $src/Packages to $IPKG_LISTS_DIR/$src_name" >&2
  227. err=t
  228. else
  229. echo "Updated list of available packages in $IPKG_LISTS_DIR/$src_name"
  230. fi
  231. done
  232. [ -n "$err" ] && return 1 ||:
  233. return 0
  234. }
  235. ipkg_list() {
  236. for src in `ipkg_src_names`; do
  237. if ipkg_require_list $src; then
  238. # black magic...
  239. sed -ne "
  240. /^Package:/{
  241. s/^Package:[[:space:]]*\<\([a-z0-9.+-]*$1[a-z0-9.+-]*\).*/\1/
  242. h
  243. }
  244. /^Description:/{
  245. s/^Description:[[:space:]]*\(.*\)/\1/
  246. H
  247. g
  248. s/\\
  249. / - /
  250. p
  251. }
  252. " $IPKG_LISTS_DIR/$src
  253. fi
  254. done
  255. }
  256. ipkg_extract_paragraph() {
  257. local pkg="$1"
  258. sed -ne "/Package:[[:space:]]*$pkg[[:space:]]*\$/,/^\$/p"
  259. }
  260. ipkg_extract_field() {
  261. local field="$1"
  262. # blacker magic...
  263. sed -ne "
  264. : TOP
  265. /^$field:/{
  266. p
  267. n
  268. b FIELD
  269. }
  270. d
  271. : FIELD
  272. /^$/b TOP
  273. /^[^[:space:]]/b TOP
  274. p
  275. n
  276. b FIELD
  277. "
  278. }
  279. ipkg_extract_value() {
  280. sed -e "s/^[^:]*:[[:space:]]*//"
  281. }
  282. ipkg_require_list() {
  283. [ $# -lt 1 ] && return 1 ||:
  284. local src="$1"
  285. if [ ! -f "$IPKG_LISTS_DIR/$src" ]; then
  286. echo "ERROR: File not found: $IPKG_LISTS_DIR/$src" >&2
  287. echo " You probably want to run \`ipkg update'" >&2
  288. return 1
  289. fi
  290. return 0
  291. }
  292. ipkg_info() {
  293. for src in `ipkg_src_names`; do
  294. if ipkg_require_list $src; then
  295. case $# in
  296. 0)
  297. cat $IPKG_LISTS_DIR/$src
  298. ;;
  299. 1)
  300. ipkg_extract_paragraph $1 < $IPKG_LISTS_DIR/$src
  301. ;;
  302. *)
  303. ipkg_extract_paragraph $1 < $IPKG_LISTS_DIR/$src | ipkg_extract_field $2
  304. ;;
  305. esac
  306. fi
  307. done
  308. }
  309. ipkg_status_sd() {
  310. [ $# -lt 1 ] && return 0 ||:
  311. sd="$1"
  312. shift
  313. if [ -f $sd/status ]; then
  314. case $# in
  315. 0)
  316. cat $sd/status
  317. ;;
  318. 1)
  319. ipkg_extract_paragraph $1 < $sd/status
  320. ;;
  321. *)
  322. ipkg_extract_paragraph $1 < $sd/status | ipkg_extract_field $2
  323. ;;
  324. esac
  325. fi
  326. return 0
  327. }
  328. ipkg_status_all() {
  329. for sd in `ipkg_state_dirs`; do
  330. ipkg_status_sd $sd $*
  331. done
  332. }
  333. ipkg_status() {
  334. if [ -n "$DEST_NAME" ]; then
  335. ipkg_status_sd $IPKG_STATE_DIR $*
  336. else
  337. ipkg_status_all $*
  338. fi
  339. }
  340. ipkg_status_matching_sd() {
  341. local sd="$1"
  342. local re="$2"
  343. if [ -f $sd/status ]; then
  344. sed -ne "
  345. : TOP
  346. /^Package:/{
  347. s/^Package:[[:space:]]*//
  348. s/[[:space:]]*$//
  349. h
  350. }
  351. /$re/{
  352. g
  353. p
  354. b NEXT
  355. }
  356. d
  357. : NEXT
  358. /^$/b TOP
  359. n
  360. b NEXT
  361. " < $sd/status
  362. fi
  363. return 0
  364. }
  365. ipkg_status_matching_all() {
  366. for sd in `ipkg_state_dirs`; do
  367. ipkg_status_matching_sd $sd $*
  368. done
  369. }
  370. ipkg_status_matching() {
  371. if [ -n "$DEST_NAME" ]; then
  372. ipkg_status_matching_sd $IPKG_STATE_DIR $*
  373. else
  374. ipkg_status_matching_all $*
  375. fi
  376. }
  377. ipkg_status_installed_sd() {
  378. local sd="$1"
  379. local pkg="$2"
  380. ipkg_status_sd $sd $pkg Status | grep -q "Status: install ok installed"
  381. }
  382. ipkg_status_installed_all() {
  383. local ret=1
  384. for sd in `ipkg_state_dirs`; do
  385. if `ipkg_status_installed_sd $sd $*`; then
  386. ret=0
  387. fi
  388. done
  389. return $ret
  390. }
  391. ipkg_status_mentioned_sd() {
  392. local sd="$1"
  393. local pkg="$2"
  394. [ -n "`ipkg_status_sd $sd $pkg Status`" ]
  395. }
  396. ipkg_files() {
  397. local pkg="$1"
  398. if [ -n "$DEST_NAME" ]; then
  399. dests=$IPKG_ROOT
  400. else
  401. dests="`ipkg_dests_all`"
  402. fi
  403. for dest in $dests; do
  404. if [ -f $dest/$IPKG_DIR_PREFIX/info/$pkg.list ]; then
  405. dest_sed="`echo $dest | ipkg_protect_slashes`"
  406. sed -e "s/^/$dest_sed/" < $dest/$IPKG_DIR_PREFIX/info/$pkg.list
  407. fi
  408. done
  409. }
  410. ipkg_search() {
  411. local pattern="$1"
  412. for dest_name in `ipkg_dest_names`; do
  413. dest="`ipkg_dest_byname $dest_name`"
  414. dest_sed="`echo $dest | ipkg_protect_slashes`"
  415. set +o noglob
  416. local list_files="`ls -1 $dest/$IPKG_DIR_PREFIX/info/*.list 2>/dev/null`"
  417. set -o noglob
  418. for file in $list_files; do
  419. if sed "s/^/$dest_sed/" $file | grep -q $pattern; then
  420. local pkg="`echo $file | sed "s/^.*\/\(.*\)\.list/\1/"`"
  421. [ "$dest_name" != `ipkg_dest_default_name` ] && pkg="$pkg ($dest_name)" ||:
  422. sed "s/^/$dest_sed/" $file | grep $pattern | sed "s/^/$pkg: /"
  423. fi
  424. done
  425. done
  426. }
  427. ipkg_status_remove_sd() {
  428. local sd="$1"
  429. local pkg="$2"
  430. if [ ! -f $sd/status ]; then
  431. mkdir -p $sd
  432. touch $sd/status
  433. fi
  434. sed -ne "/Package:[[:space:]]*$pkg[[:space:]]*\$/,/^\$/!p" < $sd/status > $sd/status.new
  435. mv $sd/status.new $sd/status
  436. }
  437. ipkg_status_remove_all() {
  438. for sd in `ipkg_state_dirs`; do
  439. ipkg_status_remove_sd $sd $*
  440. done
  441. }
  442. ipkg_status_remove() {
  443. if [ -n "$DEST_NAME" ]; then
  444. ipkg_status_remove_sd $IPKG_STATE_DIR $*
  445. else
  446. ipkg_status_remove_all $*
  447. fi
  448. }
  449. ipkg_status_update_sd() {
  450. local sd="$1"
  451. local pkg="$2"
  452. ipkg_status_remove_sd $sd $pkg
  453. ipkg_extract_field "$IPKG_STATUS_FIELDS" >> $sd/status
  454. echo "" >> $sd/status
  455. }
  456. ipkg_status_update() {
  457. ipkg_status_update_sd $IPKG_STATE_DIR $*
  458. }
  459. ipkg_unsatisfied_dependences() {
  460. local pkg=$1
  461. local deps="`ipkg_get_depends $pkg`"
  462. local remaining_deps=
  463. for dep in $deps; do
  464. local installed="`ipkg_get_installed $dep`"
  465. if [ "$installed" != "installed" ] ; then
  466. remaining_deps="$remaining_deps $dep"
  467. fi
  468. done
  469. ## echo "ipkg_unsatisfied_dependences pkg=$pkg $remaining_deps" > /dev/console
  470. echo $remaining_deps
  471. }
  472. ipkg_safe_pkg_name() {
  473. local pkg=$1
  474. local spkg="`echo pkg_$pkg | sed -e y/-+./___/`"
  475. echo $spkg
  476. }
  477. ipkg_set_depends() {
  478. local pkg=$1; shift
  479. local new_deps="$*"
  480. pkg="`ipkg_safe_pkg_name $pkg`"
  481. ## setvar ${pkg}_depends "$new_deps"
  482. echo $new_deps > $IPKG_TMP/${pkg}.depends
  483. }
  484. ipkg_get_depends() {
  485. local pkg=$1
  486. pkg="`ipkg_safe_pkg_name $pkg`"
  487. cat $IPKG_TMP/${pkg}.depends
  488. ## eval "echo \$${pkg}_depends"
  489. }
  490. ipkg_set_installed() {
  491. local pkg=$1
  492. pkg="`ipkg_safe_pkg_name $pkg`"
  493. echo installed > $IPKG_TMP/${pkg}.installed
  494. ## setvar ${pkg}_installed "installed"
  495. }
  496. ipkg_set_uninstalled() {
  497. local pkg=$1
  498. pkg="`ipkg_safe_pkg_name $pkg`"
  499. ### echo ipkg_set_uninstalled $pkg > /dev/console
  500. echo uninstalled > $IPKG_TMP/${pkg}.installed
  501. ## setvar ${pkg}_installed "uninstalled"
  502. }
  503. ipkg_get_installed() {
  504. local pkg=$1
  505. pkg="`ipkg_safe_pkg_name $pkg`"
  506. if [ -f $IPKG_TMP/${pkg}.installed ]; then
  507. cat $IPKG_TMP/${pkg}.installed
  508. fi
  509. ## eval "echo \$${pkg}_installed"
  510. }
  511. ipkg_depends() {
  512. local new_pkgs="$*"
  513. local all_deps=
  514. local installed_pkgs="`ipkg_status_matching_all 'Status:.*[[:space:]]installed'`"
  515. for pkg in $installed_pkgs; do
  516. ipkg_set_installed $pkg
  517. done
  518. while [ -n "$new_pkgs" ]; do
  519. all_deps="$all_deps $new_pkgs"
  520. local new_deps=
  521. for pkg in $new_pkgs; do
  522. if echo $pkg | grep -q '[^a-z0-9.+-]'; then
  523. echo "ipkg_depends: ERROR: Package name $pkg contains illegal characters (should be [a-z0-9.+-])" >&2
  524. return 1
  525. fi
  526. # TODO: Fix this. For now I am ignoring versions and alternations in dependencies.
  527. new_deps="$new_deps "`ipkg_info $pkg '\(Pre-\)\?Depends' | ipkg_extract_value | sed -e 's/([^)]*)//g
  528. s/\(|[[:space:]]*[a-z0-9.+-]\+[[:space:]]*\)\+//g
  529. s/,/ /g
  530. s/ \+/ /g'`
  531. ipkg_set_depends $pkg $new_deps
  532. done
  533. new_deps=`echo $new_deps | sed -e 's/[[:space:]]\+/\n/g' | sort | uniq`
  534. local maybe_new_pkgs=
  535. for pkg in $new_deps; do
  536. if ! echo $installed_pkgs | grep -q "\<$pkg\>"; then
  537. maybe_new_pkgs="$maybe_new_pkgs $pkg"
  538. fi
  539. done
  540. new_pkgs=
  541. for pkg in $maybe_new_pkgs; do
  542. if ! echo $all_deps | grep -q "\<$pkg\>"; then
  543. if [ -z "`ipkg_info $pkg`" ]; then
  544. echo "ipkg_depends: Warning: $pkg mentioned in dependency but no package found in $IPKG_LISTS_DIR" >&2
  545. ipkg_set_installed $pkg
  546. else
  547. new_pkgs="$new_pkgs $pkg"
  548. ipkg_set_uninstalled $pkg
  549. fi
  550. else
  551. ipkg_set_uninstalled $pkg
  552. fi
  553. done
  554. done
  555. echo $all_deps
  556. }
  557. ipkg_get_install_dest() {
  558. local dest="$1"
  559. shift
  560. local sd=$dest/$IPKG_DIR_PREFIX
  561. local info_dir=$sd/info
  562. local requested_pkgs="$*"
  563. local pkgs="`ipkg_depends $*`"
  564. mkdir -p $info_dir
  565. for pkg in $pkgs; do
  566. if ! ipkg_status_mentioned_sd $sd $pkg; then
  567. echo "Package: $pkg
  568. Status: install ok not-installed" | ipkg_status_update_sd $sd $pkg
  569. fi
  570. done
  571. ## mark the packages that we were directly requested to install as uninstalled
  572. for pkg in $requested_pkgs; do ipkg_set_uninstalled $pkg; done
  573. local new_pkgs=
  574. local pkgs_installed=0
  575. while [ -n "pkgs" ]; do
  576. curcheck=0
  577. ## echo "pkgs to install: {$pkgs}" > /dev/console
  578. for pkg in $pkgs; do
  579. curcheck="`expr $curcheck + 1`"
  580. local is_installed="`ipkg_get_installed $pkg`"
  581. if [ "$is_installed" = "installed" ]; then
  582. echo "$pkg is installed" > /dev/console
  583. continue
  584. fi
  585. local remaining_deps="`ipkg_unsatisfied_dependences $pkg`"
  586. if [ -n "$remaining_deps" ]; then
  587. new_pkgs="$new_pkgs $pkg"
  588. ### echo "Dependences not satisfied for $pkg: $remaining_deps"
  589. if [ $curcheck -ne `echo $pkgs|wc -w` ]; then
  590. continue
  591. fi
  592. fi
  593. local filename=
  594. for src in `ipkg_src_names`; do
  595. if ipkg_require_list $src; then
  596. filename="`ipkg_extract_paragraph $pkg < $IPKG_LISTS_DIR/$src | ipkg_extract_field Filename | ipkg_extract_value`"
  597. [ -n "$filename" ] && break ||:
  598. fi
  599. done
  600. if [ -z "$filename" ]; then
  601. echo "ipkg_get_install: ERROR: Cannot find package $pkg in $IPKG_LISTS_DIR"
  602. echo "ipkg_get_install: Check the spelling and maybe run \`ipkg update'."
  603. ipkg_status_remove_sd $sd $pkg
  604. return 1;
  605. fi
  606. echo ""
  607. local tmp_pkg_file="$IPKG_TMP/"`ipkg_file_part $filename`
  608. if ! ipkg_download `ipkg_src_byname $src`/$filename $tmp_pkg_file; then
  609. echo "ipkg_get_install: Perhaps you need to run \`ipkg update'?"
  610. return 1
  611. fi
  612. if ! ipkg_install_file_dest $dest $tmp_pkg_file; then
  613. echo "ipkg_get_install: ERROR: Failed to install $tmp_pkg_file"
  614. echo "ipkg_get_install: I'll leave it there for you to try a manual installation"
  615. return 1
  616. fi
  617. ipkg_set_installed $pkg
  618. pkgs_installed="`expr $pkgs_installed + 1`"
  619. rm $tmp_pkg_file
  620. done
  621. ### echo "Installed $pkgs_installed package(s) this round"
  622. if [ $pkgs_installed -eq 0 ]; then
  623. if [ -z "$new_pkgs" ]; then
  624. break
  625. fi
  626. fi
  627. pkgs_installed=0
  628. pkgs="$new_pkgs"
  629. new_pkgs=
  630. curcheck=0
  631. done
  632. }
  633. ipkg_get_install() {
  634. ipkg_get_install_dest $IPKG_ROOT $*
  635. }
  636. ipkg_install_file_dest() {
  637. local dest="$1"
  638. local filename="$2"
  639. local sd=$dest/$IPKG_DIR_PREFIX
  640. local info_dir=$sd/info
  641. if [ ! -f "$filename" ]; then
  642. echo "ipkg_install_file: ERROR: File $filename not found"
  643. return 1
  644. fi
  645. local pkg="`ipkg_file_part $filename | sed 's/\([a-z0-9.+-]\+\)_.*/\1/'`"
  646. local ext="`echo $filename | sed 's/.*\.//'`"
  647. local pkg_extract_stdout
  648. if [ "$ext" = "ipk" ]; then
  649. pkg_extract_stdout="tar -xzOf"
  650. elif [ "$ext" = "deb" ]; then
  651. pkg_extract_stdout="ar p"
  652. else
  653. echo "ipkg_install_file: ERROR: File $filename has unknown extension $ext (not .ipk or .deb)"
  654. return 1
  655. fi
  656. # Check dependencies
  657. local depends="`ipkg_depends $pkg | sed -e "s/\<$pkg\>//"`"
  658. # Don't worry about deps that are scheduled for installation
  659. local missing_deps=
  660. for dep in $depends; do
  661. if ! ipkg_status_all $dep | grep -q 'Status:[[:space:]]install'; then
  662. missing_deps="$missing_deps $dep"
  663. fi
  664. done
  665. if [ ! -z "$missing_deps" ]; then
  666. if [ -n "$FORCE_DEPENDS" ]; then
  667. echo "ipkg_install_file: Warning: $pkg depends on the following uninstalled programs: $missing_deps"
  668. else
  669. echo "ipkg_install_file: ERROR: $pkg depends on the following uninstalled programs:
  670. $missing_deps"
  671. echo "ipkg_install_file: You may want to use \`ipkg install' to install these."
  672. return 1
  673. fi
  674. fi
  675. mkdir -p $IPKG_TMP/$pkg/control
  676. mkdir -p $IPKG_TMP/$pkg/data
  677. mkdir -p $info_dir
  678. if ! $pkg_extract_stdout $filename ./control.tar.gz | (cd $IPKG_TMP/$pkg/control; tar -xzf - ) ; then
  679. echo "ipkg_install_file: ERROR unpacking control.tar.gz from $filename"
  680. return 1
  681. fi
  682. if [ -n "$IPKG_OFFLINE_ROOT" ]; then
  683. if grep -q '^InstallsOffline:[[:space:]]*no' $IPKG_TMP/$pkg/control/control; then
  684. echo "*** Warning: Package $pkg may not be installed in offline mode"
  685. echo "*** Warning: Scheduling $filename for pending installation (installing into $IPKG_PENDING_DIR)"
  686. echo "Package: $pkg
  687. Status: install ok pending" | ipkg_status_update_sd $sd $pkg
  688. mkdir -p $IPKG_PENDING_DIR
  689. cp -f $filename $IPKG_PENDING_DIR
  690. rm -r $IPKG_TMP/$pkg/control
  691. rm -r $IPKG_TMP/$pkg/data
  692. rmdir $IPKG_TMP/$pkg
  693. return 0
  694. fi
  695. fi
  696. echo -n "Unpacking $pkg..."
  697. set +o noglob
  698. for file in $IPKG_TMP/$pkg/control/*; do
  699. local base_file="`ipkg_file_part $file`"
  700. mv $file $info_dir/$pkg.$base_file
  701. done
  702. set -o noglob
  703. rm -r $IPKG_TMP/$pkg/control
  704. if ! $pkg_extract_stdout $filename ./data.tar.gz | (cd $IPKG_TMP/$pkg/data; tar -xzf - ) ; then
  705. echo "ipkg_install_file: ERROR unpacking data.tar.gz from $filename"
  706. return 1
  707. fi
  708. echo "Done."
  709. echo -n "Configuring $pkg..."
  710. export PKG_ROOT=$dest
  711. if [ -x "$info_dir/$pkg.preinst" ]; then
  712. if ! $info_dir/$pkg.preinst install; then
  713. echo "$info_dir/$pkg.preinst failed. Aborting installation of $pkg"
  714. rm -rf $IPKG_TMP/$pkg/data
  715. rmdir $IPKG_TMP/$pkg
  716. return 1
  717. fi
  718. fi
  719. local old_conffiles="`ipkg_status_sd $sd $pkg Conffiles | ipkg_extract_value`"
  720. local new_conffiles=
  721. if [ -f "$info_dir/$pkg.conffiles" ]; then
  722. for conffile in `cat $info_dir/$pkg.conffiles`; do
  723. if [ -f "$dest/$conffile" ] && ! echo " $old_conffiles " | grep -q " $conffile "`md5sum $dest/$conffile | sed 's/ .*//'`; then
  724. local use_maintainers_conffile=
  725. if [ -z "$FORCE_DEFAULTS" ]; then
  726. while true; do
  727. echo -n "Configuration file \`$conffile'
  728. ==> File on system created by you or by a script.
  729. ==> File also in package provided by package maintainer.
  730. What would you like to do about it ? Your options are:
  731. Y or I : install the package maintainer's version
  732. N or O : keep your currently-installed version
  733. D : show the differences between the versions (if diff is installed)
  734. The default action is to keep your current version.
  735. *** `ipkg_file_part $conffile` (Y/I/N/O/D) [default=N] ? "
  736. read response
  737. case "$response" in
  738. [YyIi] | [Yy][Ee][Ss])
  739. use_maintainers_conffile=t
  740. break
  741. ;;
  742. [Dd])
  743. echo "
  744. diff -u $dest/$conffile $IPKG_TMP/$pkg/data/$conffile"
  745. diff -u $dest/$conffile $IPKG_TMP/$pkg/data/$conffile || true
  746. echo "[Press ENTER to continue]"
  747. read junk
  748. ;;
  749. *)
  750. break
  751. ;;
  752. esac
  753. done
  754. fi
  755. if [ -n "$use_maintainers_conffile" ]; then
  756. local md5sum="`md5sum $IPKG_TMP/$pkg/data/$conffile | sed 's/ .*//'`"
  757. new_conffiles="$new_conffiles $conffile $md5sum"
  758. else
  759. new_conffiles="$new_conffiles $conffile <custom>"
  760. rm $IPKG_TMP/$pkg/data/$conffile
  761. fi
  762. else
  763. md5sum="`md5sum $IPKG_TMP/$pkg/data/$conffile | sed 's/ .*//'`"
  764. new_conffiles="$new_conffiles $conffile $md5sum"
  765. fi
  766. done
  767. fi
  768. local owd="`pwd`"
  769. (cd $IPKG_TMP/$pkg/data/; tar cf - . | (cd $owd; cd $dest; tar xf -))
  770. rm -rf $IPKG_TMP/$pkg/data
  771. rmdir $IPKG_TMP/$pkg
  772. rm -f $info_dir/$pkg.list
  773. $pkg_extract_stdout $filename ./data.tar.gz | tar tzf - | sed -e 's/^\.//' > $info_dir/$pkg.list
  774. if [ -x "$info_dir/$pkg.postinst" ]; then
  775. IPKG_INSTROOT="$IPKG_INSTROOT" $info_dir/$pkg.postinst configure
  776. fi
  777. if [ -n "$new_conffiles" ]; then
  778. new_conffiles='Conffiles: '`echo $new_conffiles | ipkg_protect_slashes`
  779. fi
  780. local sed_safe_offline_root="`echo ${IPKG_OFFLINE_ROOT} | ipkg_protect_slashes`"
  781. local sed_safe_root="`echo $dest | sed -e "s/^${sed_safe_offline_root}//" | ipkg_protect_slashes`"
  782. sed -e "s/\(Package:.*\)/\1\\
  783. Status: install ok installed\\
  784. Root: ${sed_safe_root}\\
  785. ${new_conffiles}/" $info_dir/$pkg.control | ipkg_status_update_sd $sd $pkg
  786. rm -f $info_dir/$pkg.control
  787. rm -f $info_dir/$pkg.conffiles
  788. rm -f $info_dir/$pkg.preinst
  789. rm -f $info_dir/$pkg.postinst
  790. echo "Done."
  791. }
  792. ipkg_install_file() {
  793. ipkg_install_file_dest $IPKG_ROOT $*
  794. }
  795. ipkg_install() {
  796. while [ $# -gt 0 ]; do
  797. local pkg="$1"
  798. shift
  799. case "$pkg" in
  800. http://* | ftp://*)
  801. local tmp_pkg_file="$IPKG_TMP/"`ipkg_file_part $pkg`
  802. if ipkg_download $pkg $tmp_pkg_file; then
  803. ipkg_install_file $tmp_pkg_file
  804. rm $tmp_pkg_file
  805. fi
  806. ;;
  807. file:/*.ipk | file://*.deb)
  808. local ipkg_filename="`echo $pkg|sed 's/^file://'`"
  809. ipkg_install_file $ipkg_filename
  810. ;;
  811. *.ipk | *.deb)
  812. if [ -f "$pkg" ]; then
  813. ipkg_install_file $pkg
  814. else
  815. echo "File not found $pkg" >&2
  816. fi
  817. ;;
  818. *)
  819. ipkg_get_install $pkg || true
  820. ;;
  821. esac
  822. done
  823. }
  824. ipkg_install_pending() {
  825. [ -n "$IPKG_OFFLINE_ROOT" ] && return 0 ||:
  826. if [ -d "$IPKG_PENDING_DIR" ]; then
  827. set +o noglob
  828. local pending="`ls -1d $IPKG_PENDING_DIR/*.ipk 2> /dev/null`" || true
  829. set -o noglob
  830. if [ -n "$pending" ]; then
  831. echo "The following packages in $IPKG_PENDING_DIR will now be installed:"
  832. echo $pending
  833. for filename in $pending; do
  834. if ipkg_install_file $filename; then
  835. rm $filename
  836. fi
  837. done
  838. fi
  839. fi
  840. return 0
  841. }
  842. ipkg_install_wanted() {
  843. local wanted="`ipkg_status_matching 'Status:[[:space:]]*install.*not-installed'`"
  844. if [ -n "$wanted" ]; then
  845. echo "The following package were previously requested but have not been installed:"
  846. echo $wanted
  847. if [ -n "$FORCE_DEFAULTS" ]; then
  848. echo "Installing them now."
  849. else
  850. echo -n "Install them now [Y/n] ? "
  851. read response
  852. case "$response" in
  853. [Nn] | [Nn][Oo])
  854. return 0
  855. ;;
  856. esac
  857. fi
  858. ipkg_install $wanted
  859. fi
  860. return 0
  861. }
  862. ipkg_upgrade_pkg() {
  863. local pkg="$1"
  864. local avail_ver="`ipkg_info $pkg Version | ipkg_extract_value | head -n 1`"
  865. is_installed=
  866. for dest_name in `ipkg_dest_names`; do
  867. local dest="`ipkg_dest_byname $dest_name`"
  868. local sd=$dest/$IPKG_DIR_PREFIX
  869. local inst_ver="`ipkg_status_sd $sd $pkg Version | ipkg_extract_value`"
  870. if [ -n "$inst_ver" ]; then
  871. is_installed=t
  872. if [ -z "$avail_ver" ]; then
  873. echo "Assuming locally installed package $pkg ($inst_ver) is up to date"
  874. return 0
  875. fi
  876. if [ "$avail_ver" = "$inst_ver" ]; then
  877. echo "Package $pkg ($inst_ver) installed in $dest_name is up to date"
  878. elif ipkg_is_upgrade "$avail_ver" "$inst_ver"; then
  879. echo "Upgrading $pkg ($dest_name) from $inst_ver to $avail_ver"
  880. ipkg_get_install_dest $dest $pkg
  881. else
  882. echo "Not downgrading package $pkg from $inst_ver to $avail_ver"
  883. fi
  884. fi
  885. done
  886. if [ -z "$is_installed" ]; then
  887. echo "Package $pkg does not appear to be installed"
  888. return 0
  889. fi
  890. }
  891. ipkg_upgrade() {
  892. if [ $# -lt 1 ]; then
  893. local pkgs="`ipkg_status_matching 'Status:.*[[:space:]]installed'`"
  894. else
  895. pkgs="$*"
  896. fi
  897. for pkg in $pkgs; do
  898. ipkg_upgrade_pkg $pkg
  899. done
  900. }
  901. ipkg_remove_pkg_dest() {
  902. local dest="$1"
  903. local pkg="$2"
  904. local sd=$dest/$IPKG_DIR_PREFIX
  905. local info_dir=$sd/info
  906. if ! ipkg_status_installed_sd $sd $pkg; then
  907. echo "ipkg_remove: Package $pkg does not appear to be installed in $dest"
  908. if ipkg_status_mentioned_sd $sd $pkg; then
  909. echo "Purging mention of $pkg from the ipkg database"
  910. ipkg_status_remove_sd $sd $pkg
  911. fi
  912. return 1
  913. fi
  914. echo "ipkg_remove: Removing $pkg... "
  915. local files="`cat $info_dir/$pkg.list`"
  916. export PKG_ROOT=$dest
  917. if [ -x "$info_dir/$pkg.prerm" ]; then
  918. $info_dir/$pkg.prerm remove
  919. fi
  920. local conffiles="`ipkg_status_sd $sd $pkg Conffiles | ipkg_extract_value`"
  921. local dirs_to_remove=
  922. for file in $files; do
  923. if [ -d "$dest/$file" ]; then
  924. dirs_to_remove="$dirs_to_remove $dest/$file"
  925. else
  926. if echo " $conffiles " | grep -q " $file "; then
  927. if echo " $conffiles " | grep -q " $file "`md5sum $dest/$file | sed 's/ .*//'`; then
  928. rm -f $dest/$file
  929. fi
  930. else
  931. rm -f $dest/$file
  932. fi
  933. fi
  934. done
  935. local removed_a_dir=t
  936. while [ -n "$removed_a_dir" ]; do
  937. removed_a_dir=
  938. local new_dirs_to_remove=
  939. for dir in $dirs_to_remove; do
  940. if rmdir $dir >/dev/null 2>&1; then
  941. removed_a_dir=t
  942. else
  943. new_dirs_to_remove="$new_dirs_to_remove $dir"
  944. fi
  945. done
  946. dirs_to_remove="$new_dirs_to_remove"
  947. done
  948. if [ -n "$dirs_to_remove" ]; then
  949. echo "ipkg_remove: Warning: Not removing the following directories since they are not empty:" >&2
  950. echo "$dirs_to_remove" | sed -e 's/\/[/]\+/\//g' >&2
  951. fi
  952. if [ -x "$info_dir/$pkg.postrm" ]; then
  953. $info_dir/$pkg.postrm remove
  954. fi
  955. ipkg_status_remove_sd $sd $pkg
  956. set +o noglob
  957. rm -f $info_dir/$pkg.*
  958. set -o noglob
  959. echo "Done."
  960. }
  961. ipkg_remove_pkg() {
  962. local pkg="$1"
  963. for dest in `ipkg_dests_all`; do
  964. local sd=$dest/$IPKG_DIR_PREFIX
  965. if ipkg_status_mentioned_sd $sd $pkg; then
  966. ipkg_remove_pkg_dest $dest $pkg
  967. fi
  968. done
  969. }
  970. ipkg_remove() {
  971. while [ $# -gt 0 ]; do
  972. local pkg="$1"
  973. shift
  974. if [ -n "$DEST_NAME" ]; then
  975. ipkg_remove_pkg_dest $IPKG_ROOT $pkg
  976. else
  977. ipkg_remove_pkg $pkg
  978. fi
  979. done
  980. }
  981. ###########
  982. # ipkg main
  983. ###########
  984. # Parse options
  985. while [ $# -gt 0 ]; do
  986. arg="$1"
  987. case $arg in
  988. -d | -dest)
  989. [ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"
  990. DEST_NAME="$2"
  991. shift
  992. ;;
  993. -o | -offline)
  994. [ $# -gt 1 ] || ipkg_usage "option $arg requires an argument"
  995. IPKG_OFFLINE_ROOT="$2"
  996. shift
  997. ;;
  998. -force-depends)
  999. FORCE_DEPENDS=t
  1000. ;;
  1001. -force-defaults)
  1002. FORCE_DEFAULTS=t
  1003. ;;
  1004. -c)
  1005. additional_options="$additional_options -c "
  1006. ;;
  1007. -q)
  1008. additional_options="$additional_options -q "
  1009. ;;
  1010. -*)
  1011. ipkg_usage "unknown option $arg"
  1012. ;;
  1013. *)
  1014. break
  1015. ;;
  1016. esac
  1017. shift
  1018. done
  1019. [ $# -ge 1 ] || ipkg_usage "ipkg must have one sub-command argument"
  1020. cmd="$1"
  1021. shift
  1022. ipkg_load_configuration
  1023. mkdir -p /tmp/ipkg
  1024. case "$cmd" in
  1025. update|upgrade|list|info|status|install_pending)
  1026. ;;
  1027. install|depends|remove|files|search)
  1028. [ $# -ge 1 ] || ipkg_usage "ERROR: the \`\`$cmd'' command requires an argument"
  1029. ;;
  1030. *)
  1031. echo "ERROR: unknown sub-command \`$cmd'"
  1032. ipkg_usage
  1033. ;;
  1034. esac
  1035. # Only install pending if we have an interactive sub-command
  1036. case "$cmd" in
  1037. upgrade|install)
  1038. ipkg_install_pending
  1039. ipkg_install_wanted
  1040. ;;
  1041. esac
  1042. ipkg_$cmd $*
  1043. for a in `ls $IPKG_TMP`; do
  1044. rm -rf $IPKG_TMP/$a
  1045. done