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