ipkg 28 KB

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