tazpkg view modules/install @ rev 945

modules/install: equivalent_pkg(): fix for --cookmode and --local
author Aleksej Bobylev <al.bobylev@gmail.com>
date Fri May 26 16:18:57 2017 +0300 (2017-05-26)
parents 50421cb50644
children dbf40347342a
line source
1 #!/bin/sh
2 # TazPkg - Tiny autonomous zone packages manager, hg.slitaz.org/tazpkg
3 # install - TazPkg module
4 # Install packages
7 # Connect function libraries
8 . /lib/libtaz.sh
9 . /usr/lib/slitaz/libpkg.sh
12 # Get TazPkg working environment
13 . @@MODULES@@/getenv
14 # $CACHE_DIR will change, it based on unchanged value of $SAVE_CACHE_DIR
15 SAVE_CACHE_DIR="$CACHE_DIR"
18 . @@MODULES@@/find-depends
23 # Log TazPkg activity
25 log_pkg() {
26 debug "\nlog_pkg('$1')\n PACKAGE='$PACKAGE'\n VERSION='$VERSION'\n EXTRAVERSION='$EXTRAVERSION'"
28 local extra
30 [ "$1" == 'Installed' ] && \
31 extra=" - $(fgrep " $PACKAGE-$VERSION" "$PKGS_DB/installed.$SUM" | awk '{print $1}')"
32 debug " extra='$extra'"
34 [ -w "$LOG" ] &&
35 echo "$(date +'%F %T') - $1 - $PACKAGE ($VERSION$EXTRAVERSION)$extra" >> $LOG
36 }
39 # get an already installed package from packages.equiv
41 equivalent_pkg() {
42 # input: $1 = dependency package name (like "nano");
43 # $2 = package path/name for which dependency tested
44 local i rep rules rule out
46 if [ -n "$local" ]; then
47 # Search for virtual packages
48 if [ -n "$cookmode" ]; then
49 pi='/home/slitaz/packages/packages.info'
50 else
51 pi="$(dirname "$2")/packages.info"
52 fi
53 [ -f "$pi" ] &&
54 out=$(awk -F$'\t' -vpkg="$1" '{
55 # if package name or provided package name matched
56 if ($1 == pkg || index(" " $10 " ", " " pkg " ")) { print $1 }
57 }' "$pi")
58 for i in $out; do
59 # If package installed
60 [ -f "$PKGS_DB/installed/$i/receipt" ] && out="$i" && break
61 unset out
62 done
63 else
64 rules=$(for rep in $PRIORITY; do
65 grep -hs "^$1=" "$rep/packages.equiv"
66 done | sed "s|^$1=||")
67 debug " >rules='$rules'"
69 for rule in $rules; do
70 debug " >rule='$rule'"
71 case $rule in
72 *:*)
73 debug '-- x:x'
74 # format 'alternative:newname'
75 # if alternative is installed then substitute newname
76 out="${rule#*:}"
77 awk -F$'\t' -vp="${rule%:*}" '$1==p{exit 1}' "$PKGS_DB/installed.info" || break
78 debug '-- x:x /'
79 ;;
80 *)
81 debug '-- x'
82 # unconditional substitution
83 out="$rule"
84 awk -F$'\t' -vp="$rule" '$1==p{exit 1}' "$PKGS_DB/installed.info" || break
85 debug '-- x /'
86 ;;
87 esac
88 unset out
89 done
90 fi
91 debug '--'
92 # if not found in packages.equiv then no substitution
93 echo "${out:-$1}"
94 }
97 # Check and install all missing deps.
98 # Auto install or ask user then install all missing deps from local dir, CD-ROM,
99 # media or from the mirror.
101 install_all_deps() {
102 # input: $1 = package file to check/install missing dependencies
103 # ROOT READY
104 # dep: equivalent_pkg.
106 debug "\ninstall_all_deps('$1')"
108 local TMP_DIR DEPENDS num missing_packages equiv pkg answer dir found pkgfile
110 # Check for missing deps listed in a receipt packages.
112 # Get the receipt's variable DEPENDS
113 DEPENDS=$(
114 TMP_DIR=$(mktemp -d); cd "$TMP_DIR"
115 cpio --quiet -i receipt >/dev/null 2>&1
116 . receipt; echo $DEPENDS
117 rm -rf "$TMP_DIR"
118 ) < "$1"
120 unset num missing_packages
121 for depend in $DEPENDS; do
122 debug " depend='$depend'"
123 equiv=$(equivalent_pkg $depend "$1")
124 debug " equiv='$equiv'\n"
125 if [ ! -d "$INSTALLED/$equiv" ]; then
126 missing_packages="$missing_packages $equiv"
127 num=$((num+1))
128 elif [ ! -f "$INSTALLED/$equiv/receipt" ]; then
129 [ -z "$quiet" ] && _ 'WARNING! Dependency loop between "%s" and "%s".' "$PACKAGE" "$equiv"
130 fi
131 done
133 # Nothing to install, exit function
134 [ -z "$num" ] && return
137 title "$(_ 'Tracking dependencies for package "%s"' "$PACKAGE")"
139 # Individual messages for each missing package
140 [ -z "$quiet" ] && \
141 for pkg in $missing_packages; do
142 _ 'Missing package "%s"' "$pkg"
143 done
145 footer "$(_p \
146 '%s missing package to install.' \
147 '%s missing packages to install.' "$num" \
148 "$num")"
151 if [ "$AUTO_INSTALL_DEPS" == 'yes' ] || [ -n "$quiet" ]; then
152 # Quietly not displaying anything. Assume 'yes' unless '--noconfirm' is provided
153 answer=0
154 [ -n "$noconfirm" ] && answer=1
155 else
156 # Display question; wait for answer or print auto-answer
157 newline
158 confirm "$(_ 'Install all missing dependencies? (y/N)')"
159 answer=$?
160 newline
161 fi
162 debug " answer='$answer'"
164 dir="$(dirname "$1")"
165 debug " dir='$dir'"
167 # We can install packages from /home/boot/packages at boot time
168 # Also we can prefer local packages over mirrored/cached using '--local' option
169 [ "$dir" == '/home/boot/packages' ] && local='yes'
170 debug " local='$local'"
172 # "--nodeps" option prevents to install dependencies
173 if [ "$answer" -eq 0 -a -z "$nodeps" ]; then
174 debug " let's install missing packages"
175 for pkg in $missing_packages; do
176 debug " pkg='$pkg'"
177 [ -d "$INSTALLED/$pkg" ] && continue
178 # Package not installed
180 found='0'; namever=''; pkgfile=''
181 # Prefer local packages
182 if [ -n "$local" ]; then
183 [ -z "$quiet" ] && _ 'Checking if package "%s" exists in local list...' "$pkg"
184 # Find local package
185 if [ -f "$dir/packages.info" ]; then
186 # Packages database exists (should be everfresh!)
187 namever=$(awk -F$'\t' -vpkg="$pkg" '{
188 # if package name or provided package name matched
189 if (index(" " $1 " " $10 " ", " " pkg " ")) { printf("%s-%s", $1, $2); exit; }
190 }' "$dir/packages.info") # <namever> = <package_name>-<package_version>
191 # Package file may be in form <namever>.tazpkg or <namever>-<arch>.tazpkg, so find one
192 [ -n "$namever" ] && pkgfile=$(find "$dir" -name "$namever*.tazpkg")
193 [ -n "$pkgfile" ] && found='1'
194 else
195 # Packages DB missing, proceed to sniff packages
196 tempd="$(mktemp -d)"; cd "$tempd"
197 for pkgfile in $dir/$pkg-*.tazpkg; do
198 [ -e "$pkgfile" ] || continue
199 # Extract receipt from each matched package
200 cpio -F "$pkgfile" -i receipt >/dev/null 2>&1
201 name=$(. receipt; echo $PACKAGE)
202 [ "$name" == "$pkg" ] && found='1' && break
203 # Install the first matched package: normally there is only one package
204 # with the $PACKAGE matched in the receipt
205 rm receipt
206 done
207 rm -r "$tempd"
208 fi
209 fi
210 debug " found='$found'"
212 if [ "$found" -eq 1 ]
213 then tazpkg install "$pkgfile"
214 else tazpkg get-install "$pkg"
215 fi
216 done
217 else
218 # Answered 'No' to install dependencies, or '--nodeps' option given
219 newline
220 _ 'Leaving dependencies for package "%s" unresolved.' "$PACKAGE"
221 _ 'The package will be installed but will probably not work.'
222 newline
223 fi
224 }
227 # Extract a package with cpio and gzip/lzma.
229 extract_package() {
230 # input: $1 - path to package to be extracted; package should be in the current dir
231 # ROOT INDEPENDENT
232 action 'Extracting package...'
234 # Extract "outer layer": cpio; remove the original package file
235 cpio -idm --quiet < "$1" && rm -f "$1"
237 # "Inner layer" may vary
238 if [ -f fs.cpio.lzma ]; then
239 # "Plain" cpio.lzma
240 unlzma < fs.cpio.lzma | cpio -idm --quiet && rm fs.cpio.lzma
241 elif [ -f fs.cpio.gz ]; then
242 # "Fast" cpio.gz (used to pack-then-install process in most of get-packages)
243 zcat fs.cpio.gz | cpio -idm --quiet && rm fs.cpio.gz
244 fi
246 status
247 }
250 # Print short package description
252 print_short_description() {
253 # TODO: undigest repo support? priority...
254 # ROOT READY
255 local short_desc=''
257 # Try to find localized short description
258 for LC in $LANG ${LANG%_*}; do
259 [ -e "$PKGS_DB/packages-desc.$LC" ] &&
260 short_desc=$(awk -F$'\t' -vp="$1" '$1==p{print $2; exit}' "$PKGS_DB/packages-desc.$LC")
261 done
263 # Try to find short description for mirrored package
264 [ -z "$short_desc" -a -s "$PKGS_DB/packages.info" ] &&
265 short_desc=$(awk -F$'\t' -vp="$1" '$1==p{print $4; exit}' "$PKGS_DB/packages.info")
267 [ -z "$short_desc" ] && short_desc="$SHORT_DESC"
269 longline "$short_desc"
270 }
273 grepesc() {
274 sed 's/\[/\\[/g'
275 }
280 #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*
282 # Block of receipt function callers
283 # Why? "Bad" receipt sourcing can redefine some vital TazPkg variables.
284 # Few receipts functions should be patched now.
286 # Input: $1 = path to the receipt to be processed
288 # Pre-install commands
289 call_pre_install() {
290 local tmp
291 if grep -q '^pre_install()' "$1"; then
292 action 'Execute pre-install commands...'
293 tmp="$(mktemp)"
294 cp "$1" "$tmp"
295 sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
296 ( . "$tmp"; pre_install "$root" )
297 status
298 rm "$tmp"
299 fi
301 }
302 # Post-install commands
303 call_post_install() {
304 local tmp
305 if grep -q '^post_install()' "$1"; then
306 action 'Execute post-install commands...'
307 tmp="$(mktemp)"
308 cp "$1" "$tmp"
309 sed -i 's|$1/*$INSTALLED|$INSTALLED|g' "$tmp"
310 ( . "$tmp"; post_install "$root" )
311 status
312 rm "$tmp"
313 fi
314 }
317 #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*
320 # This function installs a package in the rootfs.
322 install_package() {
323 # input: $1 = path to package to be installed
324 # dep: install_all_deps, print_short_description, extract_package, grepesc.
326 debug "\ninstall_package('$1')"
327 local dir
329 PACKAGE_FILE="$1"
330 TMP_DIR="$(mktemp -d)"
332 # Get receipt's variables and functions
333 { cd "$TMP_DIR"; cpio --quiet -i receipt >/dev/null 2>&1; } < "$PACKAGE_FILE"
334 # Why next code? "Bad" receipt sourcing can redefine some vital TazPkg variables.
335 (
336 . "$TMP_DIR/receipt"
337 cat > "$TMP_DIR/receipt.var" <<EOT
338 PACKAGE="$PACKAGE"
339 VERSION="$VERSION"
340 EXTRAVERSION="$EXTRAVERSION"
341 CATEGORY="$CATEGORY"
342 SHORT_DESC="${SHORT_DESC//\"/\"}"
343 WEB_SITE="$WEB_SITE"
344 TAGS="$TAGS"
345 DEPENDS="$DEPENDS"
346 CONFIG_FILES="$CONFIG_FILES"
347 PACKED_SIZE="$PACKED_SIZE"
348 UNPACKED_SIZE="$UNPACKED_SIZE"
349 EOT
350 rm "$TMP_DIR/receipt"
351 )
352 . "$TMP_DIR/receipt.var"
355 # Make sure folder exists on new installs or upgrades
356 mkdir -p "$INSTALLED/$PACKAGE"
358 # Keep "modifiers" and "files.list" on upgrade
359 find "$INSTALLED/$PACKAGE" -type f \( ! -name modifiers ! -name files.list \) -delete
361 # Update "installed.md5"
362 # TODO: discontinue using 'installed.md5'
363 touch "$PKGS_DB/installed.$SUM"
364 sed -i "/ $(basename "$PACKAGE_FILE")$/d" "$PKGS_DB/installed.$SUM" 2>/dev/null
365 cd "$(dirname "$PACKAGE_FILE")"
366 $CHECKSUM "$(basename "$PACKAGE_FILE")" >> "$PKGS_DB/installed.$SUM"
368 # Resolve package dependencies before package installation
369 install_all_deps "$PACKAGE_FILE"
372 # TODO: why this list-processed in the $PKGS_DB?
373 #[ -n "$INSTALL_LIST" ] && echo "$PACKAGE_FILE" >> "$PKGS_DB/$INSTALL_LIST-processed"
375 # Special mode for using in cookutils: clearly show whether freshly used package or cached one
376 if [ -n "$cookmode" ]; then
377 f=${PACKAGE_FILE%/*}; f=${f%/*}; f=${f##*/}
378 if [ "$f" == "$(cat /etc/slitaz-release)" ]; then
379 _ 'Installing (web/cache): %s' "$(basename $PACKAGE_FILE .tazpkg)"
380 else
381 _ 'Installing (pkg/local): %s' "$(basename $PACKAGE_FILE .tazpkg)"
382 fi
383 fi
385 if [ -n "$sequence" ]; then
386 title 'Installation of package "%s" (%s)' "$PACKAGE" "$sequence"
387 else
388 title 'Installation of package "%s"' "$PACKAGE"
389 fi
391 if [ -z "$quiet" ]; then
392 print_short_description "$PACKAGE"
393 separator '-'
394 fi
396 action 'Copying package...'
397 cp "$PACKAGE_FILE" "$TMP_DIR"
398 status
400 cd "$TMP_DIR"
401 extract_package "$(basename "$PACKAGE_FILE")"
403 # Include temporary receipt to get the right variables
404 . "$TMP_DIR/receipt.var"
406 cd "$INSTALLED"
409 # Get files to remove if upgrading
410 # IFS here modified temporarily for processing filenames with spaces
411 IFS=$'\n'
412 if [ -f "$PACKAGE/files.list" ]; then
413 while read file; do
414 grep -q "^$(echo "$file" | grepesc)$" "$TMP_DIR/files.list" && continue
415 for i in $(cat "$PACKAGE/modifiers" 2>/dev/null;
416 fgrep -sl "$PACKAGE" */modifiers | cut -d/ -f1); do
417 grep -qs "^$(echo "$file" | grepesc)$" "$i/files.list" && continue 2
418 done
419 echo "$file"
420 done < "$PACKAGE/files.list" > "$TMP_DIR/files2remove.list"
421 fi
422 unset IFS
425 # Remember modified packages
426 action 'Remember modified packages...'
427 {
428 check=false
429 # TODO: why '[' the special?
430 # FIXME: we have files with spaces in our packages!
431 for i in $(fgrep -v [ $TMP_DIR/files.list); do
432 [ -e "$root$i" ] || continue
433 [ -d "$root$i" ] && continue
434 echo "- $i"
435 check=true
436 done ;
437 $check && \
438 for i in *; do
439 [ "$i" == "$PACKAGE" ] && continue
440 [ -s "$i/files.list" ] || continue
441 awk "{ printf \"$i %s\\n\",\$1 }" < "$i/files.list"
442 done;
443 } | awk '
444 {
445 if ($1 == "-" || file[$2] != "") {
446 file[$2] = file[$2] " " $1
447 if ($1 != "-") {
448 if (pkg[$1] == "") all = all " " $1
449 pkg[$1] = pkg[$1] " " $2
450 }
451 }
452 }
453 END {
454 for (i = split(all, p, " "); i > 0; i--)
455 for (j = split(pkg[p[i]], f, " "); j > 0; j--)
456 printf "%s %s\n",p[i],f[j];
457 }
458 ' | while read dir file; do
459 if grep -qs "^$dir$" "$PACKAGE/modifiers"; then
460 # Do not overload an overloaded file !
461 rm "$TMP_DIR/$file" 2>/dev/null
462 continue
463 fi
464 grep -qs "^$PACKAGE$" "$dir/modifiers" && continue
465 if [ -s "$dir/volatile.cpio.gz" ]; then
466 # We can modify backed up files without notice
467 zcat "$dir/volatile.cpio.gz" | cpio -t --quiet | \
468 grep -q "^${file#/}$" && continue
469 fi
470 echo "$PACKAGE" >> "$dir/modifiers"
471 done
472 status
475 cd "$TMP_DIR"
476 # Copy receipt, etc.
477 for file in receipt files.list description.txt $CHECKSUM; do
478 [ -f "$file" ] && cp "$file" "$INSTALLED/$PACKAGE"
479 done
482 # Pre-install commands
483 call_pre_install "$INSTALLED/$PACKAGE/receipt"
486 if [ -n "$CONFIG_FILES" ]; then
487 # Save "official" configuration files
488 action 'Saving configuration files...'
489 debug "\n"
491 cd fs
492 local config_file
493 for config_file in $CONFIG_FILES; do
494 debug " config_file: '$config_file'"
495 find ${config_file#/} -type f 2>/dev/null
496 done | cpio -o -H newc --quiet | gzip -9 > "$INSTALLED/$PACKAGE/volatile.cpio.gz"
497 cd ..
499 if [ -z "$newconf" ]; then
500 debug " no '--newconf': clean official config files"
501 # Keep user configuration files: remove "official" from fs tree
502 for config_file in $CONFIG_FILES; do
503 for config_file_official in $(find "fs$config_file" ! -type d 2>/dev/null | sed 's|^fs||'); do
504 if [ -e "$root$config_file_official" ]; then
505 debug " official '$config_file_official' will be skipped"
506 rm "fs$config_file_official"
507 else
508 debug " official '$config_file_official' will be written"
509 fi
510 done
511 done
512 fi
513 # always '[ Done ]' status, unless '--newconf' is passed or not
514 :; status
515 fi
518 if [ -n "$(ls fs/* 2>/dev/null)" ]; then
519 action 'Installing package...'
521 debug '\n resolving destination links in source'
522 IFS=$'\n'
523 for dir in $(find fs -type d | sed 's|^fs||;/^$/d'); do
524 if ldir=$(readlink -n $root$dir); then
525 debug " * mv 'fs$dir'\n -> 'fs${dir%/*}/$ldir'"
526 mkdir -p "fs${dir%/*}/${ldir%/*}"
527 mv "fs$dir" "fs${dir%/*}/$ldir"
528 fi
529 done
530 unset IFS
532 debug ' copying folders and files to destination'
533 cp -af fs/* "$root/"
534 status
535 fi
538 if [ -s files2remove.list ]; then
539 action 'Removing old files...'
540 while read file; do
541 dir="$root$file"
542 # Remove specified file
543 rm -f "$dir"
544 # Recursive remove non-empty up-dirs
545 while [ "$dir" != "$root/" ]; do
546 dir=$(dirname "$dir")
547 rmdir "$dir" 2>/dev/null || break
548 done
549 done < files2remove.list
550 :; status
551 fi
554 # Remove the temporary random directory.
555 action "Removing all tmp files..."
556 cd ..; rm -rf "$TMP_DIR"
557 status
560 # Post install commands
561 call_post_install "$INSTALLED/$PACKAGE/receipt"
566 # Update system databases
567 # Updating DBs is important process, so not to hide such errors (localized):
568 # chroot: can't execute '/usr/bin/***': No such file or directory
570 local fl="$INSTALLED/$PACKAGE/files.list" upd=0 udesk umime uicon uschm ukrnl ukrnlfs
572 fgrep /usr/share/applications/ "$fl" | fgrep -q .desktop && udesk='yes'
573 fgrep -q /usr/share/mime "$fl" && umime='yes'
574 fgrep -q /usr/share/icon/hicolor "$fl" && uicon='yes'
575 fgrep /usr/share/glib-2.0/schemas "$fl" | fgrep -q .xml && uschm='yes'
576 fgrep /usr/lib/gdk-pixbuf "$fl" | fgrep -q .so && upixb='yes'
577 if fgrep -q /lib/modules "$fl"; then
578 ukrnl='yes'
579 if fgrep -q /kernel/fs/ "$fl"; then
580 ukrnlfs='yes'
581 fi
582 fi
584 if [ -n "$udesk$umime$uicon$uschm$upixb$ukrnl" ]; then
585 action 'Update system databases...'
586 upd=1
587 fi
589 # package 'desktop-file-utils'
590 [ -n "$udesk" ] && chroot "$root/" /usr/bin/update-desktop-database /usr/share/applications 2>/dev/null
591 # package 'shared-mime-info'
592 [ -n "$umime" ] && chroot "$root/" /usr/bin/update-mime-database /usr/share/mime
593 # packages 'gtk+', 'gtk+3'
594 [ -n "$uicon" ] && chroot "$root/" /usr/bin/gtk-update-icon-cache /usr/share/icons/hicolor
595 # package 'glib'
596 # hide messages like next because they are unresolved (we may to patch glib to hide them, almost the same)
597 # warning: Schema '*' has path '*'. Paths starting with '/apps/', '/desktop/' or '/system/' are deprecated.
598 [ -n "$uschm" ] && chroot "$root/" /usr/bin/glib-compile-schemas /usr/share/glib-2.0/schemas 2>&1 | fgrep -v '/apps/'
599 # package 'gdk-pixbuf'
600 [ -n "$upixb" ] && chroot "$root/" /usr/bin/gdk-pixbuf-query-loaders --update-cache
602 if [ -n "$ukrnlfs" ]; then
603 for i in $(awk -F/ '{if($6=="fs" && $8~$7)print $7}' "$fl" | sort -u); do
604 touch "$root/etc/filesystems"
605 grep -q "^$i\$" "$root/etc/filesystems" || echo "$i" >> "$root/etc/filesystems"
606 done
607 fi
608 # packages 'busybox', 'kmod', 'depmod'
609 [ -n "$ukrnl" ] && grep '/lib/modules' "$fl" | cut -d'/' -f4 | uniq | xargs chroot "$root/" /sbin/depmod -a
611 [ "$upd" -eq 1 ] && status
616 # Update installed.info
617 SIZES=$(echo $PACKED_SIZE $UNPACKED_SIZE | sed 's|\.0||g')
618 # Remove newlines from some receipts
619 DEPENDS=$(echo $DEPENDS)
620 PKG_SUM="$(fgrep " $PACKAGE-$VERSION$EXTRAVERSION.tazpkg" "$PKGS_DB/installed.$SUM" | cut -d' ' -f1)"
621 ii="$PKGS_DB/installed.info"
622 # Remove old entry
623 sed -i "/^$PACKAGE /d" "$ii"
624 cat >> "$ii" <<EOT
625 $PACKAGE $VERSION$EXTRAVERSION $CATEGORY $SHORT_DESC $WEB_SITE $TAGS $SIZES $DEPENDS $PKG_SUM
626 EOT
627 #awk -F$'\t' -vp="$PACKAGE" '$1==p' "$PKGS_DB/packages.info" > $ii
628 TEMP_FILE="$(mktemp)"
629 sort "$ii" > "$TEMP_FILE"; mv -f "$TEMP_FILE" "$ii"; chmod a+r "$ii"; unset ii
631 cd "$CUR_DIR"
632 footer "$(_ 'Package "%s" (%s) is installed.' "$PACKAGE" "$VERSION$EXTRAVERSION")"
634 # Log this activity
635 log_pkg Installed
637 # Remove package from upgrade list
638 [ -s "$UP_LIST" ] && sed -i "/^$PACKAGE\$/d" "$UP_LIST"
639 }
644 #*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*
647 PACKAGE=$(
648 tmp_dir=$(mktemp -d); cd "$tmp_dir"
649 cpio --quiet -i receipt >/dev/null 2>&1
650 . receipt; echo $PACKAGE
651 rm -rf "$tmp_dir"
652 ) < "$1"
654 if grep -qs "^$PACKAGE$" "$BLOCKED"; then
655 _ 'Package "%s" blocked.' "$PACKAGE"
656 exit 1
657 fi
659 if [ -z "$forced" ]; then
660 # Check if a package is already installed
661 debug "\ncheck for installed package '$PACKAGE'"
663 awk -F$'\t' -vpv="$PACKAGE" '$1==pv { exit 1 }' "$PKGS_DB/installed.info"
665 if [ "$?" -eq 1 ]; then
666 if [ -z "$quiet" ]; then
667 newline
668 _ '"%s" package is already installed.' "$(colorize 34 "$PACKAGE")"
669 longline "$(_ 'You can use the --forced option to force installation.')"
670 newline
671 fi
672 exit 1
673 fi
674 fi
676 install_package "$(realpath "$1")"