You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1884 lines
47 KiB

  1. ############################################################### smallutils
  2. smallyes() {
  3. YES="${1-y}"
  4. while echo "$YES" 2>/dev/null ; do : ; done
  5. }
  6. in_path () {
  7. local OLD_IFS="$IFS"
  8. IFS=":"
  9. for dir in $PATH; do
  10. if [ -x "$dir/$1" ]; then
  11. IFS="$OLD_IFS"
  12. return 0
  13. fi
  14. done
  15. IFS="$OLD_IFS"
  16. return 1
  17. }
  18. ############################################################### interaction
  19. error () {
  20. # <error code> <name> <string> <args>
  21. local err name fmt
  22. err="$1"
  23. name="$2"
  24. fmt="$3"
  25. shift; shift; shift
  26. if [ "$USE_DEBIANINSTALLER_INTERACTION" ]; then
  27. (echo "E: $name"
  28. for x in "$@"; do echo "EA: $x"; done
  29. echo "EF: $fmt") >&4
  30. else
  31. (printf "E: $fmt\n" "$@") >&4
  32. fi
  33. exit "$err"
  34. }
  35. warning () {
  36. # <name> <string> <args>
  37. local name fmt
  38. name="$1"
  39. fmt="$2"
  40. shift; shift
  41. if [ "$USE_DEBIANINSTALLER_INTERACTION" ]; then
  42. (echo "W: $name"
  43. for x in "$@"; do echo "WA: $x"; done
  44. echo "WF: $fmt") >&4
  45. else
  46. printf "W: $fmt\n" "$@" >&4
  47. fi
  48. }
  49. info () {
  50. # <name> <string> <args>
  51. local name fmt
  52. name="$1"
  53. fmt="$2"
  54. shift; shift
  55. if [ "$USE_DEBIANINSTALLER_INTERACTION" ]; then
  56. (echo "I: $name"
  57. for x in "$@"; do echo "IA: $x"; done
  58. echo "IF: $fmt") >&4
  59. else
  60. printf "I: $fmt\n" "$@" >&4
  61. fi
  62. }
  63. PROGRESS_NOW=0
  64. PROGRESS_END=0
  65. PROGRESS_NEXT=""
  66. PROGRESS_WHAT=""
  67. progress_next () {
  68. PROGRESS_NEXT="$1"
  69. }
  70. wgetprogress () {
  71. [ ! "$VERBOSE" ] && NVSWITCH="-nv"
  72. local ret=0
  73. if [ "$USE_DEBIANINSTALLER_INTERACTION" ] && [ "$PROGRESS_NEXT" ]; then
  74. # The exit status of a pipeline is that of the last command in
  75. # the pipeline, so wget's exit status must be saved in the
  76. # pipeline's first command. Since commands in a pipeline run in
  77. # subshells, we have to print the exit status (on a file
  78. # descriptor other than standard output, which is used by the
  79. # pipeline itself) and then assign it to $ret outside of the
  80. # pipeline. The "||" is necessary due to "set -e"; otherwise, a
  81. # non-zero exit status would cause the echo command to be
  82. # skipped. If wget succeeds, $ret will be "", so it then has to
  83. # be set to a default value of 0.
  84. ret=$({ { wget $@ 2>&1 >/dev/null || echo $? >&2; } | "$PKGDETAILS" "WGET%" "$PROGRESS_NOW" "$PROGRESS_NEXT" "$PROGRESS_END" >&3; } 2>&1)
  85. : ${ret:=0}
  86. else
  87. wget ${NVSWITCH:+"$NVSWITCH"} "$@"
  88. ret=$?
  89. fi
  90. return $ret
  91. }
  92. progress () {
  93. # <now> <end> <name> <string> <args>
  94. local now end name fmt
  95. now="$1"
  96. end="$2"
  97. name="$3"
  98. fmt="$4"
  99. shift; shift; shift; shift
  100. if [ "$USE_DEBIANINSTALLER_INTERACTION" ]; then
  101. PROGRESS_NOW="$now"
  102. PROGRESS_END="$end"
  103. PROGRESS_NEXT=""
  104. (echo "P: $now $end $name"
  105. for x in "$@"; do echo "PA: $x"; done
  106. echo "PF: $fmt") >&3
  107. fi
  108. }
  109. dpkg_progress () {
  110. # <now> <end> <name> <desc> UNPACKING|CONFIGURING
  111. local now end name desc action expect
  112. now="$1"
  113. end="$2"
  114. name="$3"
  115. desc="$4"
  116. action="$5"
  117. expect=""
  118. if [ "$action" = UNPACKING ]; then
  119. expect=half-installed
  120. elif [ "$action" = CONFIGURING ]; then
  121. expect=half-configured
  122. fi
  123. dp () {
  124. now=$(($now + ${1:-1}))
  125. }
  126. exitcode=0
  127. while read status pkg qstate; do
  128. if [ "$status" = "EXITCODE" ]; then
  129. exitcode="$pkg"
  130. continue
  131. fi
  132. [ "$qstate" = "$expect" ] || continue
  133. case $qstate in
  134. half-installed)
  135. dp; progress "$now" "$end" "$name" "$desc"
  136. info "$action" "Unpacking %s..." "${pkg%:}"
  137. expect="unpacked"
  138. ;;
  139. unpacked)
  140. expect="half-installed"
  141. ;;
  142. half-configured)
  143. dp; progress "$now" "$end" "$name" "$desc"
  144. info "$action" "Configuring %s..." "${pkg%:}"
  145. expect="installed"
  146. ;;
  147. installed)
  148. expect="half-configured"
  149. ;;
  150. esac
  151. done
  152. return "$exitcode"
  153. }
  154. ############################################################# set variables
  155. default_mirror () {
  156. DEF_MIRROR="$1"
  157. }
  158. FINDDEBS_NEEDS_INDICES="false"
  159. finddebs_style () {
  160. case "$1" in
  161. hardcoded)
  162. ;;
  163. from-indices)
  164. FINDDEBS_NEEDS_INDICES="true"
  165. ;;
  166. *)
  167. error 1 BADFINDDEBS "unknown finddebs style"
  168. ;;
  169. esac
  170. }
  171. mk_download_dirs () {
  172. if [ "$DLDEST" = "apt_dest" ]; then
  173. mkdir -p "$TARGET/$APTSTATE/lists/partial"
  174. mkdir -p "$TARGET/var/cache/apt/archives/partial"
  175. fi
  176. }
  177. download_style () {
  178. case "$1" in
  179. apt)
  180. if [ "$2" = "var-state" ]; then
  181. APTSTATE="var/state/apt"
  182. else
  183. APTSTATE="var/lib/apt"
  184. fi
  185. DLDEST="apt_dest"
  186. export APTSTATE DLDEST DEBFOR
  187. ;;
  188. *)
  189. error 1 BADDLOAD "unknown download style"
  190. ;;
  191. esac
  192. }
  193. keyring () {
  194. # avoid unnecessary warning with --second-stage
  195. if [ -z "$KEYRING" ] && [ "$SECOND_STAGE_ONLY" != true ]; then
  196. if [ -e "$1" ]; then
  197. KEYRING="$1"
  198. elif [ -z "$DISABLE_KEYRING" ]; then
  199. if [ -n "$DEF_HTTPS_MIRROR" ] && [ -z "$USER_MIRROR" ] && [ -z "$FORCE_KEYRING" ]; then
  200. info KEYRING "Keyring file not available at %s; switching to https mirror %s" "$1" "$DEF_HTTPS_MIRROR"
  201. USER_MIRROR="$DEF_HTTPS_MIRROR"
  202. else
  203. warning KEYRING "Cannot check Release signature; keyring file not available %s" "$1"
  204. if [ -n "$FORCE_KEYRING" ]; then
  205. error 1 KEYRING "Keyring-based check was requested; aborting accordingly"
  206. fi
  207. fi
  208. fi
  209. fi
  210. }
  211. detect_container () {
  212. if [ "$container" = lxc ]; then
  213. CONTAINER="lxc"
  214. elif grep -qs container=lxc-libvirt /proc/1/environ; then
  215. CONTAINER="lxc-libvirt"
  216. elif grep -qs ^systemd-nspawn$ /run/systemd/container || grep -qs systemd-nspawn /proc/1/environ || [ "$container" = "systemd-nspawn" ]; then
  217. CONTAINER="systemd-nspawn"
  218. elif grep -qs '[[:space:]]/docker/.*/sys/fs/cgroup' /proc/1/mountinfo; then
  219. CONTAINER="docker"
  220. else
  221. CONTAINER=""
  222. fi
  223. }
  224. ########################################################## variant handling
  225. doing_variant () {
  226. if [ "$1" = "$VARIANT" ]; then return 0; fi
  227. if [ "$1" = "-" ] && [ "$VARIANT" = "" ]; then return 0; fi
  228. return 1
  229. }
  230. SUPPORTED_VARIANTS="-"
  231. variants () {
  232. SUPPORTED_VARIANTS="$*"
  233. for v in $*; do
  234. if doing_variant "$v"; then return 0; fi
  235. done
  236. error 1 UNSUPPVARIANT "unsupported variant"
  237. }
  238. ########################################################### option handling
  239. check_conflicting_option () {
  240. if ( [ "$set_what_to_do" = --foreign ] && [ "${1%%=*}" = --unpack-tarball ] ) || \
  241. ( [ "${set_what_to_do%%=*}" = "--unpack-tarball" ] && [ "$1" = --foreign ] ); then
  242. LOOSEN_CONFLICTING_RESTRICTION="true"
  243. elif [ -n "$set_what_to_do" ]; then
  244. error 1 ARG_CONFLICTING "$set_what_to_do is specified with $1, please use only one of those options."
  245. fi
  246. set_what_to_do="$1"
  247. }
  248. ################################################# work out names for things
  249. mirror_style () {
  250. case "$1" in
  251. release)
  252. DOWNLOAD_INDICES="download_release_indices"
  253. DOWNLOAD_DEBS="download_release"
  254. ;;
  255. main)
  256. DOWNLOAD_INDICES="download_main_indices"
  257. DOWNLOAD_DEBS="download_main"
  258. ;;
  259. *)
  260. error 1 BADMIRROR "unknown mirror style"
  261. ;;
  262. esac
  263. export DOWNLOAD_INDICES
  264. export DOWNLOAD_DEBS
  265. }
  266. force_md5 () {
  267. DEBOOTSTRAP_CHECKSUM_FIELD=MD5SUM
  268. export DEBOOTSTRAP_CHECKSUM_FIELD
  269. }
  270. verify_checksum () {
  271. # args: dest checksum size
  272. local expchecksum="$2"
  273. local expsize="$3"
  274. if [ "$DEBOOTSTRAP_CHECKSUM_FIELD" = "MD5SUM" ]; then
  275. if in_path md5sum; then
  276. relchecksum=$(md5sum < "$1" | sed 's/ .*$//')
  277. elif in_path md5; then
  278. relchecksum=$(md5 < "$1")
  279. else
  280. error 1 SIGCHECK "Cannot check md5sum"
  281. fi
  282. else
  283. if in_path "sha${SHA_SIZE}sum"; then
  284. relchecksum="$(sha${SHA_SIZE}sum < "$1" | sed 's/ .*$//')"
  285. elif in_path "sha${SHA_SIZE}"; then
  286. relchecksum="$(sha${SHA_SIZE} < "$1")"
  287. else
  288. error 1 SIGCHECK "Cannot check sha${SHA_SIZE}sum"
  289. fi
  290. fi
  291. relsize="$(wc -c < "$1")"
  292. if [ "$expsize" -ne "$relsize" ] || [ "$expchecksum" != "$relchecksum" ]; then
  293. return 1
  294. fi
  295. return 0
  296. }
  297. get () {
  298. # args: from dest 'nocache'
  299. # args: from dest [checksum size] [alt {checksum size type}]
  300. # args: from dest 'byhash' [checksum size] [alt {checksum size type}]
  301. local displayname
  302. local versionname
  303. local from_base
  304. local dest_base
  305. local nocache=""
  306. local byhash=""
  307. from_base="$1"; shift
  308. dest_base="$1"; shift
  309. if [ "$1" = "nocache" ]; then
  310. nocache="true"; shift
  311. elif [ "$1" = "byhash" ]; then
  312. byhash="true"; shift
  313. fi
  314. if [ "${dest_base%.deb}" != "$dest_base" ]; then
  315. displayname="$(echo "$dest_base" | sed 's,^.*/,,;s,_.*$,,')"
  316. versionname="$(echo "$dest_base" | sed 's,^.*/,,' | cut -d_ -f2 | sed 's/%3a/:/')"
  317. else
  318. displayname="$(echo "$from_base" | sed 's,^.*/,,')"
  319. fi
  320. if [ -e "$dest_base" ]; then
  321. if [ -z "$1" ]; then
  322. return 0
  323. elif [ -n "$nocache" ]; then
  324. rm -f "$dest_base"
  325. else
  326. info VALIDATING "Validating %s %s" "$displayname" "$versionname"
  327. if verify_checksum "$dest_base" "$1" "$2"; then
  328. return 0
  329. else
  330. rm -f "$dest_base"
  331. fi
  332. fi
  333. fi
  334. if [ "$#" -gt 3 ]; then
  335. local st=1
  336. if [ "$3" = "-" ]; then st=4; fi
  337. local order="$(a=$st; while [ "$a" -le $# ]; do eval echo \"\${$(($a+1))}\" $a;
  338. a=$(($a + 3)); done | sort -n | sed 's/.* //')"
  339. else
  340. local order=1
  341. fi
  342. for a in $order; do
  343. local checksum siz typ from dest iters
  344. checksum="$(eval echo \${$a})"
  345. siz="$(eval echo \${$(( $a+1 ))})"
  346. typ="$(eval echo \${$(( $a+2 ))})"
  347. iters="0"
  348. case "$typ" in
  349. xz) from="$from_base.xz"; dest="$dest_base.xz" ;;
  350. bz2) from="$from_base.bz2"; dest="$dest_base.bz2" ;;
  351. gz) from="$from_base.gz"; dest="$dest_base.gz" ;;
  352. *) from="$from_base"; dest="$dest_base" ;;
  353. esac
  354. if [ ! -z "$CACHE_DIR" ]; then
  355. dest="${dest%%*/}"
  356. elif [ "${dest#/}" = "$dest" ]; then
  357. dest="./$dest"
  358. fi
  359. local dest2="$dest"
  360. if [ -d "${dest2%/*}/partial" ]; then
  361. dest2="${dest2%/*}/partial/${dest2##*/}"
  362. fi
  363. while [ "$iters" -lt 10 ]; do
  364. local from2=""
  365. info RETRIEVING "Retrieving %s %s" "$displayname" "$versionname"
  366. if [ "$checksum" != "" ] && [ "$byhash" != "" ]; then
  367. # assume we don't mix acquire-by-hash and md5
  368. from2="$(dirname "$from")/by-hash/SHA${SHA_SIZE}/$checksum"
  369. fi
  370. if [ ! -e "$dest2" ]; then
  371. if [ -z "$from2" ] || ! just_get "$from2" "$dest2"; then
  372. if ! just_get "$from" "$dest2"; then continue 2; fi
  373. fi
  374. fi
  375. if [ "$checksum" != "" ]; then
  376. info VALIDATING "Validating %s %s" "$displayname" "$versionname"
  377. if verify_checksum "$dest2" "$checksum" "$siz"; then
  378. checksum=""
  379. fi
  380. fi
  381. if [ -z "$checksum" ]; then
  382. [ "$dest2" = "$dest" ] || mv "$dest2" "$dest"
  383. case "$typ" in
  384. gz) gunzip "$dest" ;;
  385. bz2) bunzip2 "$dest" ;;
  386. xz) unxz "$dest" ;;
  387. esac
  388. return 0
  389. else
  390. rm -f "$dest2"
  391. warning RETRYING "Retrying failed download of %s" "$from"
  392. iters=$(($iters + 1))
  393. fi
  394. done
  395. warning CORRUPTFILE "%s was corrupt" "$from"
  396. done
  397. return 1
  398. }
  399. just_get () {
  400. # args: from dest
  401. local from="$1"
  402. local dest="$2"
  403. mkdir -p "${dest%/*}"
  404. if [ "${from#null:}" != "$from" ]; then
  405. error 1 NOTPREDL "%s was not pre-downloaded" "${from#null:}"
  406. elif [ "${from#http://}" != "$from" ] || [ "${from#https://}" != "$from" ] || [ "${from#ftp://}" != "$from" ]; then
  407. # http/https/ftp mirror
  408. if wgetprogress ${CHECKCERTIF:+"$CHECKCERTIF"} ${CERTIFICATE:+"$CERTIFICATE"} ${PRIVATEKEY:+"$PRIVATEKEY"} -O "$dest" "$from"; then
  409. return 0
  410. else
  411. rm -f "$dest"
  412. return 1
  413. fi
  414. elif [ "${from#file:}" != "$from" ]; then
  415. local base="${from#file:}"
  416. if [ "${base#//}" != "$base" ]; then
  417. base="/${from#file://*/}"
  418. fi
  419. if [ -e "$base" ]; then
  420. cp "$base" "$dest"
  421. return 0
  422. else
  423. return 1
  424. fi
  425. elif [ "${from#ssh:}" != "$from" ]; then
  426. local ssh_dest="$(echo "$from" | sed -e 's#ssh://##' -e 's#/#:/#')"
  427. if [ -n "$ssh_dest" ]; then
  428. scp "$ssh_dest" "$dest"
  429. return 0
  430. else
  431. return 1
  432. fi
  433. else
  434. error 1 UNKNOWNLOC "unknown location %s" "$from"
  435. fi
  436. }
  437. download () {
  438. mk_download_dirs
  439. "$DOWNLOAD_DEBS" "$(echo "$@" | tr ' ' '\n' | sort)"
  440. }
  441. download_indices () {
  442. mk_download_dirs
  443. "$DOWNLOAD_INDICES" "$(echo "$@" | tr ' ' '\n' | sort)"
  444. }
  445. debfor () {
  446. (while read pkg path; do
  447. for p in "$@"; do
  448. [ "$p" = "$pkg" ] || continue;
  449. echo "$path"
  450. done
  451. done <"$TARGET/debootstrap/debpaths"
  452. )
  453. }
  454. apt_dest () {
  455. # args:
  456. # deb package version arch mirror path
  457. # pkg suite component arch mirror path
  458. # rel suite mirror path
  459. case "$1" in
  460. deb)
  461. echo "/var/cache/apt/archives/${2}_${3}_${4}.deb" | sed 's/:/%3a/'
  462. ;;
  463. pkg)
  464. local m="$5"
  465. printf "%s" "$APTSTATE/lists/"
  466. echo "${m}_$6" | sed -e 's,^[^:]\+://,,' -e 's/\//_/g'
  467. ;;
  468. rel)
  469. local m="$3"
  470. printf "%s" "$APTSTATE/lists/"
  471. echo "${m}_$4" | sed -e 's,^[^:]\+://,,' -e 's/\//_/g'
  472. ;;
  473. esac
  474. }
  475. ################################################################## download
  476. get_release_checksum () {
  477. local reldest path
  478. reldest="$1"
  479. path="$2"
  480. if [ "$DEBOOTSTRAP_CHECKSUM_FIELD" = MD5SUM ]; then
  481. local match="^[Mm][Dd]5[Ss][Uu][Mm]"
  482. else
  483. local match="^[Ss][Hh][Aa]$SHA_SIZE:"
  484. fi
  485. sed -n "/$match/,/^[^ ]/p" < "$reldest" | \
  486. while read a b c; do
  487. if [ "$c" = "$path" ]; then echo "$a $b"; fi
  488. done | head -n 1
  489. }
  490. extract_release_components () {
  491. local reldest="$1"; shift
  492. TMPCOMPONENTS="$(sed -n 's/Components: *//p' "$reldest")"
  493. for c in $TMPCOMPONENTS ; do
  494. eval "
  495. case \"\$c\" in
  496. $USE_COMPONENTS)
  497. COMPONENTS=\"\$COMPONENTS \$c\"
  498. ;;
  499. esac
  500. "
  501. done
  502. if [ -z "$COMPONENTS" ]; then
  503. mv "$reldest" "$reldest.malformed"
  504. error 1 INVALIDREL "Invalid Release file, no valid components"
  505. fi
  506. }
  507. CODENAME=""
  508. validate_suite () {
  509. local reldest suite
  510. reldest="$1"
  511. CODENAME=$(sed -n "s/^Codename: *//p" "$reldest")
  512. suite=$(sed -n "s/^Suite: *//p" "$reldest")
  513. for s in $SUITE $EXTRA_SUITES; do
  514. if [ "$s" = "$suite" ] || [ "$s" = "$CODENAME" ]; then
  515. return 0
  516. fi
  517. done
  518. if [ "$EXTRA_SUITES" = "" ]; then
  519. error 1 WRONGSUITE "Asked to install suite %s, but got %s (codename: %s) from mirror" "$SUITE" "$suite" "$CODENAME"
  520. else
  521. error 1 WRONGSUITE "Asked to install suites %s %s, but got %s (codename: %s) from mirror" "$SUITE" "$EXTRA_SUITES" "$suite" "$CODENAME"
  522. fi
  523. }
  524. split_inline_sig () {
  525. local inreldest reldest relsigdest
  526. inreldest="$1"
  527. reldest="$2"
  528. relsigdest="$3"
  529. # Note: InRelease files are fun since one needs to remove the
  530. # last newline from the PGP SIGNED MESSAGE part, while keeping
  531. # the PGP SIGNATURE part intact. This shell implementation
  532. # should work on most if not all systems, instead of trying to
  533. # sed/tr/head, etc.
  534. rm -f "$reldest" "$relsigdest"
  535. nl=""
  536. state="pre-begin"
  537. while IFS= read -r line; do
  538. case "${state}" in
  539. pre-begin)
  540. if [ "x${line}" = "x-----BEGIN PGP SIGNED MESSAGE-----" ]; then
  541. state="begin"
  542. fi
  543. ;;
  544. begin)
  545. if [ "x${line}" = "x" ]; then
  546. state="data"
  547. fi
  548. ;;
  549. data)
  550. if [ "x${line}" = "x-----BEGIN PGP SIGNATURE-----" ]; then
  551. printf "%s\n" "${line}" > "$relsigdest"
  552. state="signature"
  553. else
  554. printf "${nl}%s" "${line}" >> "$reldest"
  555. nl="\n"
  556. fi
  557. ;;
  558. signature)
  559. printf "%s\n" "${line}" >> "$relsigdest"
  560. if [ "x${line}" = "x-----END PGP SIGNATURE-----" ]; then
  561. break
  562. fi
  563. esac
  564. done < "$inreldest"
  565. }
  566. download_release_sig () {
  567. local m1 suite inreldest reldest relsigdest
  568. m1="$1"
  569. suite="$2"
  570. inreldest="$3"
  571. reldest="$4"
  572. relsigdest="$5"
  573. progress 0 100 DOWNREL "Downloading Release file"
  574. progress_next 100
  575. if get "$m1/dists/$suite/InRelease" "$inreldest" nocache; then
  576. split_inline_sig "$inreldest" "$reldest" "$relsigdest"
  577. progress 100 100 DOWNREL "Downloading Release file"
  578. else
  579. get "$m1/dists/$suite/Release" "$reldest" nocache ||
  580. error 1 NOGETREL "Failed getting release file %s" "$m1/dists/$suite/Release"
  581. progress 100 100 DOWNREL "Downloading Release file"
  582. fi
  583. if [ -n "$KEYRING" ] && [ -z "$DISABLE_KEYRING" ]; then
  584. progress 0 100 DOWNRELSIG "Downloading Release file signature"
  585. if ! [ -f "$relsigdest" ]; then
  586. progress_next 50
  587. get "$m1/dists/$suite/Release.gpg" "$relsigdest" nocache ||
  588. error 1 NOGETRELSIG "Failed getting release signature file %s" \
  589. "$m1/dists/$suite/Release.gpg"
  590. progress 50 100 DOWNRELSIG "Downloading Release file signature"
  591. fi
  592. info RELEASESIG "Checking Release signature"
  593. # Don't worry about the exit status from gpgv; parsing the output will
  594. # take care of that.
  595. (gpgv --status-fd 1 --keyring "$KEYRING" --ignore-time-conflict \
  596. "$relsigdest" "$reldest" || true) | read_gpg_status
  597. progress 100 100 DOWNRELSIG "Downloading Release file signature"
  598. fi
  599. }
  600. download_release_indices () {
  601. local m1 inreldest reldest relsigdest totalpkgs \
  602. subpath xzi bz2i gzi normi i ext \
  603. donepkgs pkgdest acquirebyhash
  604. m1="${MIRRORS%% *}"
  605. for s in $SUITE $EXTRA_SUITES; do
  606. inreldest="$TARGET/$($DLDEST rel "$s" "$m1" "dists/$s/InRelease")"
  607. reldest="$TARGET/$($DLDEST rel "$s" "$m1" "dists/$s/Release")"
  608. relsigdest="$TARGET/$($DLDEST rel "$s" "$m1" "dists/$s/Release.gpg")"
  609. download_release_sig "$m1" "$s" "$inreldest" "$reldest" "$relsigdest"
  610. validate_suite "$reldest"
  611. extract_release_components "$reldest"
  612. acquirebyhash=$(grep "^Acquire-By-Hash: yes$" "$reldest" || true)
  613. totalpkgs=0
  614. for c in $COMPONENTS; do
  615. subpath="$c/binary-$ARCH/Packages"
  616. xzi="$(get_release_checksum "$reldest" "$subpath.xz")"
  617. bz2i="$(get_release_checksum "$reldest" "$subpath.bz2")"
  618. gzi="$(get_release_checksum "$reldest" "$subpath.gz")"
  619. normi="$(get_release_checksum "$reldest" "$subpath")"
  620. if [ "$normi" != "" ]; then
  621. i="$normi"
  622. elif in_path bunzip2 && [ "$bz2i" != "" ]; then
  623. i="$bz2i"
  624. elif in_path unxz && [ "$xzi" != "" ]; then
  625. i="$xzi"
  626. elif in_path gunzip && [ "$gzi" != "" ]; then
  627. i="$gzi"
  628. fi
  629. if [ "$i" != "" ]; then
  630. totalpkgs=$(( $totalpkgs + ${i#* } ))
  631. else
  632. mv "$reldest" "$reldest.malformed"
  633. error 1 MISSINGRELENTRY "Invalid Release file, no entry for %s" "$subpath"
  634. fi
  635. done
  636. donepkgs=0
  637. progress 0 $totalpkgs DOWNPKGS "Downloading Packages files"
  638. for c in $COMPONENTS; do
  639. subpath="$c/binary-$ARCH/Packages"
  640. path="dists/$s/$subpath"
  641. xzi="$(get_release_checksum "$reldest" "$subpath.xz")"
  642. bz2i="$(get_release_checksum "$reldest" "$subpath.bz2")"
  643. gzi="$(get_release_checksum "$reldest" "$subpath.gz")"
  644. normi="$(get_release_checksum "$reldest" "$subpath")"
  645. ext=""
  646. if [ "$acquirebyhash" != "" ]; then
  647. ext="$ext byhash"
  648. fi
  649. if [ "$normi" != "" ]; then
  650. ext="$ext $normi ."
  651. i="$normi"
  652. fi
  653. if in_path unxz && [ "$xzi" != "" ]; then
  654. ext="$ext $xzi xz"
  655. i="${i:-$xzi}"
  656. fi
  657. if in_path bunzip2 && [ "$bz2i" != "" ]; then
  658. ext="$ext $bz2i bz2"
  659. i="${i:-$bz2i}"
  660. fi
  661. if in_path gunzip && [ "$gzi" != "" ]; then
  662. ext="$ext $gzi gz"
  663. i="${i:-$gzi}"
  664. fi
  665. progress_next $(($donepkgs + ${i#* }))
  666. for m in $MIRRORS; do
  667. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m" "$path")"
  668. if get "$m/$path" "$pkgdest" $ext; then break; fi
  669. done
  670. if [ ! -f "$pkgdest" ]; then
  671. error 1 COULDNTDL "Couldn't download %s" "$m/$path"
  672. fi
  673. donepkgs=$(($donepkgs + ${i#* }))
  674. progress $donepkgs $totalpkgs DOWNPKGS "Downloading Packages files"
  675. done
  676. done
  677. }
  678. get_package_sizes () {
  679. # mirror pkgdest debs..
  680. local m pkgdest
  681. m="$1"; shift
  682. pkgdest="$1"; shift
  683. $PKGDETAILS PKGS "$m" "$pkgdest" "$@" | (
  684. newleft=""
  685. totaldebs=0
  686. countdebs=0
  687. while read p details; do
  688. if [ "$details" = "-" ]; then
  689. newleft="$newleft $p"
  690. else
  691. size="${details##* }";
  692. totaldebs=$(($totaldebs + $size))
  693. countdebs=$(($countdebs + 1))
  694. fi
  695. done
  696. echo "$countdebs $totaldebs$newleft"
  697. )
  698. }
  699. # note, leftovers come back on fd5 !!
  700. download_debs () {
  701. local m pkgdest debdest debcache
  702. m="$1"
  703. pkgdest="$2"
  704. shift; shift
  705. "$PKGDETAILS" PKGS "$m" "$pkgdest" "$@" | (
  706. leftover=""
  707. while read p ver arc mdup fil checksum size; do
  708. if [ "$ver" = "-" ]; then
  709. leftover="$leftover $p"
  710. else
  711. progress_next $(($dloaddebs + $size))
  712. debdest="$($DLDEST deb "$p" "$ver" "$arc" "$m" "$fil")"
  713. debcache="$(echo "$p"_"$ver"_"$arc".deb | sed 's/:/%3a/')"
  714. if [ -z "$CACHE_DIR" ] && get "$m/$fil" "$TARGET/$debdest" "$checksum" "$size"; then
  715. dloaddebs=$(($dloaddebs + $size))
  716. echo >>"$TARGET/debootstrap/deburis" "$p $ver $m/$fil"
  717. echo >>"$TARGET/debootstrap/debpaths" "$p $debdest"
  718. elif [ -d "$CACHE_DIR" ] && get "$m/$fil" "$CACHE_DIR/$debcache" "$checksum" "$size"; then
  719. dloaddebs=$(($dloaddebs + $size))
  720. echo >>"$TARGET/debootstrap/deburis" "$p $ver $m/$fil"
  721. echo >>"$TARGET/debootstrap/debpaths" "$p $debdest"
  722. cp "$CACHE_DIR/$debcache" "$TARGET/$debdest"
  723. else
  724. warning COULDNTDL "Couldn't download package %s (ver %s arch %s) at %s" "$p" "$ver" "$arc" "$m/$fil"
  725. leftover="$leftover $p"
  726. fi
  727. fi
  728. done
  729. echo >&5 ${leftover# }
  730. )
  731. }
  732. download_release () {
  733. local m1 numdebs countdebs totaldebs leftoverdebs path pkgdest dloaddebs
  734. m1="${MIRRORS%% *}"
  735. numdebs="$#"
  736. countdebs=0
  737. progress "$countdebs" "$numdebs" SIZEDEBS "Finding package sizes"
  738. totaldebs=0
  739. leftoverdebs="$*"
  740. # Fix possible duplicate package names, which would screw up counts:
  741. leftoverdebs=$(printf "$leftoverdebs"|tr ' ' '\n'|sort -u|tr '\n' ' ')
  742. numdebs=$(printf "$leftoverdebs"|wc -w)
  743. for s in $SUITE $EXTRA_SUITES; do
  744. for c in $COMPONENTS; do
  745. if [ "$countdebs" -ge "$numdebs" ]; then break; fi
  746. path="dists/$s/$c/binary-$ARCH/Packages"
  747. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m1" "$path")"
  748. if [ ! -e "$pkgdest" ]; then continue; fi
  749. info CHECKINGSIZES "Checking component %s on %s..." "$c" "$m1"
  750. leftoverdebs="$(get_package_sizes "$m1" "$pkgdest" $leftoverdebs)"
  751. countdebs=$(($countdebs + ${leftoverdebs%% *}))
  752. leftoverdebs=${leftoverdebs#* }
  753. totaldebs=${leftoverdebs%% *}
  754. leftoverdebs=${leftoverdebs#* }
  755. progress "$countdebs" "$numdebs" SIZEDEBS "Finding package sizes"
  756. done
  757. done
  758. if [ "$countdebs" -ne "$numdebs" ]; then
  759. error 1 LEFTOVERDEBS "Couldn't find these debs: %s" "$leftoverdebs"
  760. fi
  761. dloaddebs=0
  762. progress "$dloaddebs" "$totaldebs" DOWNDEBS "Downloading packages"
  763. :>"$TARGET/debootstrap/debpaths"
  764. pkgs_to_get="$*"
  765. for s in $SUITE $EXTRA_SUITES; do
  766. for c in $COMPONENTS; do
  767. path="dists/$s/$c/binary-$ARCH/Packages"
  768. for m in $MIRRORS; do
  769. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m" "$path")"
  770. if [ ! -e "$pkgdest" ]; then continue; fi
  771. pkgs_to_get="$(download_debs "$m" "$pkgdest" $pkgs_to_get 5>&1 1>&6)"
  772. if [ -z "$pkgs_to_get" ]; then break; fi
  773. done 6>&1
  774. if [ -z "$pkgs_to_get" ]; then break; fi
  775. done
  776. if [ -z "$pkgs_to_get" ]; then break; fi
  777. done
  778. progress "$dloaddebs" "$totaldebs" DOWNDEBS "Downloading packages"
  779. if [ "$pkgs_to_get" != "" ]; then
  780. error 1 COULDNTDLPKGS "Couldn't download packages: %s" "$pkgs_to_get"
  781. fi
  782. }
  783. download_main_indices () {
  784. local m1 comp path pkgdest
  785. m1="${MIRRORS%% *}"
  786. comp="${USE_COMPONENTS}"
  787. progress 0 100 DOWNMAINPKGS "Downloading Packages file"
  788. progress_next 100
  789. if [ -z "$comp" ]; then comp=main; fi
  790. COMPONENTS="$(echo $comp | tr '|' ' ')"
  791. export COMPONENTS
  792. for m in $MIRRORS; do
  793. for s in $SUITE $EXTRA_SUITES; do
  794. for c in $COMPONENTS; do
  795. path="dists/$s/$c/binary-$ARCH/Packages"
  796. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m" "$path")"
  797. if in_path gunzip && get "$m/${path}.gz" "${pkgdest}.gz"; then
  798. rm -f "$pkgdest"
  799. gunzip "$pkgdest.gz"
  800. elif get "$m/$path" "$pkgdest"; then
  801. true
  802. fi
  803. done
  804. done
  805. done
  806. progress 100 100 DOWNMAINPKGS "Downloading Packages file"
  807. }
  808. download_main () {
  809. local m1 path pkgdest debdest
  810. m1="${MIRRORS%% *}"
  811. :>"$TARGET/debootstrap/debpaths"
  812. for p in "$@"; do
  813. for s in $SUITE $EXTRA_SUITES; do
  814. for c in $COMPONENTS; do
  815. local details=""
  816. for m in $MIRRORS; do
  817. path="dists/$s/$c/binary-$ARCH/Packages"
  818. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m" "$path")"
  819. if [ ! -e "$pkgdest" ]; then continue; fi
  820. details="$($PKGDETAILS PKGS "$m" "$pkgdest" "$p")"
  821. if [ "$details" = "$p -" ]; then
  822. details=""
  823. continue
  824. fi
  825. size="${details##* }"; details="${details% *}"
  826. checksum="${details##* }"; details="${details% *}"
  827. debdest="$($DLDEST deb $details)"
  828. if get "$m/${details##* }" "$TARGET/$debdest" "$checksum" "$size"; then
  829. echo >>"$TARGET/debootstrap/debpaths" "$p $debdest"
  830. details="done"
  831. break
  832. fi
  833. done
  834. if [ "$details" != "" ]; then
  835. break
  836. fi
  837. done
  838. if [ "$details" != "" ]; then
  839. break
  840. fi
  841. done
  842. if [ "$details" != "done" ]; then
  843. error 1 COULDNTDL "Couldn't download %s" "$p"
  844. fi
  845. done
  846. }
  847. ###################################################### deb choosing support
  848. get_debs () {
  849. local field m1 c path pkgdest
  850. field="$1"
  851. shift
  852. for m1 in $MIRRORS; do
  853. for s in $SUITE $EXTRA_SUITES; do
  854. for c in $COMPONENTS; do
  855. path="dists/$s/$c/binary-$ARCH/Packages"
  856. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m1" "$path")"
  857. echo "$("$PKGDETAILS" FIELD "$field" "$m1" "$pkgdest" "$@" | sed 's/ .*//')"
  858. done
  859. done
  860. done
  861. }
  862. ################################################################ extraction
  863. EXTRACTORS_SUPPORTED="dpkg-deb ar"
  864. EXTRACT_DEB_TAR_OPTIONS=
  865. # Native dpkg-deb based extractors
  866. extract_dpkg_deb_field () {
  867. local pkg field
  868. pkg="$1"
  869. field="$2"
  870. dpkg-deb -f "$pkg" "$field"
  871. }
  872. extract_dpkg_deb_data () {
  873. local pkg="$1"
  874. dpkg-deb --fsys-tarfile "$pkg" | tar $EXTRACT_DEB_TAR_OPTIONS -xf - || error 1 FILEEXIST "Tried to extract package, but file already exists. Exit..."
  875. }
  876. # Raw .deb extractors
  877. extract_ar_deb_field () {
  878. local pkg field tarball
  879. pkg="$1"
  880. field="$2"
  881. tarball=$(ar -t "$pkg" | grep "^control\.tar")
  882. case "$tarball" in
  883. control.tar.gz) cat_cmd=zcat ;;
  884. control.tar.xz) cat_cmd=xzcat ;;
  885. control.tar) cat_cmd=cat ;;
  886. *) error 1 UNKNOWNCONTROLCOMP "Unknown compression type for %s in %s" "$tarball" "$pkg" ;;
  887. esac
  888. if in_path $cat_cmd; then
  889. ar -p "$pkg" "$tarball" | $cat_cmd |
  890. tar -O -xf - control ./control 2>/dev/null |
  891. grep -i "^$field:" | sed -e 's/[^:]*: *//' | head -n 1
  892. else
  893. error 1 UNPACKCMDUNVL "Extracting %s requires the %s command, which is not available" "$pkg" "$cat_cmd"
  894. fi
  895. }
  896. extract_ar_deb_data () {
  897. local pkg tarball
  898. pkg="$1"
  899. tarball="$(ar -t "$pkg" | grep "^data.tar")"
  900. case "$tarball" in
  901. data.tar.gz) cat_cmd=zcat ;;
  902. data.tar.bz2) cat_cmd=bzcat ;;
  903. data.tar.xz) cat_cmd=xzcat ;;
  904. data.tar) cat_cmd=cat ;;
  905. *) error 1 UNKNOWNDATACOMP "Unknown compression type for %s in %s" "$tarball" "$pkg" ;;
  906. esac
  907. if in_path "$cat_cmd"; then
  908. ar -p "$pkg" "$tarball" | "$cat_cmd" | tar $EXTRACT_DEB_TAR_OPTIONS -xf -
  909. else
  910. error 1 UNPACKCMDUNVL "Extracting %s requires the %s command, which is not available" "$pkg" "$cat_cmd"
  911. fi
  912. }
  913. valid_extractor () {
  914. local extractor="$1"
  915. for E in $EXTRACTORS_SUPPORTED; do
  916. if [ "$extractor" = "$E" ]; then
  917. return 0
  918. fi
  919. done
  920. return 1
  921. }
  922. choose_extractor () {
  923. local extractor
  924. if [ -n "$EXTRACTOR_OVERRIDE" ]; then
  925. extractor="$EXTRACTOR_OVERRIDE"
  926. elif in_path dpkg-deb; then
  927. extractor="dpkg-deb"
  928. else
  929. extractor="ar"
  930. fi
  931. info CHOSENEXTRACTOR "Chosen extractor for .deb packages: %s" "$extractor"
  932. case "$extractor" in
  933. dpkg-deb)
  934. extract_deb_field () { extract_dpkg_deb_field "$@"; }
  935. extract_deb_data () { extract_dpkg_deb_data "$@"; }
  936. ;;
  937. ar)
  938. extract_deb_field () { extract_ar_deb_field "$@"; }
  939. extract_deb_data () { extract_ar_deb_data "$@"; }
  940. ;;
  941. esac
  942. }
  943. extract () { (
  944. cd "$TARGET" || exit 1
  945. local p cat_cmd
  946. p=0
  947. for pkg in $(debfor "$@"); do
  948. p=$(($p + 1))
  949. progress "$p" "$#" EXTRACTPKGS "Extracting packages"
  950. packagename="$(echo "$pkg" | sed 's,^.*/,,;s,_.*$,,')"
  951. info EXTRACTING "Extracting %s..." "$packagename"
  952. extract_deb_data "./$pkg"
  953. done
  954. ); }
  955. in_target_nofail () {
  956. if ! PATH=/sbin:/usr/sbin:/bin:/usr/bin eval "$CHROOT_CMD \"\$@\"" 2>/dev/null; then
  957. true
  958. fi
  959. return 0
  960. }
  961. in_target_failmsg () {
  962. local code msg arg
  963. code="$1"
  964. msg="$2"
  965. arg="$3"
  966. shift; shift; shift
  967. if ! PATH=/sbin:/usr/sbin:/bin:/usr/bin eval "$CHROOT_CMD \"\$@\""; then
  968. warning "$code" "$msg" "$arg"
  969. # Try to point user at actual failing package.
  970. msg="See %s for details"
  971. if [ -e "$TARGET/debootstrap/debootstrap.log" ]; then
  972. arg="$TARGET/debootstrap/debootstrap.log"
  973. local pkg="$(grep '^dpkg: error processing ' "$TARGET/debootstrap/debootstrap.log" | head -n 1 | sed 's/\(error processing \)\(package \|archive \)/\1/' | cut -d ' ' -f 4)"
  974. if [ -n "$pkg" ]; then
  975. msg="$msg (possibly the package $pkg is at fault)"
  976. fi
  977. else
  978. arg="the log"
  979. fi
  980. warning "$code" "$msg" "$arg"
  981. return 1
  982. fi
  983. return 0
  984. }
  985. in_target () {
  986. in_target_failmsg IN_TARGET_FAIL "Failure trying to run: %s" "$CHROOT_CMD $*" "$@"
  987. }
  988. ###################################################### standard setup stuff
  989. conditional_cp () {
  990. if [ ! -e "$2/$1" ]; then
  991. if [ -L "$1" ] && [ -e "$1" ]; then
  992. cat "$1" >"$2/$1"
  993. elif [ -e "$1" ]; then
  994. cp "$1" "$2/$1"
  995. fi
  996. fi
  997. }
  998. setup_apt_sources () {
  999. mkdir -p "$TARGET/etc/apt"
  1000. for m in "$@"; do
  1001. for s in $SUITE $EXTRA_SUITES; do
  1002. local cs c path pkgdest
  1003. for c in ${COMPONENTS:-$USE_COMPONENTS}; do
  1004. path="dists/$s/$c/binary-$ARCH/Packages"
  1005. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m" "$path")"
  1006. if [ -e "$pkgdest" ]; then cs="$cs $c"; fi
  1007. done
  1008. if [ "$cs" != "" ]; then echo "deb $m $s$cs"; fi
  1009. done
  1010. done > "$TARGET/etc/apt/sources.list"
  1011. }
  1012. setup_etc () {
  1013. mkdir -p "$TARGET/etc"
  1014. conditional_cp /etc/resolv.conf "$TARGET"
  1015. conditional_cp /etc/hostname "$TARGET"
  1016. }
  1017. UMOUNT_DIRS=
  1018. umount_exit_function () {
  1019. local realdir
  1020. for dir in $UMOUNT_DIRS; do
  1021. realdir="$(in_target_nofail readlink -f "$dir")"
  1022. [ "$realdir" ] || continue
  1023. ( cd / ; umount "$TARGET/${realdir#/}" ) || true
  1024. done
  1025. }
  1026. umount_on_exit () {
  1027. if [ "$UMOUNT_DIRS" ]; then
  1028. UMOUNT_DIRS="$1 $UMOUNT_DIRS"
  1029. else
  1030. UMOUNT_DIRS="$1"
  1031. on_exit umount_exit_function
  1032. fi
  1033. }
  1034. clear_mtab () {
  1035. if [ -f "$TARGET/etc/mtab" ] && [ ! -h "$TARGET/etc/mtab" ]; then
  1036. rm -f "$TARGET/etc/mtab"
  1037. fi
  1038. }
  1039. setup_proc () {
  1040. case "$HOST_OS" in
  1041. *freebsd*)
  1042. umount_on_exit /dev
  1043. umount_on_exit /proc
  1044. umount "$TARGET/proc" 2>/dev/null || true
  1045. if [ "$HOST_OS" = kfreebsd ]; then
  1046. in_target mount -t linprocfs proc /proc
  1047. else
  1048. mount -t linprocfs proc "$TARGET/proc"
  1049. fi
  1050. ;;
  1051. hurd*)
  1052. # firmlink $TARGET/{dev,servers,proc} to the system ones.
  1053. settrans -a "$TARGET/dev" /hurd/firmlink /dev
  1054. settrans -a "$TARGET/servers" /hurd/firmlink /servers
  1055. settrans -a "$TARGET/proc" /hurd/firmlink /proc
  1056. ;;
  1057. *)
  1058. umount_on_exit /dev/pts
  1059. umount_on_exit /dev/shm
  1060. umount_on_exit /proc
  1061. umount_on_exit /proc/bus/usb
  1062. umount "$TARGET/proc" 2>/dev/null || true
  1063. # some container environment are used at second-stage, it already treats /proc and so on
  1064. if [ -z "$(ls -A "$TARGET/proc")" ]; then
  1065. # second-stage in docker, we cannot detect it is inside docker... just ignore warning
  1066. in_target mount -t proc proc /proc || true
  1067. umount_on_exit /proc
  1068. fi
  1069. if [ -n "$(ls -A "$TARGET/sys")" ] && \
  1070. grep -qs '[[:space:]]sysfs' "$TARGET/proc/filesystems" || \
  1071. [ "$CONTAINER" = "docker" ]; then
  1072. umount_on_exit /sys
  1073. umount "$TARGET/sys" 2>/dev/null || true
  1074. else
  1075. # second-stage in docker, we cannot detect it is inside docker... just ignore warning
  1076. in_target mount -t sysfs sysfs /sys || true
  1077. umount_on_exit /sys
  1078. fi
  1079. on_exit clear_mtab
  1080. ;;
  1081. esac
  1082. umount_on_exit /lib/init/rw
  1083. }
  1084. setup_proc_symlink () {
  1085. rm -rf "$TARGET/proc"
  1086. ln -s /proc "$TARGET"
  1087. }
  1088. # create the static device nodes
  1089. setup_devices () {
  1090. if doing_variant fakechroot; then
  1091. setup_devices_fakechroot
  1092. return 0
  1093. fi
  1094. case "$HOST_OS" in
  1095. kfreebsd*)
  1096. ;;
  1097. freebsd)
  1098. ;;
  1099. hurd*)
  1100. ;;
  1101. *)
  1102. if [ "$CONTAINER" = "lxc" ] || [ "$CONTAINER" = "lxc-libvirt" ]; then
  1103. if ! setup_devices_simple; then
  1104. setup_devices_bind
  1105. fi
  1106. return 0
  1107. fi
  1108. setup_devices_simple
  1109. ;;
  1110. esac
  1111. }
  1112. # enable the dynamic device nodes
  1113. setup_dynamic_devices () {
  1114. if doing_variant fakechroot; then
  1115. return 0
  1116. fi
  1117. case "$HOST_OS" in
  1118. kfreebsd*)
  1119. in_target mount -t devfs devfs /dev ;;
  1120. freebsd)
  1121. mount -t devfs devfs "$TARGET/dev" ;;
  1122. hurd*)
  1123. # Use the setup-translators of the hurd package
  1124. in_target /usr/lib/hurd/setup-translators -k ;;
  1125. esac
  1126. }
  1127. # Create a device node if it does not exist. By default, the mode is 666.
  1128. mknod_if_needed () {
  1129. local device type major minor mode
  1130. device="$1"
  1131. type="$2"
  1132. major="$3"
  1133. minor="$4"
  1134. mode="${5:-666}"
  1135. if [ ! -e "$device" ]; then
  1136. mknod -m "$mode" "$device" "$type" "$major" "$minor"
  1137. fi
  1138. }
  1139. setup_devices_simple () {
  1140. # The list of devices that can be created in a container comes from
  1141. # src/core/cgroup.c in the systemd source tree.
  1142. mknod_if_needed "$TARGET/dev/null" c 1 3
  1143. mknod_if_needed "$TARGET/dev/zero" c 1 5
  1144. mknod_if_needed "$TARGET/dev/full" c 1 7
  1145. mknod_if_needed "$TARGET/dev/random" c 1 8
  1146. mknod_if_needed "$TARGET/dev/urandom" c 1 9
  1147. mknod_if_needed "$TARGET/dev/tty" c 5 0
  1148. if [ ! "$CONTAINER" = "systemd-nspawn" ]; then
  1149. mknod_if_needed "$TARGET/dev/console" c 5 1
  1150. fi
  1151. # To avoid pre-exist directory causes error, specify "-p" option
  1152. mkdir -p "$TARGET/dev/pts/" "$TARGET/dev/shm/"
  1153. # Inside a container, we might not be allowed to create /dev/ptmx.
  1154. # If not, do the next best thing.
  1155. if ! mknod_if_needed "$TARGET/dev/ptmx" c 5 2; then
  1156. warning MKNOD "Could not create /dev/ptmx, falling back to symlink. This chroot will require /dev/pts mounted with ptmxmode=666"
  1157. ln -sf pts/ptmx "$TARGET/dev/ptmx"
  1158. fi
  1159. ln -sf /proc/self/fd "$TARGET/dev/fd"
  1160. ln -sf /proc/self/fd/0 "$TARGET/dev/stdin"
  1161. ln -sf /proc/self/fd/1 "$TARGET/dev/stdout"
  1162. ln -sf /proc/self/fd/2 "$TARGET/dev/stderr"
  1163. }
  1164. setup_devices_fakechroot () {
  1165. rm -rf "$TARGET/dev"
  1166. ln -s /dev "$TARGET"
  1167. }
  1168. setup_devices_bind () {
  1169. mount -t tmpfs nodev "$TARGET/dev"
  1170. umount_on_exit /dev
  1171. for device in null zero full random urandom tty pts shm ptmx; do
  1172. if [ -d "/dev/$device" ]; then
  1173. mkdir "$TARGET/dev/$device"
  1174. elif [ -c "/dev/$device" ]; then
  1175. touch "$TARGET/dev/$device"
  1176. else
  1177. continue
  1178. fi
  1179. mount -o bind "/dev/$device" "$TARGET/dev/$device"
  1180. umount_on_exit "/dev/$device"
  1181. done
  1182. ln -s /proc/self/fd "$TARGET/dev/fd"
  1183. ln -s /proc/self/fd/0 "$TARGET/dev/stdin"
  1184. ln -s /proc/self/fd/1 "$TARGET/dev/stdout"
  1185. ln -s /proc/self/fd/2 "$TARGET/dev/stderr"
  1186. }
  1187. setup_dselect_method () {
  1188. case "$1" in
  1189. apt)
  1190. mkdir -p "$TARGET/var/lib/dpkg"
  1191. echo "apt apt" > "$TARGET/var/lib/dpkg/cmethopt"
  1192. chmod 644 "$TARGET/var/lib/dpkg/cmethopt"
  1193. ;;
  1194. *)
  1195. error 1 UNKNOWNDSELECT "unknown dselect method"
  1196. ;;
  1197. esac
  1198. }
  1199. # Find out where the runtime dynamic linker and the shared libraries
  1200. # can be installed on each architecture: native, multilib and multiarch.
  1201. # This data can be verified by checking the files in the debian/sysdeps/
  1202. # directory of the glibc package.
  1203. #
  1204. # This function must be updated to support any new architecture which
  1205. # either installs the RTLD in a directory different from /lib or builds
  1206. # multilib library packages.
  1207. setup_merged_usr() {
  1208. if doing_variant buildd || [ -z "$MERGED_USR" ]; then
  1209. MERGED_USR="no"
  1210. fi
  1211. if [ "$MERGED_USR" = "no" ]; then return 0; fi
  1212. local link_dir
  1213. case $ARCH in
  1214. hurd-*) return 0 ;;
  1215. amd64) link_dir="lib32 lib64 libx32" ;;
  1216. i386) link_dir="lib64 libx32" ;;
  1217. mips|mipsel)
  1218. link_dir="lib32 lib64" ;;
  1219. mips64*|mipsn32*)
  1220. link_dir="lib32 lib64 libo32" ;;
  1221. powerpc) link_dir="lib64" ;;
  1222. ppc64) link_dir="lib32 lib64" ;;
  1223. ppc64el) link_dir="lib64" ;;
  1224. s390x) link_dir="lib32" ;;
  1225. sparc) link_dir="lib64" ;;
  1226. sparc64) link_dir="lib32 lib64" ;;
  1227. x32) link_dir="lib32 lib64 libx32" ;;
  1228. esac
  1229. link_dir="bin sbin lib $link_dir"
  1230. local dir
  1231. for dir in $link_dir; do
  1232. ln -s usr/"$dir" "$TARGET/$dir"
  1233. mkdir -p "$TARGET/usr/$dir"
  1234. done
  1235. }
  1236. ################################################################ pkgdetails
  1237. # NOTE
  1238. # For the debootstrap udeb, pkgdetails is provided by the bootstrap-base
  1239. # udeb, so the pkgdetails API needs to be kept in sync with that.
  1240. if in_path perl; then
  1241. PKGDETAILS=pkgdetails_perl
  1242. # test if grep supports --perl-regexp
  1243. set +e
  1244. echo x | grep --perl-regexp . >/dev/null 2>&1
  1245. if [ $? -eq 2 ]; then
  1246. gropt=-E
  1247. else
  1248. gropt=--perl-regexp
  1249. fi
  1250. set -e
  1251. pkgdetails_field () {
  1252. # uniq field mirror Packages values...
  1253. perl -le '
  1254. $unique = shift @ARGV; $field = lc(shift @ARGV); $mirror = shift @ARGV;
  1255. %fields = map { $_, 0 } @ARGV;
  1256. $prevpkg = "";
  1257. $chksumfield = lc($ENV{DEBOOTSTRAP_CHECKSUM_FIELD}).":";
  1258. while (<STDIN>) {
  1259. if (/^([^:]*:)\s*(.*)$/) {
  1260. $f = lc($1); $v = $2;
  1261. if ($f eq "package:") {
  1262. $last = 0;
  1263. $pkg = $v;
  1264. if ($pkg ne $prevpkg) {
  1265. print $output if defined $output;
  1266. if ($unique && defined $output_val) {
  1267. delete $fields{$output_val};
  1268. $last = 1 unless keys %fields;
  1269. }
  1270. $prevpkg = $pkg;
  1271. }
  1272. undef $output;
  1273. undef $output_val;
  1274. last if $last;
  1275. }
  1276. $ver = $v if ($f eq "version:");
  1277. $arc = $v if ($f eq "architecture:");
  1278. $fil = $v if ($f eq "filename:");
  1279. $chk = $v if ($f eq $chksumfield);
  1280. $siz = $v if ($f eq "size:");
  1281. $val = $v if ($f eq $field);
  1282. } elsif (/^$/) {
  1283. if (defined $val && defined $fields{$val}) {
  1284. $output = sprintf "%s %s %s %s %s %s %s",
  1285. $pkg, $ver, $arc, $mirror, $fil, $chk, $siz;
  1286. $output_val = $val;
  1287. }
  1288. undef $val;
  1289. }
  1290. }
  1291. print $output if defined $output;
  1292. delete $fields{$output_val} if $unique && defined $output_val;
  1293. for $v (keys %fields) {
  1294. printf ("%s -\n", $v) if ($unique);
  1295. }
  1296. ' "$@"
  1297. }
  1298. pkgdetails_perl () {
  1299. if [ "$1" = "WGET%" ]; then
  1300. shift;
  1301. perl -e '
  1302. $v = 0;
  1303. $allow_percentage = 0;
  1304. while (read STDIN, $x, 1) {
  1305. if ($x =~ m/\s/) {
  1306. $allow_percentage = 1;
  1307. } elsif ($allow_percentage and $x =~ m/\d/) {
  1308. $v *= 10;
  1309. $v += $x;
  1310. } elsif ($allow_percentage and $x eq "%") {
  1311. printf "P: %d %d%s\n", int($v / 100.0 * ($ARGV[1] - $ARGV[0]) + $ARGV[0]), $ARGV[2], ($#ARGV == 3 ? " $ARGV[3]" : "");
  1312. $v = 0;
  1313. } else {
  1314. $v = 0;
  1315. $allow_percentage = 0;
  1316. }
  1317. }' "$@"
  1318. elif [ "$1" = "GETDEPS" ]; then
  1319. local pkgdest="$2"; shift; shift
  1320. LC_ALL=C grep "$gropt" '^$|^Package:|^Depends:|^Pre-Depends:' $pkgdest | perl -e '
  1321. %seen = map { $_ => 1 } @ARGV;
  1322. while (<STDIN>) {
  1323. if (/^Package: (.*)$/) {
  1324. $pkg = $1;
  1325. next;
  1326. } elsif (/^$/) {
  1327. $in = 0;
  1328. next;
  1329. }
  1330. $in = 1 if $seen{$pkg};
  1331. if ($in and (/^Depends: (.*)$/ or /^Pre-Depends: (.*)$/)) {
  1332. for $d (split /\s*,\s*/, $1) {
  1333. $d =~ s/\s*[|].*$//;
  1334. $d =~ s/\s*[(].*[)]\s*//;
  1335. $d =~ s/:.*//;
  1336. $depends{$d} = 1;
  1337. }
  1338. }
  1339. }
  1340. foreach (sort keys %depends) {
  1341. print "$_\n";
  1342. }
  1343. ' "$@"
  1344. elif [ "$1" = "PKGS" ]; then
  1345. local m="$2"
  1346. local p="$3"
  1347. shift; shift; shift
  1348. LC_ALL=C grep "$gropt" '^$|^Architecture:|^Filename:|^MD5sum:|^Package:|^Priority:|^SHA256:|^Size:|^Version:|^Depends:|^Pre-Depends:' "$p" | pkgdetails_field 1 Package: "$m" "$@"
  1349. elif [ "$1" = "FIELD" ]; then
  1350. local f="$2"
  1351. local m="$3"
  1352. local p="$4"
  1353. shift; shift; shift; shift
  1354. LC_ALL=C grep "$gropt" '^$|^Package:|^Priority:' "$p" | pkgdetails_field 0 "$f" "$m" "$@"
  1355. elif [ "$1" = "STANZAS" ]; then
  1356. local pkgdest="$2"; shift; shift
  1357. perl -e '
  1358. my $accum = "";
  1359. %seen = map { $_ => 1 } @ARGV;
  1360. while (<STDIN>) {
  1361. $accum .= $_;
  1362. $in = 1 if (/^Package: (.*)$/ && $seen{$1});
  1363. if ($in and /^$/) {
  1364. print $accum;
  1365. if (substr($accum, -1) != "\n") {
  1366. print "\n\n";
  1367. } elsif (substr($accum, -2, 1) != "\n") {
  1368. print "\n";
  1369. }
  1370. $in = 0;
  1371. }
  1372. $accum = "" if /^$/;
  1373. }' <"$pkgdest" "$@"
  1374. fi
  1375. }
  1376. elif [ -e "/usr/lib/debootstrap/pkgdetails" ]; then
  1377. PKGDETAILS="/usr/lib/debootstrap/pkgdetails"
  1378. elif [ -e "$DEBOOTSTRAP_DIR/pkgdetails" ]; then
  1379. PKGDETAILS="$DEBOOTSTRAP_DIR/pkgdetails"
  1380. else
  1381. PKGDETAILS=""
  1382. fi
  1383. ##################################################### dependency resolution
  1384. resolve_deps () {
  1385. local m1="${MIRRORS%% *}"
  1386. local PKGS="$*"
  1387. local ALLPKGS="$PKGS";
  1388. local ALLPKGS2="";
  1389. while [ "$PKGS" != "" ]; do
  1390. local NEWPKGS=""
  1391. for s in $SUITE $EXTRA_SUITES; do
  1392. for c in ${COMPONENTS:-$(echo ${USE_COMPONENTS} | tr '|' ' ')}; do
  1393. local path="dists/$s/$c/binary-$ARCH/Packages"
  1394. local pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m1" "$path")"
  1395. NEWPKGS="$NEWPKGS $("$PKGDETAILS" GETDEPS "$pkgdest" $PKGS)"
  1396. done
  1397. done
  1398. PKGS=$(echo "$PKGS $NEWPKGS" | tr ' ' '\n' | sort | uniq)
  1399. local REALPKGS=""
  1400. for s in $SUITE $EXTRA_SUITES; do
  1401. for c in ${COMPONENTS:-$(echo ${USE_COMPONENTS} | tr '|' ' ')}; do
  1402. local path="dists/$s/$c/binary-$ARCH/Packages"
  1403. local pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m1" "$path")"
  1404. REALPKGS="$REALPKGS $("$PKGDETAILS" PKGS REAL "$pkgdest" $PKGS | sed -n 's/ .*REAL.*$//p')"
  1405. done
  1406. done
  1407. PKGS="$REALPKGS"
  1408. ALLPKGS2=$(echo "$PKGS $ALLPKGS" | tr ' ' '\n' | sort | uniq)
  1409. PKGS=$(without "$ALLPKGS2" "$ALLPKGS")
  1410. ALLPKGS="$ALLPKGS2"
  1411. done
  1412. echo "$ALLPKGS"
  1413. }
  1414. setup_available () {
  1415. local m1 c path pkgdest pkg
  1416. m1="${MIRRORS%% *}"
  1417. for s in $SUITE $EXTRA_SUITES; do
  1418. for c in ${COMPONENTS:-$(echo ${USE_COMPONENTS} | tr '|' ' ')}; do
  1419. path="dists/$s/$c/binary-$ARCH/Packages"
  1420. pkgdest="$TARGET/$($DLDEST pkg "$s" "$c" "$ARCH" "$m1" "$path")"
  1421. # XXX: What if a package is in more than one component?
  1422. # -- cjwatson 2009-07-29
  1423. # XXX: ...or suite?
  1424. # -- jrtc27 2019-06-11
  1425. "$PKGDETAILS" STANZAS "$pkgdest" "$@"
  1426. done
  1427. done >"$TARGET/var/lib/dpkg/available"
  1428. for pkg; do
  1429. echo "$pkg install"
  1430. done | in_target dpkg --set-selections
  1431. }
  1432. get_next_predep () {
  1433. local stanza="$(in_target_nofail dpkg --predep-package)"
  1434. [ "$stanza" ] || return 1
  1435. echo "$stanza" | grep '^Package:' | sed 's/^Package://; s/^ *//'
  1436. }
  1437. ################################################################### helpers
  1438. # Return zero if it is possible to create devices and execute programs in
  1439. # this directory. (Both may be forbidden by mount options, e.g. nodev and
  1440. # noexec respectively.)
  1441. check_sane_mount () {
  1442. mkdir -p "$1"
  1443. case "$HOST_OS" in
  1444. *freebsd*|hurd*)
  1445. ;;
  1446. *)
  1447. if ! doing_variant fakechroot; then
  1448. case "$CONTAINER" in
  1449. lxc|lxc-libvirt)
  1450. ;;
  1451. *)
  1452. mknod "$1/test-dev-null" c 1 3 || return 1
  1453. if ! echo test > "$1/test-dev-null"; then
  1454. rm -f "$1/test-dev-null"
  1455. return 1
  1456. fi
  1457. rm -f "$1/test-dev-null"
  1458. ;;
  1459. esac
  1460. fi
  1461. esac
  1462. SH="/bin/sh"
  1463. [ -x "$SH" ] || SH="$(which sh)"
  1464. cat > "$1/test-exec" <<EOF
  1465. #! $SH
  1466. :
  1467. EOF
  1468. chmod +x "$1/test-exec"
  1469. if ! "$1/test-exec"; then
  1470. rm -f "$1/test-exec"
  1471. return 1
  1472. fi
  1473. rm -f "$1/test-exec"
  1474. return 0
  1475. }
  1476. read_gpg_status () {
  1477. local badsig unkkey validsig
  1478. while read prefix keyword keyid rest; do
  1479. [ "$prefix" = '[GNUPG:]' ] || continue
  1480. case $keyword in
  1481. BADSIG) badsig="$keyid" ;;
  1482. NO_PUBKEY) unkkey="$keyid" ;;
  1483. VALIDSIG) validsig="$keyid" ;;
  1484. esac
  1485. done
  1486. if [ "$validsig" ]; then
  1487. info VALIDRELSIG "Valid Release signature (key id %s)" "$validsig"
  1488. elif [ "$badsig" ]; then
  1489. error 1 BADRELSIG "Invalid Release signature (key id %s)" "$badsig"
  1490. elif [ "$unkkey" ]; then
  1491. error 1 UNKNOWNRELSIG "Release signed by unknown key (key id %s)\n The specified keyring $KEYRING may be incorrect or out of date.\n You can find the latest Debian release key at https://ftp-master.debian.org/keys.html" "$unkkey"
  1492. else
  1493. error 1 SIGCHECK "Error executing gpgv to check Release signature"
  1494. fi
  1495. }
  1496. without () {
  1497. # usage: without "a b c" "a d" -> "b" "c"
  1498. (echo "$1" | tr ' ' '\n' | sort | uniq;
  1499. echo "$2" "$2" | tr ' ' '\n') | sort | uniq -u | tr '\n' ' '
  1500. echo
  1501. }
  1502. # Formerly called 'repeat', but that's a reserved word in zsh.
  1503. repeatn () {
  1504. local n="$1"
  1505. shift
  1506. while [ "$n" -gt 0 ]; do
  1507. if "$@"; then
  1508. break
  1509. else
  1510. n=$(( $n - 1 ))
  1511. sleep 1
  1512. fi
  1513. done
  1514. if [ "$n" -eq 0 ]; then return 1; fi
  1515. return 0
  1516. }
  1517. N_EXIT_THINGS=0
  1518. exit_function () {
  1519. local n=0
  1520. while [ "$n" -lt "$N_EXIT_THINGS" ]; do
  1521. (eval $(eval echo \${EXIT_THING_$n}) 2>/dev/null || true)
  1522. n=$(( $n + 1 ))
  1523. done
  1524. N_EXIT_THINGS=0
  1525. }
  1526. trap "exit_function" 0
  1527. trap "exit 129" 1
  1528. trap "error 130 INTERRUPTED \"Interrupt caught ... exiting\"" 2
  1529. trap "exit 131" 3
  1530. trap "exit 143" 15
  1531. on_exit () {
  1532. eval "$(echo EXIT_THING_${N_EXIT_THINGS}=\"$1\")"
  1533. N_EXIT_THINGS=$(( $N_EXIT_THINGS + 1 ))
  1534. }
  1535. ############################################################## fakechroot tools
  1536. install_fakechroot_tools () {
  1537. if [ "$VARIANT" = "fakechroot" ]; then
  1538. export PATH=/usr/sbin:/sbin:$PATH
  1539. fi
  1540. mv "$TARGET/sbin/ldconfig" "$TARGET/sbin/ldconfig.REAL"
  1541. echo \
  1542. "#!/bin/sh
  1543. echo
  1544. echo \"Warning: Fake ldconfig called, doing nothing\"" > "$TARGET/sbin/ldconfig"
  1545. chmod 755 "$TARGET/sbin/ldconfig"
  1546. echo \
  1547. "/sbin/ldconfig
  1548. /sbin/ldconfig.REAL
  1549. fakechroot" >> "$TARGET/var/lib/dpkg/diversions"
  1550. mv "$TARGET/usr/bin/ldd" "$TARGET/usr/bin/ldd.REAL"
  1551. cat << 'END' > "$TARGET/usr/bin/ldd"
  1552. #!/usr/bin/perl
  1553. # fakeldd
  1554. #
  1555. # Replacement for ldd with usage of objdump
  1556. #
  1557. # (c) 2003-2005 Piotr Roszatycki <dexter@debian.org>, BSD
  1558. my %libs = ();
  1559. my $status = 0;
  1560. my $dynamic = 0;
  1561. my $biarch = 0;
  1562. my $ldlinuxsodir = "/lib";
  1563. my @ld_library_path = qw(/usr/lib /lib);
  1564. sub ldso($) {
  1565. my ($lib) = @_;
  1566. my @files = ();
  1567. if ($lib =~ /^\//) {
  1568. $libs{$lib} = $lib;
  1569. push @files, $lib;
  1570. } else {
  1571. foreach my $ld_path (@ld_library_path) {
  1572. next unless -f "$ld_path/$lib";
  1573. my $badformat = 0;
  1574. open OBJDUMP, "objdump -p $ld_path/$lib 2>/dev/null |";
  1575. while (my $line = <OBJDUMP>) {
  1576. if ($line =~ /file format (\S*)$/) {
  1577. $badformat = 1 unless $format eq $1;
  1578. last;
  1579. }
  1580. }
  1581. close OBJDUMP;
  1582. next if $badformat;
  1583. $libs{$lib} = "$ld_path/$lib";
  1584. push @files, "$ld_path/$lib";
  1585. }
  1586. objdump(@files);
  1587. }
  1588. }
  1589. sub objdump(@) {
  1590. my (@files) = @_;
  1591. my @libs = ();
  1592. foreach my $file (@files) {
  1593. open OBJDUMP, "objdump -p $file 2>/dev/null |";
  1594. while (my $line = <OBJDUMP>) {
  1595. $line =~ s/^\s+//;
  1596. my @f = split (/\s+/, $line);
  1597. if ($line =~ /file format (\S*)$/) {
  1598. if (not $format) {
  1599. $format = $1;
  1600. if ($unamearch eq "x86_64" and $format eq "elf32-i386") {
  1601. my $link = readlink "/lib/ld-linux.so.2";
  1602. if ($link =~ /^\/emul\/ia32-linux\//) {
  1603. $ld_library_path[-2] = "/emul/ia32-linux/usr/lib";
  1604. $ld_library_path[-1] = "/emul/ia32-linux/lib";
  1605. }
  1606. } elsif ($unamearch =~ /^(sparc|sparc64)$/ and $format eq "elf64-sparc") {
  1607. $ldlinuxsodir = "/lib64";
  1608. $ld_library_path[-2] = "/usr/lib64";
  1609. $ld_library_path[-1] = "/lib64";
  1610. }
  1611. } else {
  1612. next unless $format eq $1;
  1613. }
  1614. }
  1615. if (not $dynamic and $f[0] eq "Dynamic") {
  1616. $dynamic = 1;
  1617. }
  1618. next unless $f[0] eq "NEEDED";
  1619. if ($f[1] =~ /^ld-linux(\.|-)/) {
  1620. $f[1] = "$ldlinuxsodir/" . $f[1];
  1621. }
  1622. if (not defined $libs{$f[1]}) {
  1623. $libs{$f[1]} = undef;
  1624. push @libs, $f[1];
  1625. }
  1626. }
  1627. close OBJDUMP;
  1628. }
  1629. foreach my $lib (@libs) {
  1630. ldso($lib);
  1631. }
  1632. }
  1633. if ($#ARGV < 0) {
  1634. print STDERR "fakeldd: missing file arguments\n";
  1635. exit 1;
  1636. }
  1637. while ($ARGV[0] =~ /^-/) {
  1638. my $arg = $ARGV[0];
  1639. shift @ARGV;
  1640. last if $arg eq "--";
  1641. }
  1642. open LD_SO_CONF, "/etc/ld.so.conf";
  1643. while ($line = <LD_SO_CONF>) {
  1644. chomp $line;
  1645. unshift @ld_library_path, $line;
  1646. }
  1647. close LD_SO_CONF;
  1648. unshift @ld_library_path, split(/:/, $ENV{LD_LIBRARY_PATH});
  1649. $unamearch = "$(/bin/uname -m)";
  1650. chomp $unamearch;
  1651. foreach my $file (@ARGV) {
  1652. my $address;
  1653. %libs = ();
  1654. $dynamic = 0;
  1655. if ($#ARGV > 0) {
  1656. print "$file:\n";
  1657. }
  1658. if (not -f $file) {
  1659. print STDERR "ldd: $file: No such file or directory\n";
  1660. $status = 1;
  1661. next;
  1662. }
  1663. objdump($file);
  1664. if ($dynamic == 0) {
  1665. print "\tnot a dynamic executable\n";
  1666. $status = 1;
  1667. } elsif (scalar %libs eq "0") {
  1668. print "\tstatically linked\n";
  1669. }
  1670. if ($format =~ /^elf64-/) {
  1671. $address = "0x0000000000000000";
  1672. } else {
  1673. $address = "0x00000000";
  1674. }
  1675. foreach $lib (keys %libs) {
  1676. if ($libs{$lib}) {
  1677. printf "\t%s => %s (%s)\n", $lib, $libs{$lib}, $address;
  1678. } else {
  1679. printf "\t%s => not found\n", $lib;
  1680. }
  1681. }
  1682. }
  1683. exit $status;
  1684. END
  1685. chmod 755 "$TARGET/usr/bin/ldd"
  1686. echo \
  1687. "/usr/bin/ldd
  1688. /usr/bin/ldd.REAL
  1689. fakechroot" >> "$TARGET/var/lib/dpkg/diversions"
  1690. }