| |
1 #!@l_prefix@/lib/openpkg/bash |
| |
2 ## |
| |
3 ## rpmdb -- OpenPKG RPM Database Administration Utility |
| |
4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/> |
| |
5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/> |
| |
6 ## |
| |
7 ## Permission to use, copy, modify, and distribute this software for |
| |
8 ## any purpose with or without fee is hereby granted, provided that |
| |
9 ## the above copyright notice and this permission notice appear in all |
| |
10 ## copies. |
| |
11 ## |
| |
12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| |
13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| |
14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| |
15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
| |
16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| |
17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| |
18 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| |
19 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| |
20 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| |
21 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| |
22 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| |
23 ## SUCH DAMAGE. |
| |
24 ## |
| |
25 |
| |
26 # program information |
| |
27 progname="rpmdb" |
| |
28 |
| |
29 # configuration defaults |
| |
30 help="" |
| |
31 prefix="@l_prefix@" |
| |
32 dbpath="" |
| |
33 rpm="" |
| |
34 musr="@l_musr@" |
| |
35 mgrp="@l_mgrp@" |
| |
36 mode="" |
| |
37 force=no |
| |
38 verbose=2 |
| |
39 |
| |
40 ## |
| |
41 ## PARSE COMMAND LINE |
| |
42 ## |
| |
43 |
| |
44 # iterate over argument line |
| |
45 for opt |
| |
46 do |
| |
47 case $opt in |
| |
48 -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;; |
| |
49 *) arg='' ;; |
| |
50 esac |
| |
51 case $opt in |
| |
52 -h|--help ) help="Usage" ;; |
| |
53 -B|--build ) mode=build ;; |
| |
54 -R|--rebuild ) mode=rebuild ;; |
| |
55 -C|--cleanup ) mode=cleanup ;; |
| |
56 -F|--fixate ) mode=fixate ;; |
| |
57 -L|--list ) mode=list ;; |
| |
58 -f|--force ) force=yes ;; |
| |
59 -q|--quiet ) verbose=0 ;; |
| |
60 -v|--verbose ) verbose=`expr $verbose + 1` ;; |
| |
61 --prefix=* ) prefix=$arg ;; |
| |
62 --dbpath=* ) dbpath=$arg ;; |
| |
63 --rpm=* ) rpm=$arg ;; |
| |
64 --musr=* ) musr=$arg ;; |
| |
65 --mgrp=* ) mgrp=$arg ;; |
| |
66 * ) help="Invalid option \`$opt'"; break ;; |
| |
67 esac |
| |
68 done |
| |
69 |
| |
70 # makre sure exactly one run-time mode is specified |
| |
71 if [ ".$mode" = . ]; then |
| |
72 help="No or invalid run-time mode specified" |
| |
73 fi |
| |
74 |
| |
75 # error or usage message |
| |
76 if [ ".$help" != . ]; then |
| |
77 if [ ".$help" != ".Usage" ]; then |
| |
78 echo "$progname:ERROR: $help" 1>&2 |
| |
79 fi |
| |
80 cat 1>&2 <<EOT |
| |
81 $progname:USAGE: $progname [options] |
| |
82 |
| |
83 -h, --help print usage message (this one) |
| |
84 -B, --build build new RPM database from scratch |
| |
85 -R, --rebuild rebuild new from old RPM database |
| |
86 -C, --cleanup cleanup existing RPM database |
| |
87 -F, --fixate fixate existing RPM database |
| |
88 -L, --list list all RPM database files |
| |
89 -f, --force operate in force mode (no save operations) |
| |
90 -q, --quiet operate in quiet mode (no verbose messages at all) |
| |
91 -v, --verbose operate in more verbose mode (increase verbose level) |
| |
92 --prefix=PREFIX use OpenPKG instance under PREFIX |
| |
93 --dbpath=PATH use OpenPKG RPM database under PATH |
| |
94 --rpm=PROG use OpenPKG RPM executable PROG |
| |
95 --musr=USERNAME use OpenPKG management user USERNAME |
| |
96 --mgrp=GROUPNAME use OpenPKG management group GROUPNAME |
| |
97 |
| |
98 This is OpenPKG rpmdb, an RPM database administration utility, providing |
| |
99 lower-level maintainance functions for the Berkeley-DB 4.1 based RPM 4.2 |
| |
100 database. It allows building new RPM databases from scratch, rebuilding |
| |
101 a new from an old RPM database (content dumping and reloading), |
| |
102 cleaning up problems on an existing RPM database (removal of DB region |
| |
103 files, etc) and fixating the files in an existing RPM database (file |
| |
104 attributes). |
| |
105 |
| |
106 EOT |
| |
107 if [ ".$help" != ".Usage" ]; then |
| |
108 exit 2 |
| |
109 else |
| |
110 exit 0 |
| |
111 fi |
| |
112 fi |
| |
113 |
| |
114 # delayed determination of variables |
| |
115 if [ ".$dbpath" = . ]; then |
| |
116 dbpath="$prefix/RPM/DB" |
| |
117 fi |
| |
118 if [ ".$rpm" = . ]; then |
| |
119 rpm="$prefix/bin/openpkg rpm" |
| |
120 fi |
| |
121 |
| |
122 ## |
| |
123 ## DATABASE FILE INFORMATION |
| |
124 ## |
| |
125 |
| |
126 dbfiles=" |
| |
127 hash:Basenames |
| |
128 hash:Conflictname |
| |
129 hash:Depends |
| |
130 btree:Dirnames |
| |
131 hash:Filemd5s |
| |
132 hash:Group |
| |
133 btree:Installtid |
| |
134 hash:Name |
| |
135 hash:Packages |
| |
136 hash:Providename |
| |
137 btree:Provideversion |
| |
138 hash:Pubkeys |
| |
139 hash:Requirename |
| |
140 btree:Requireversion |
| |
141 hash:Sha1header |
| |
142 hash:Sigmd5 |
| |
143 hash:Triggername |
| |
144 region:__db.001 |
| |
145 region:__db.002 |
| |
146 region:__db.003 |
| |
147 region:__db.004 |
| |
148 region:__db.005 |
| |
149 region:__db.006 |
| |
150 region:__db.007 |
| |
151 region:__db.008 |
| |
152 region:__db.009 |
| |
153 " |
| |
154 |
| |
155 ## |
| |
156 ## HELPER FUNCTIONS |
| |
157 ## |
| |
158 |
| |
159 error () { |
| |
160 echo "$progname:ERROR: $*" 1>&2 |
| |
161 exit 1 |
| |
162 } |
| |
163 |
| |
164 warning () { |
| |
165 echo "$progname:WARNING: $*" 1>&2 |
| |
166 } |
| |
167 |
| |
168 verbose () { |
| |
169 local level=$1 |
| |
170 shift |
| |
171 if [ $level -le $verbose ]; then |
| |
172 local lead="" |
| |
173 case "$level" in |
| |
174 1 ) lead="" ;; |
| |
175 2 ) lead="" ;; |
| |
176 3 ) lead=" " ;; |
| |
177 * ) lead=" " ;; |
| |
178 esac |
| |
179 echo "$progname: $lead$*" 1>&2 |
| |
180 fi |
| |
181 } |
| |
182 |
| |
183 rpm () { |
| |
184 local opts="--dbpath `echo $dbpath | sed -e 's;/*$;;' -e 's;$;/;'`" |
| |
185 if [ ".$force" = .yes ]; then |
| |
186 opts="$opts --define '__dbi_private yes'" |
| |
187 fi |
| |
188 verbose 3 "run: $rpm $opts $@" |
| |
189 eval "$rpm $opts \"\$@\"" |
| |
190 } |
| |
191 |
| |
192 rpmdb_load () { |
| |
193 $prefix/lib/openpkg/rpmdb_load ${1+"$@"} |
| |
194 } |
| |
195 |
| |
196 rpmdb_dump () { |
| |
197 $prefix/lib/openpkg/rpmdb_dump ${1+"$@"} |
| |
198 } |
| |
199 |
| |
200 ## |
| |
201 ## RPM DATABASE OPERATIONS |
| |
202 ## |
| |
203 |
| |
204 db_wait () { |
| |
205 # wait until RPM has released the database in case we are called |
| |
206 # asynchronously to RPM (especially important when upgrading from |
| |
207 # RPM 4.0 where concurrent access is still not possible) |
| |
208 verbose 2 "waiting for RPM database to be available" |
| |
209 local i=0 |
| |
210 while [ $i -lt 10 ]; do |
| |
211 if $prefix/libexec/openpkg/rpm -q openpkg >/dev/null 2>&1; then |
| |
212 break |
| |
213 fi |
| |
214 sleep 1 |
| |
215 i=`expr $i + 1` |
| |
216 done |
| |
217 if [ $i -eq 10 ]; then |
| |
218 exit 1 |
| |
219 else |
| |
220 exit 0 |
| |
221 fi |
| |
222 } |
| |
223 |
| |
224 db_remove () { |
| |
225 # remove all known files |
| |
226 verbose 2 "removing (possibly existing) old RPM database DB files" |
| |
227 for dbfile in $dbfiles; do |
| |
228 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
| |
229 verbose 3 "removing database file: $dbpath/$dbfile ($dbtype)" |
| |
230 rm -f $dbpath/$dbfile |
| |
231 done |
| |
232 } |
| |
233 |
| |
234 db_init () { |
| |
235 # perform official "initdb" operation |
| |
236 # (is mostly a no-operation in RPM 4.2, but anyway) |
| |
237 verbose 2 "creating new RPM database (built-in RPM procedure)" |
| |
238 rpm --initdb |
| |
239 |
| |
240 # perform some real RPM work, so more database files |
| |
241 # magically spring into existence |
| |
242 verbose 2 "operating on new RPM database" |
| |
243 rpm --import $prefix/etc/openpkg/openpkg.org.pgp || true |
| |
244 rpm -e gpg-pubkey-63c4cb9f-3c591eda --allmatches || true |
| |
245 |
| |
246 # perform official "rebuilddb" operation in the hope it |
| |
247 # creates even more database files now that we have some content |
| |
248 verbose 2 "rebuilding new RPM database (built-in RPM procedure)" |
| |
249 rpm --rebuilddb |
| |
250 } |
| |
251 |
| |
252 db_unbreak () { |
| |
253 # cleanup DB region files |
| |
254 verbose 2 "cleaning up RPM database DB region files" |
| |
255 for dbfile in $dbfiles; do |
| |
256 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
| |
257 if [ ".$dbtype" = .region ]; then |
| |
258 verbose 3 "cleaning up DB file: $dbpath/$dbfile ($dbtype)" |
| |
259 rm -f $dbpath/$dbfile || true |
| |
260 touch $dbpath/$dbfile || true |
| |
261 fi |
| |
262 done |
| |
263 } |
| |
264 |
| |
265 db_extend () { |
| |
266 # make sure all RPM database DB files are present |
| |
267 verbose 2 "making sure RPM database contains all possible DB files" |
| |
268 for dbfile in $dbfiles; do |
| |
269 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
| |
270 if [ ! -f $dbpath/$dbfile ]; then |
| |
271 verbose 3 "creating DB file: $dbpath/$dbfile ($dbtype)" |
| |
272 if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then |
| |
273 ( echo "VERSION=3" |
| |
274 echo "format=bytevalue" |
| |
275 echo "type=$dbtype" |
| |
276 echo "db_pagesize=16384" |
| |
277 echo "HEADER=END" |
| |
278 echo "DATA=END" |
| |
279 ) | rpmdb_load $dbpath/$dbfile || true |
| |
280 else |
| |
281 touch $dbpath/$dbfile || true |
| |
282 fi |
| |
283 fi |
| |
284 done |
| |
285 } |
| |
286 |
| |
287 db_reload () { |
| |
288 # rebuilding new from old RPM database DB files by dumping and |
| |
289 # reloading their entire content |
| |
290 verbose 2 "dumping and reloading RPM database DB file contents" |
| |
291 for dbfile in $dbfiles; do |
| |
292 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
| |
293 verbose 3 "dumping and reloading DB file: $dbpath/$dbfile ($dbtype)" |
| |
294 if [ -f $dbpath/$dbfile ]; then |
| |
295 if [ ".$dbtype" = .hash -o ".$dbtype" = .btree ]; then |
| |
296 rpmdb_dump $dbpath/$dbfile |\ |
| |
297 rpmdb_load $dbpath/$dbfile.new |
| |
298 rm -f $dbpath/$dbfile |
| |
299 mv $dbpath/$dbfile.new $dbpath/$dbfile |
| |
300 else |
| |
301 rm -f $dbpath/$dbfile || true |
| |
302 touch $dbpath/$dbfile || true |
| |
303 fi |
| |
304 fi |
| |
305 done |
| |
306 } |
| |
307 |
| |
308 db_rebuild () { |
| |
309 # perform official "rebuilddb" operation |
| |
310 verbose 2 "rebuilding RPM database (built-in RPM procedure)" |
| |
311 rpm --rebuilddb |
| |
312 } |
| |
313 |
| |
314 db_operate () { |
| |
315 # perform some read/write operation on RPM database |
| |
316 # (we have no package available, but removing and reimporting |
| |
317 # the OpenPKG OpenPGP keys is a harmless thing and always possible) |
| |
318 verbose 2 "performing read/write operation on RPM database" |
| |
319 for spec in \ |
| |
320 openpkg.org.pgp:gpg-pubkey-63c4cb9f-3c591eda \ |
| |
321 openpkg.com.pgp:gpg-pubkey-61b7ae34-4544a6af \ |
| |
322 openpkg.net.pgp:gpg-pubkey-52197903-4544a74d \ |
| |
323 ; do |
| |
324 eval `echo "$spec" | sed -e 's/^\(.*\):\(.*\)$/file="\1"; package="\2"/'` |
| |
325 rpm -q $package >/dev/null 2>&1 && rpm -e $package --allmatches || true |
| |
326 rpm -q $package >/dev/null 2>&1 || rpm --import $prefix/etc/openpkg/$file || true |
| |
327 done |
| |
328 rpm -qa >/dev/null 2>&1 |
| |
329 } |
| |
330 |
| |
331 db_fixate () { |
| |
332 # fix ownership and permissions of (especially newly created) |
| |
333 # RPM database files to make sure they are consistent |
| |
334 verbose 2 "making sure RPM database files have consistent attributes" |
| |
335 for dbfile in $dbfiles; do |
| |
336 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
| |
337 verbose 3 "fixating DB file: $dbpath/$dbfile ($dbtype)" |
| |
338 chown $musr:$mgrp $dbpath/$dbfile 2>/dev/null || true |
| |
339 chmod 644 $dbpath/$dbfile 2>/dev/null || true |
| |
340 done |
| |
341 } |
| |
342 |
| |
343 db_list () { |
| |
344 # list all database files |
| |
345 for dbfile in $dbfiles; do |
| |
346 eval `echo $dbfile | sed -e 's/^\(.*\):\(.*\)$/dbtype="\1"; dbfile="\2";/'` |
| |
347 if [ $verbose -eq 0 ]; then |
| |
348 echo "$dbfile" |
| |
349 elif [ $verbose -eq 1 ]; then |
| |
350 echo "$dbpath/$dbfile" |
| |
351 elif [ $verbose -ge 2 ]; then |
| |
352 echo "$dbpath/$dbfile ($dbtype)" |
| |
353 fi |
| |
354 done |
| |
355 } |
| |
356 |
| |
357 ## |
| |
358 ## ENVIRONMENT CONSISTENCY CHECKS |
| |
359 ## |
| |
360 |
| |
361 # sanity check OpenPKG instance |
| |
362 if [ ".$prefix" = . ]; then |
| |
363 error "OpenPKG instance directory is empty" |
| |
364 fi |
| |
365 if [ ! -d $prefix ]; then |
| |
366 error "OpenPKG instance directory \"$prefix\" not found" |
| |
367 fi |
| |
368 if [ ! -x $prefix/bin/openpkg ]; then |
| |
369 error "OpenPKG instance directory \"$prefix\" not valid" |
| |
370 fi |
| |
371 |
| |
372 # sanity check OpenPKG RPM database |
| |
373 if [ ".$dbpath" = . ]; then |
| |
374 error "OpenPKG RPM database directory is empty" |
| |
375 fi |
| |
376 if [ ! -d $dbpath ]; then |
| |
377 error "OpenPKG RPM database directory \"$dbpath\" not found" |
| |
378 fi |
| |
379 if [ ! -w $dbpath ]; then |
| |
380 error "OpenPKG RPM database directory \"$dbpath\" not writable" |
| |
381 fi |
| |
382 |
| |
383 ## |
| |
384 ## DISPATCH INTO COMMANDS |
| |
385 ## |
| |
386 |
| |
387 case "$mode" in |
| |
388 build ) |
| |
389 verbose 1 "BUILDING NEW RPM DATABASE FROM SCRATCH ($dbpath)" |
| |
390 db_remove |
| |
391 db_init |
| |
392 db_extend |
| |
393 db_rebuild |
| |
394 db_fixate |
| |
395 db_operate |
| |
396 ;; |
| |
397 |
| |
398 rebuild ) |
| |
399 verbose 1 "REBUILDING NEW FROM OLD RPM DATABASE ($dbpath)" |
| |
400 db_unbreak |
| |
401 db_extend |
| |
402 db_reload |
| |
403 db_rebuild |
| |
404 db_fixate |
| |
405 db_operate |
| |
406 ;; |
| |
407 |
| |
408 cleanup ) |
| |
409 verbose 1 "CLEANING UP EXISTING RPM DATABASE ($dbpath)" |
| |
410 db_unbreak |
| |
411 db_extend |
| |
412 db_rebuild |
| |
413 db_fixate |
| |
414 db_operate |
| |
415 ;; |
| |
416 |
| |
417 fixate ) |
| |
418 verbose 1 "FIXATING EXISTING RPM DATABASE ($dbpath)" |
| |
419 db_extend |
| |
420 db_fixate |
| |
421 db_operate |
| |
422 ;; |
| |
423 |
| |
424 list ) |
| |
425 db_list |
| |
426 ;; |
| |
427 esac |
| |
428 |
| |
429 exit 0 |
| |
430 |