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