]>
Commit | Line | Data |
---|---|---|
9efd10cd | 1 | #!/bin/bash |
fcac2376 AM |
2 | # |
3 | # bacman: recreate a package from a running system | |
4 | # This script rebuilds an already installed package using metadata | |
5 | # stored into the pacman database and system files | |
6 | # | |
7 | # (c) 2008 - locci <carlocci_at_gmail_dot_com> | |
8 | # | |
9 | # This program is free software; you can redistribute it and/or modify | |
10 | # it under the terms of the GNU General Public License as published by | |
11 | # the Free Software Foundation; either version 2 of the License, or | |
12 | # (at your option) any later version. | |
13 | # | |
14 | # This program is distributed in the hope that it will be useful, | |
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | # GNU General Public License for more details. | |
18 | # | |
19 | # You should have received a copy of the GNU General Public License | |
20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
21 | # | |
22 | ||
273cc66a | 23 | shopt -s extglob |
24 | shopt -s nullglob | |
25 | ||
fcac2376 | 26 | readonly progname="bacman" |
0199a7ee | 27 | readonly progver="0.2.1" |
fcac2376 AM |
28 | |
29 | # | |
30 | # User Friendliness | |
31 | # | |
7e5bbf03 | 32 | usage() { |
3f937c84 | 33 | echo "This program recreates a package using pacman's db and system files" |
34 | echo "Usage: $progname <installed package name>" | |
35 | echo "Example: $progname kernel26" | |
fcac2376 AM |
36 | } |
37 | ||
7e5bbf03 | 38 | if (( $# != 1 )); then |
3f937c84 | 39 | usage |
40 | exit 1 | |
fcac2376 AM |
41 | fi |
42 | ||
7e5bbf03 | 43 | if [[ $1 == "--help" || $1 == "-h" ]]; then |
3f937c84 | 44 | usage |
45 | exit 0 | |
fcac2376 AM |
46 | fi |
47 | ||
7e5bbf03 | 48 | if [[ $1 == "--version" || $1 == "-v" ]]; then |
3f937c84 | 49 | echo "$progname version $progver" |
50 | echo "Copyright (C) 2008 locci" | |
51 | exit 0 | |
fcac2376 AM |
52 | fi |
53 | ||
54 | # | |
55 | # Fakeroot support | |
56 | # | |
7e5bbf03 | 57 | if (( EUID )); then |
58 | if [[ -f /usr/bin/fakeroot ]]; then | |
3f937c84 | 59 | echo "Entering fakeroot environment" |
60 | export INFAKEROOT="1" | |
7e5bbf03 | 61 | /usr/bin/fakeroot -u -- "$0" "$@" |
3f937c84 | 62 | exit $? |
63 | else | |
64 | echo "WARNING: installing fakeroot or running ${progname} as root is required to" | |
65 | echo " preserve the ownership permissions of files in some packages" | |
66 | echo "" | |
67 | fi | |
fcac2376 AM |
68 | fi |
69 | ||
70 | # | |
71 | # Setting environmental variables | |
72 | # | |
7e5bbf03 | 73 | if [[ ! -r @sysconfdir@/pacman.conf ]]; then |
3f937c84 | 74 | echo "ERROR: unable to read @sysconfdir@/pacman.conf" |
75 | exit 1 | |
fcac2376 AM |
76 | fi |
77 | ||
05f0a289 N |
78 | eval $(awk '/DBPath/ {print $1$2$3}' @sysconfdir@/pacman.conf) |
79 | pac_db="${DBPath:-@localstatedir@/lib/pacman/}/local" | |
fcac2376 | 80 | |
7e5bbf03 | 81 | if [[ ! -r @sysconfdir@/makepkg.conf ]]; then |
3f937c84 | 82 | echo "ERROR: unable to read @sysconfdir@/makepkg.conf" |
83 | exit 1 | |
fcac2376 AM |
84 | fi |
85 | ||
05f0a289 | 86 | source "@sysconfdir@/makepkg.conf" |
7e5bbf03 | 87 | if [[ -r ~/.makepkg.conf ]]; then |
3f937c84 | 88 | source ~/.makepkg.conf |
fcac2376 AM |
89 | fi |
90 | ||
91 | pkg_arch=${CARCH:-'unknown'} | |
92 | pkg_dest="${PKGDEST:-$PWD}" | |
93 | pkg_pkger=${PACKAGER:-'Unknown Packager'} | |
94 | ||
95 | pkg_name="$1" | |
22abe27b | 96 | pkg_dir=("$pac_db/$pkg_name"-+([^-])-+([0-9])) |
97 | pkg_namver=("${pkg_dir[@]##*/}") | |
fcac2376 AM |
98 | |
99 | # | |
100 | # Checks everything is in place | |
101 | # | |
7e5bbf03 | 102 | if [[ ! -d $pac_db ]]; then |
3f937c84 | 103 | echo "ERROR: pacman database directory ${pac_db} not found" |
104 | exit 1 | |
fcac2376 AM |
105 | fi |
106 | ||
22abe27b | 107 | if (( ${#pkg_dir[@]} != 1 )); then |
108 | printf "ERROR: %d entries for package %s found in pacman database\n" \ | |
109 | ${#pkg_dir[@]} "${pkg_name}" | |
110 | printf "%s\n" "${pkg_dir[@]}" | |
111 | exit 1 | |
112 | fi | |
113 | ||
7e5bbf03 | 114 | if [[ ! -d $pkg_dir ]]; then |
22abe27b | 115 | printf "ERROR: package %s is found in pacman database,\n" "${pkg_name}" |
116 | printf " but \`%s' is not a directory\n" "${pkg_dir}" | |
3f937c84 | 117 | exit 1 |
fcac2376 AM |
118 | fi |
119 | ||
120 | # | |
121 | # Begin | |
122 | # | |
273cc66a | 123 | echo "Package: ${pkg_namver}" |
124 | work_dir=$(mktemp -d --tmpdir bacman.XXXXXXXXXX) | |
b15fb504 | 125 | cd "$work_dir" || exit 1 |
fcac2376 AM |
126 | |
127 | # | |
128 | # File copying | |
129 | # | |
130 | echo "Copying package files..." | |
131 | ||
132 | cat "$pkg_dir"/files | | |
133 | while read i; do | |
7e5bbf03 | 134 | if [[ -z $i ]]; then |
3f937c84 | 135 | continue |
136 | fi | |
137 | ||
273cc66a | 138 | if [[ $i == %+([A-Z])% ]]; then |
3f937c84 | 139 | current=$i |
140 | continue | |
141 | fi | |
142 | ||
273cc66a | 143 | case "$current" in |
3f937c84 | 144 | %FILES%) |
145 | ret=0 | |
7e5bbf03 | 146 | if [[ -e /$i ]]; then |
3f937c84 | 147 | bsdtar -cnf - "/$i" 2> /dev/null | bsdtar -xpf - |
148 | ||
149 | # Workaround to bsdtar not reporting a missing file as an error | |
7e5bbf03 | 150 | if ! [[ -e $work_dir/$i || -L $work_dir/$i ]]; then |
3f937c84 | 151 | echo "" |
152 | echo "ERROR: unable to add /$i to the package" | |
153 | echo " If your user does not have permssion to read this file then" | |
154 | echo " you will need to run $progname as root" | |
155 | rm -rf "$work_dir" | |
156 | exit 1 | |
157 | fi | |
158 | else | |
159 | echo "" | |
160 | echo "WARNING: package file /$i is missing" | |
161 | echo "" | |
162 | fi | |
163 | ;; | |
164 | esac | |
fcac2376 AM |
165 | done |
166 | ||
167 | ret=$? | |
7e5bbf03 | 168 | if (( ret )); then |
3f937c84 | 169 | rm -rf "$work_dir" |
170 | exit 1 | |
fcac2376 AM |
171 | fi |
172 | ||
173 | pkg_size=$(du -sk | awk '{print $1 * 1024}') | |
174 | ||
fcac2376 AM |
175 | # |
176 | # .PKGINFO stuff | |
273cc66a | 177 | # TODO adopt makepkg's write_pkginfo() into this or scripts/library |
fcac2376 AM |
178 | # |
179 | echo Generating .PKGINFO metadata... | |
180 | echo "# Generated by $progname $progver" > .PKGINFO | |
7e5bbf03 | 181 | if [[ $INFAKEROOT == "1" ]]; then |
3f937c84 | 182 | echo "# Using $(fakeroot -v)" >> .PKGINFO |
fcac2376 AM |
183 | fi |
184 | echo "# $(LC_ALL=C date)" >> .PKGINFO | |
185 | echo "#" >> .PKGINFO | |
186 | ||
31cb2100 | 187 | cat "$pkg_dir"/{desc,files} | |
fcac2376 | 188 | while read i; do |
273cc66a | 189 | if [[ -z $i ]]; then |
3f937c84 | 190 | continue; |
191 | fi | |
192 | ||
273cc66a | 193 | if [[ $i == %+([A-Z])% ]]; then |
3f937c84 | 194 | current=$i |
195 | continue | |
196 | fi | |
197 | ||
198 | case "$current" in | |
199 | # desc | |
200 | %NAME%) | |
201 | echo "pkgname = $i" >> .PKGINFO | |
202 | ;; | |
203 | %VERSION%) | |
204 | echo "pkgver = $i" >> .PKGINFO | |
205 | ;; | |
206 | %DESC%) | |
207 | echo "pkgdesc = $i" >> .PKGINFO | |
208 | ;; | |
209 | %URL%) | |
210 | echo "url = $i" >> .PKGINFO | |
211 | ;; | |
212 | %LICENSE%) | |
213 | echo "license = $i" >> .PKGINFO | |
214 | ;; | |
215 | %ARCH%) | |
216 | echo "arch = $i" >> .PKGINFO | |
217 | ;; | |
218 | %BUILDDATE%) | |
219 | echo "builddate = $(date -u "+%s")" >> .PKGINFO | |
220 | ;; | |
221 | %PACKAGER%) | |
222 | echo "packager = $pkg_pkger" >> .PKGINFO | |
223 | ;; | |
224 | %SIZE%) | |
225 | echo "size = $pkg_size" >> .PKGINFO | |
226 | ;; | |
227 | %GROUPS%) | |
228 | echo "group = $i" >> .PKGINFO | |
229 | ;; | |
230 | %REPLACES%) | |
231 | echo "replaces = $i" >> .PKGINFO | |
232 | ;; | |
233 | %DEPENDS%) | |
234 | echo "depend = $i" >> .PKGINFO | |
235 | ;; | |
236 | %OPTDEPENDS%) | |
237 | echo "optdepend = $i" >> .PKGINFO | |
238 | ;; | |
239 | %CONFLICTS%) | |
240 | echo "conflict = $i" >> .PKGINFO | |
241 | ;; | |
242 | %PROVIDES%) | |
243 | echo "provides = $i" >> .PKGINFO | |
244 | ;; | |
245 | ||
246 | # files | |
247 | %BACKUP%) | |
248 | # strip the md5sum after the tab | |
249 | echo "backup = ${i%%$'\t'*}" >> .PKGINFO | |
250 | ;; | |
251 | esac | |
fcac2376 AM |
252 | done |
253 | ||
fd383191 AM |
254 | comp_files=".PKGINFO" |
255 | ||
7e5bbf03 | 256 | if [[ -f $pkg_dir/install ]]; then |
3f937c84 | 257 | cp "$pkg_dir/install" "$work_dir/.INSTALL" |
258 | comp_files+=" .INSTALL" | |
fd383191 | 259 | fi |
7e5bbf03 | 260 | if [[ -f $pkg_dir/changelog ]]; then |
3f937c84 | 261 | cp "$pkg_dir/changelog" "$work_dir/.CHANGELOG" |
262 | comp_files+=" .CHANGELOG" | |
fd383191 AM |
263 | fi |
264 | ||
fcac2376 AM |
265 | # |
266 | # Fixes owner:group and permissions for .PKGINFO, .CHANGELOG, .INSTALL | |
267 | # | |
b15fb504 CB |
268 | chown root:root "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null |
269 | chmod 644 "$work_dir"/{.PKGINFO,.CHANGELOG,.INSTALL} 2> /dev/null | |
fcac2376 AM |
270 | |
271 | # | |
272 | # Generate the package | |
273 | # | |
274 | echo "Generating the package..." | |
275 | ||
fd383191 | 276 | pkg_file="$pkg_dest/$pkg_namver-$pkg_arch${PKGEXT}" |
fcac2376 | 277 | ret=0 |
fd383191 | 278 | |
fd383191 AM |
279 | # TODO: Maybe this can be set globally for robustness |
280 | shopt -s -o pipefail | |
281 | bsdtar -cf - $comp_files * | | |
282 | case "$PKGEXT" in | |
3f937c84 | 283 | *tar.gz) gzip -c -f -n ;; |
284 | *tar.bz2) bzip2 -c -f ;; | |
285 | *tar.xz) xz -c -z - ;; | |
4928f9ed | 286 | *tar.Z) compress -c -f ;; |
3f937c84 | 287 | *tar) cat ;; |
4928f9ed | 288 | *) echo "WARNING: '%s' is not a valid archive extension." \ |
289 | "$PKGEXT" >&2; cat ;; | |
273cc66a | 290 | esac > "${pkg_file}"; ret=$? |
fd383191 | 291 | |
7e5bbf03 | 292 | if (( ret )); then |
3f937c84 | 293 | echo "ERROR: unable to write package to $pkg_dest" |
294 | echo " Maybe the disk is full or you do not have write access" | |
295 | rm -rf "$work_dir" | |
296 | exit 1 | |
fcac2376 AM |
297 | fi |
298 | ||
b15fb504 | 299 | rm -rf "$work_dir" |
fcac2376 AM |
300 | |
301 | echo Done | |
302 | ||
303 | exit 0 | |
304 | ||
b15fb504 CB |
305 | # vim: set ts=2 sw=2 noet: |
306 |