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