rpm2cpio.sh 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/bin/sh -efu
  2. # This file comes from rpm 4.x distribution
  3. fatal() {
  4. echo "$*" >&2
  5. exit 1
  6. }
  7. pkg="$1"
  8. [ -n "$pkg" ] && [ -e "$pkg" ] ||
  9. fatal "No package supplied"
  10. _dd() {
  11. local o="$1"; shift
  12. dd if="$pkg" skip="$o" iflag=skip_bytes status=none $*
  13. }
  14. calcsize() {
  15. case "$(_dd $1 bs=4 count=1 | tr -d '\0')" in
  16. "$(printf '\216\255\350')"*) ;; # '\x8e\xad\xe8'
  17. *) fatal "File doesn't look like rpm: $pkg" ;;
  18. esac
  19. offset=$(($1 + 8))
  20. local i b b0 b1 b2 b3 b4 b5 b6 b7
  21. i=0
  22. while [ $i -lt 8 ]; do
  23. # add . to not loose \n
  24. # strip \0 as it gets dropped with warning otherwise
  25. b="$(_dd $(($offset + $i)) bs=1 count=1 | tr -d '\0' ; echo .)"
  26. b=${b%.} # strip . again
  27. [ -z "$b" ] &&
  28. b="0" ||
  29. b="$(exec printf '%u\n' "'$b")"
  30. eval "b$i=\$b"
  31. i=$(($i + 1))
  32. done
  33. rsize=$((8 + ((($b0 << 24) + ($b1 << 16) + ($b2 << 8) + $b3) << 4) + ($b4 << 24) + ($b5 << 16) + ($b6 << 8) + $b7))
  34. offset=$(($offset + $rsize))
  35. }
  36. case "$(_dd 0 bs=4 count=1 | tr -d '\0')" in
  37. "$(printf '\355\253\356\333')"*) ;; # '\xed\xab\xee\xdb'
  38. *) fatal "File doesn't look like rpm: $pkg" ;;
  39. esac
  40. calcsize 96
  41. sigsize=$rsize
  42. calcsize $(($offset + (8 - ($sigsize % 8)) % 8))
  43. hdrsize=$rsize
  44. case "$(_dd $offset bs=2 count=1 | tr -d '\0')" in
  45. "$(printf '\102\132')") _dd $offset | bunzip2 ;; # '\x42\x5a'
  46. "$(printf '\037\213')") _dd $offset | gunzip ;; # '\x1f\x8b'
  47. "$(printf '\375\067')") _dd $offset | xzcat ;; # '\xfd\x37'
  48. "$(printf '\135')") _dd $offset | unlzma ;; # '\x5d\x00'
  49. "$(printf '\050\265')") _dd $offset | unzstd ;; # '\x28\xb5'
  50. *) fatal "Unrecognized payload compression format in rpm file: $pkg" ;;
  51. esac