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