ipkg-build 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #!/bin/sh
  2. # ipkg-build -- construct a .ipk from a directory
  3. # Carl Worth <[email protected]>
  4. # based on a script by Steve Redler IV, [email protected] 5-21-2001
  5. # 2003-04-25 [email protected]
  6. # Updated to work on Familiar Pre0.7rc1, with busybox tar.
  7. # Note it Requires: binutils-ar (since the busybox ar can't create)
  8. # For UID debugging it needs a better "find".
  9. set -e
  10. version=1.0
  11. FIND="$(command -v find)"
  12. FIND="${FIND:-$(command -v gfind)}"
  13. TAR="${TAR:-$(command -v tar)}"
  14. GZIP="$(command -v gzip)"
  15. # try to use fixed source epoch
  16. if [ -n "$PKG_SOURCE_DATE_EPOCH" ]; then
  17. TIMESTAMP=$(date --date="@$PKG_SOURCE_DATE_EPOCH")
  18. elif [ -n "$SOURCE_DATE_EPOCH" ]; then
  19. TIMESTAMP=$(date --date="@$SOURCE_DATE_EPOCH")
  20. else
  21. TIMESTAMP=$(date)
  22. fi
  23. ipkg_extract_value() {
  24. sed -e "s/^[^:]*:[[:space:]]*//"
  25. }
  26. required_field() {
  27. field=$1
  28. grep "^$field:" < $CONTROL/control | ipkg_extract_value
  29. }
  30. pkg_appears_sane() {
  31. local pkg_dir=$1
  32. local owd=$PWD
  33. cd $pkg_dir
  34. PKG_ERROR=0
  35. pkg=`required_field Package`
  36. version=`required_field Version | sed 's/Version://; s/^.://g;'`
  37. arch=`required_field Architecture`
  38. if echo $pkg | grep '[^a-zA-Z0-9_.+-]'; then
  39. echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
  40. PKG_ERROR=1;
  41. fi
  42. if [ -f $CONTROL/conffiles ]; then
  43. rm -f $CONTROL/conffiles.resolved
  44. for cf in `$FIND $(sed -e "s!^/!$pkg_dir/!" $CONTROL/conffiles) -type f`; do
  45. echo "${cf#$pkg_dir}" >> $CONTROL/conffiles.resolved
  46. done
  47. rm $CONTROL/conffiles
  48. if [ -f $CONTROL/conffiles.resolved ]; then
  49. mv $CONTROL/conffiles.resolved $CONTROL/conffiles
  50. chmod 0644 $CONTROL/conffiles
  51. fi
  52. fi
  53. cd $owd
  54. return $PKG_ERROR
  55. }
  56. resolve_file_mode_id() {
  57. local var=$1 type=$2 name=$3 id
  58. case "$name" in
  59. root)
  60. id=0
  61. ;;
  62. *[!0-9]*)
  63. id=$(sed -ne "s#^$type $name \\([0-9]\\+\\)\\b.*\$#\\1#p" "$TOPDIR/tmp/.packageusergroup" 2>/dev/null)
  64. ;;
  65. *)
  66. id=$name
  67. ;;
  68. esac
  69. export "$var=$id"
  70. [ -n "$id" ]
  71. }
  72. ###
  73. # ipkg-build "main"
  74. ###
  75. file_modes=""
  76. usage="Usage: $0 [-v] [-h] [-m] <pkg_directory> [<destination_directory>]"
  77. while getopts "hvm:" opt; do
  78. case $opt in
  79. v ) echo $version
  80. exit 0
  81. ;;
  82. h ) echo $usage >&2 ;;
  83. m ) file_modes=$OPTARG ;;
  84. \? ) echo $usage >&2
  85. esac
  86. done
  87. shift $(($OPTIND - 1))
  88. # continue on to process additional arguments
  89. case $# in
  90. 1)
  91. dest_dir=$PWD
  92. ;;
  93. 2)
  94. dest_dir=$2
  95. if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
  96. dest_dir=$PWD
  97. fi
  98. ;;
  99. *)
  100. echo $usage >&2
  101. exit 1
  102. ;;
  103. esac
  104. pkg_dir=$1
  105. if [ ! -d $pkg_dir ]; then
  106. echo "*** Error: Directory $pkg_dir does not exist" >&2
  107. exit 1
  108. fi
  109. # CONTROL is second so that it takes precedence
  110. CONTROL=
  111. [ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
  112. if [ -z "$CONTROL" ]; then
  113. echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
  114. exit 1
  115. fi
  116. if ! pkg_appears_sane $pkg_dir; then
  117. echo >&2
  118. echo "ipkg-build: Please fix the above errors and try again." >&2
  119. exit 1
  120. fi
  121. tmp_dir=$dest_dir/IPKG_BUILD.$$
  122. mkdir $tmp_dir
  123. echo $CONTROL > $tmp_dir/tarX
  124. cd $pkg_dir
  125. for file_mode in $file_modes; do
  126. case $file_mode in
  127. /*:*:*:*)
  128. ;;
  129. *)
  130. echo "ERROR: file modes must use absolute path and contain user:group:mode"
  131. echo "$file_mode"
  132. exit 1
  133. ;;
  134. esac
  135. mode=${file_mode##*:}; path=${file_mode%:*}
  136. group=${path##*:}; path=${path%:*}
  137. user=${path##*:}; path=${path%:*}
  138. if ! resolve_file_mode_id uid user "$user"; then
  139. echo "ERROR: unable to resolve uid of $user" >&2
  140. exit 1
  141. fi
  142. if ! resolve_file_mode_id gid group "$group"; then
  143. echo "ERROR: unable to resolve gid of $group" >&2
  144. exit 1
  145. fi
  146. chown "$uid:$gid" "$pkg_dir/$path"
  147. chmod "$mode" "$pkg_dir/$path"
  148. done
  149. $TAR -X $tmp_dir/tarX --format=gnu --sort=name -cpf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/data.tar.gz
  150. installed_size=`stat -c "%s" $tmp_dir/data.tar.gz`
  151. sed -i -e "s/^Installed-Size: .*/Installed-Size: $installed_size/" \
  152. $pkg_dir/$CONTROL/control
  153. ( cd $pkg_dir/$CONTROL && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" . | $GZIP -n - > $tmp_dir/control.tar.gz )
  154. rm $tmp_dir/tarX
  155. echo "2.0" > $tmp_dir/debian-binary
  156. pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
  157. rm -f $pkg_file
  158. ( cd $tmp_dir && $TAR --format=gnu --sort=name -cf - --mtime="$TIMESTAMP" ./debian-binary ./data.tar.gz ./control.tar.gz | $GZIP -n - > $pkg_file )
  159. rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
  160. rmdir $tmp_dir
  161. echo "Packaged contents of $pkg_dir into $pkg_file"