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