3 # repo-add - add a package to a given repo database file
4 # repo-remove - remove a package entry from a given repo database file
7 # Copyright (c) 2006-2008 Aaron Griffin <aaron@archlinux.org>
8 # Copyright (c) 2007-2008 Dan McGee <dan@archlinux.org>
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.
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.
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/>.
23 # gettext initialization
24 export TEXTDOMAIN
='pacman'
25 export TEXTDOMAINDIR
='@localedir@'
27 myver
='@PACKAGE_VERSION@'
28 confdir
='@sysconfdir@'
37 # ensure we have a sane umask set
43 printf "==> ${mesg}\n" "$@" >&1
49 printf " -> ${mesg}\n" "$@" >&1
54 printf "==> $(gettext "WARNING
:") ${mesg}\n" "$@" >&2
59 printf "==> $(gettext "ERROR
:") ${mesg}\n" "$@" >&2
62 # print usage instructions
64 printf "repo-add, repo-remove (pacman) %s\n\n" "$myver"
65 printf "$(gettext "Usage
: repo-add
[-d] [-q] <path-to-db
> <package|delta
> ...
\n")"
66 printf "$(gettext "Usage
: repo-remove
[-q] <path-to-db
> <packagename|delta
> ...
\n\n")"
68 repo-add will update a package database by reading a package
file.
\n\
69 Multiple packages to add can be specified on the
command line.
\n\n")"
71 repo-remove will update a package database by removing the package name
\n\
72 specified on the
command line from the given repo database. Multiple
\n\
73 packages to remove can be specified on the
command line.
\n\n")"
75 Use the
-q/--quiet flag to minimize output to basic messages
, warnings
,\n\
78 Use the
-d/--delta flag to automatically generate and add a delta
file\n\
79 between the old entry and the new one
, if the old package
file is found
\n\
80 next to the new one.
\n\n")"
81 echo "$(gettext "Example
: repo-add
/path
/to
/repo.db.
tar.gz pacman-3.0
.0.pkg.
tar.gz
")"
82 echo "$(gettext "Example
: repo-remove
/path
/to
/repo.db.
tar.gz kernel26
")"
86 printf "repo-add, repo-remove (pacman) %s\n\n" "$myver"
88 Copyright
(C
) 2006-2008 Aaron Griffin
<aaron@archlinux.org
>.
\n\
89 Copyright
(c
) 2007-2008 Dan McGee
<dan@archlinux.org
>.
\n\n\
90 This is free software
; see the
source for copying conditions.
\n\
91 There is NO WARRANTY
, to the extent permitted by law.
\n")"
97 # arg3 - File to write to
109 for pkgentry
in $tmpdir/$pkgname*; do
111 if [[ ${name%-*-*} = $pkgname ]]; then
119 # Get the package name from the delta filename
120 get_delta_pkgname
() {
127 # write a delta entry
128 # arg1 - path to delta file
132 pkgname
="$(get_delta_pkgname $deltafile)"
134 pkgentry
=$
(find_pkgentry
$pkgname)
135 if [[ -z $pkgentry ]]; then
136 error
"$(gettext "No database entry
for package
'%s'.
")" "$pkgname"
139 deltas
="$pkgentry/deltas"
140 if [[ ! -f $deltas ]]; then
141 echo -e "%DELTAS%" >$deltas
143 # get md5sum and compressed size of package
144 md5sum="$(openssl dgst -md5 "$deltafile")"
145 md5sum="${md5sum##* }"
146 csize
=$
(@SIZECMD@
"$deltafile")
148 oldfile
=$
(xdelta3 printhdr
$deltafile |
grep "XDELTA filename (source)" |
sed 's/.*: *//')
149 newfile
=$
(xdelta3 printhdr
$deltafile |
grep "XDELTA filename (output)" |
sed 's/.*: *//')
151 if grep -q "$oldfile.*$newfile" $deltas; then
152 sed -i.backup
"/$oldfile.*$newfile/d" $deltas && rm -f $deltas.backup
154 msg2
"$(gettext "Adding
'deltas' entry
: %s
-> %s
")" "$oldfile" "$newfile"
155 echo ${deltafile##*/} $md5sum $csize $oldfile $newfile >> $deltas
158 } # end db_write_delta
160 # remove a delta entry
161 # arg1 - path to delta file
165 filename
=${deltafile##*/}
166 pkgname
="$(get_delta_pkgname $deltafile)"
168 pkgentry
=$
(find_pkgentry
$pkgname)
169 if [[ -z $pkgentry ]]; then
172 deltas
="$pkgentry/deltas"
173 if [[ ! -f $deltas ]]; then
176 if grep -q "$filename" $deltas; then
177 sed -i.backup
"/$filename/d" $deltas && rm -f $deltas.backup
178 msg2
"$(gettext "Removing existing entry
'%s'...
")" "$filename"
183 } # end db_remove_delta
185 # write an entry to the pacman database
186 # arg1 - path to package
189 # blank out all variables
191 local pkgname pkgver pkgdesc csize size
md5sum url arch builddate packager force \
192 _groups _licenses _replaces _depends _conflicts _provides _optdepends
195 # IFS (field separator) is only the newline character
199 # read info from the zipped package
201 for line
in $
(bsdtar
-xOqf "$pkgfile" .PKGINFO |
202 grep -v '^#' |
sed 's|\(\w*\)\s*=\s*\(.*\)|\1 \2|'); do
203 # bash awesomeness here- var is always one word, val is everything else
208 group
) _groups
="$_groups$group\n" ;;
209 license
) _licenses
="$_licenses$license\n" ;;
210 replaces
) _replaces
="$_replaces$replaces\n" ;;
211 depend
) _depends
="$_depends$depend\n" ;;
212 conflict
) _conflicts
="$_conflicts$conflict\n" ;;
213 provides
) _provides
="$_provides$provides\n" ;;
214 optdepend
) _optdepends
="$_optdepends$optdepend\n" ;;
220 # get md5sum and compressed size of package
221 md5sum="$(openssl dgst -md5 "$pkgfile")"
222 md5sum="${md5sum##* }"
223 csize
=$
(@SIZECMD@
"$pkgfile")
225 # ensure $pkgname and $pkgver variables were found
226 if [[ -z $pkgname ||
-z $pkgver ]]; then
227 error
"$(gettext "Invalid package
file '%s'.
")" "$pkgfile"
233 if [[ -d $pkgname-$pkgver ]]; then
234 warning
"$(gettext "An entry
for '%s' already existed
")" "$pkgname-$pkgver"
236 if [ $DELTA -eq 1 ]; then
237 pkgentry
=$
(find_pkgentry
$pkgname)
238 if [ -n "$pkgentry" ]; then
239 local oldfilename
=$
(grep -A1 FILENAME
$pkgentry/desc |
tail -n1)
240 local oldfile
="$(dirname $1)/$oldfilename"
245 # remove an existing entry if it exists, ignore failures
246 db_remove_entry
"$pkgname"
248 # create package directory
249 mkdir
"$pkgname-$pkgver"
250 cd "$pkgname-$pkgver"
252 # restore an eventual deltas file
253 [[ -f ..
/$pkgname.deltas
]] && mv "../$pkgname.deltas" deltas
256 msg2
"$(gettext "Creating
'desc' db entry...
")"
257 echo -e "%FILENAME%\n$(basename "$1")\n" >>desc
258 echo -e "%NAME%\n$pkgname\n" >>desc
259 [[ -n $pkgbase ]] && echo -e "%BASE%\n$pkgbase\n" >>desc
260 echo -e "%VERSION%\n$pkgver\n" >>desc
261 [[ -n $pkgdesc ]] && echo -e "%DESC%\n$pkgdesc\n" >>desc
262 write_list_entry
"GROUPS" "$_groups" "desc"
263 [[ -n $csize ]] && echo -e "%CSIZE%\n$csize\n" >>desc
264 [[ -n $size ]] && echo -e "%ISIZE%\n$size\n" >>desc
267 msg2
"$(gettext "Computing md5 checksums...
")"
268 echo -e "%MD5SUM%\n$md5sum\n" >>desc
270 [[ -n $url ]] && echo -e "%URL%\n$url\n" >>desc
271 write_list_entry
"LICENSE" "$_licenses" "desc"
272 [[ -n $arch ]] && echo -e "%ARCH%\n$arch\n" >>desc
273 [[ -n $builddate ]] && echo -e "%BUILDDATE%\n$builddate\n" >>desc
274 [[ -n $packager ]] && echo -e "%PACKAGER%\n$packager\n" >>desc
275 write_list_entry
"REPLACES" "$_replaces" "desc"
276 [[ -n $force ]] && echo -e "%FORCE%\n" >>desc
278 # create depends entry
279 msg2
"$(gettext "Creating
'depends' db entry...
")"
280 # create the file even if it will remain empty
282 write_list_entry
"DEPENDS" "$_depends" "depends"
283 write_list_entry
"CONFLICTS" "$_conflicts" "depends"
284 write_list_entry
"PROVIDES" "$_provides" "depends"
285 write_list_entry
"OPTDEPENDS" "$_optdepends" "depends"
289 # create a delta file
290 if [ -n "$oldfilename" -a -f "$oldfile" ]; then
291 delta
=$
(pkgdelta
-q $oldfile $1)
292 if [ -f "$delta" ]; then
293 db_write_delta
$delta
295 warning
"$(gettext "Old package
file not found
: %s
")" "$oldfilename"
300 } # end db_write_entry
302 # remove existing entries from the DB
303 # arg1 - package name
307 local pkgentry
=$
(find_pkgentry
$pkgname)
308 while [[ -n $pkgentry ]]; do
310 if [[ -f $pkgentry/deltas
]]; then
311 mv "$pkgentry/deltas" "$tmpdir/$pkgname.deltas"
313 msg2
"$(gettext "Removing existing entry
'%s'...
")" \
314 "$(basename $pkgentry)"
316 pkgentry
=$
(find_pkgentry
$pkgname)
319 } # end db_remove_entry
324 if ( set -o noclobber
; echo "$$" > "$LOCKFILE") 2> /dev
/null
; then
327 error
"$(gettext "Failed to acquire lockfile
: %s.
")" "$LOCKFILE"
328 [[ -f $LOCKFILE ]] && error
"$(gettext "Held by process
%s
")" "$(cat $LOCKFILE)"
332 if [[ -f $REPO_DB_FILE ]]; then
333 # there are two situations we can have here- a DB with some entries,
334 # or a DB with no contents at all.
335 if ! bsdtar
-tqf "$REPO_DB_FILE" '*/desc' >/dev
/null
2>&1; then
337 if [[ -n $
(bsdtar
-tqf "$REPO_DB_FILE" '*' 2>/dev
/null
) ]]; then
338 error
"$(gettext "Repository
file '%s' is not a proper pacman database.
")" "$REPO_DB_FILE"
342 msg
"$(gettext "Extracting database to a temporary location...
")"
343 bsdtar
-xf "$REPO_DB_FILE" -C "$tmpdir"
347 error
"$(gettext "Repository
file '%s' was not found.
")" "$REPO_DB_FILE"
351 # check if the file can be created (write permission, directory existence, etc)
352 if ! touch "$REPO_DB_FILE"; then
353 error
"$(gettext "Repository
file '%s' could not be created.
")" "$REPO_DB_FILE"
356 rm -f "$REPO_DB_FILE"
364 if [[ ! -f $1 ]]; then
365 error
"$(gettext "File
'%s' not found.
")" "$1"
369 if [[ ${1##*.} == "delta" ]]; then
371 msg
"$(gettext "Adding delta
'%s'")" "$deltafile"
372 if ! type xdelta3
&>/dev
/null
; then
373 error
"$(gettext "Cannot
find the xdelta3 binary
! Is xdelta3 installed?
")"
376 if db_write_delta
"$deltafile"; then
384 if ! bsdtar
-tqf "$pkgfile" .PKGINFO
>/dev
/null
2>&1; then
385 error
"$(gettext "'%s' is not a package
file, skipping
")" "$pkgfile"
389 msg
"$(gettext "Adding package
'%s'")" "$pkgfile"
391 db_write_entry
"$pkgfile"
396 if [[ ${1##*.} == "delta" ]]; then
398 msg
"$(gettext "Searching
for delta
'%s'...
")" "$deltafile"
399 if db_remove_delta
"$deltafile"; then
402 error
"$(gettext "Delta matching
'%s' not found.
")" "$deltafile"
408 msg
"$(gettext "Searching
for package
'%s'...
")" "$pkgname"
410 if db_remove_entry
"$pkgname"; then
411 rm -f "$tmpdir/$pkgname.deltas"
414 error
"$(gettext "Package matching
'%s' not found.
")" "$pkgname"
430 [[ -d $tmpdir ]] && rm -rf "$tmpdir"
431 (( CLEAN_LOCK
)) && [[ -f $LOCKFILE ]] && rm -f "$LOCKFILE"
438 # determine whether we have gettext; make it a no-op if we do not
439 if ! type gettext &>/dev
/null
; then
446 -h|
--help) usage
; exit 0;;
447 -V|
--version) version
; exit 0;;
450 # figure out what program we are
452 if [[ $cmd != "repo-add" && $cmd != "repo-remove" ]]; then
453 error
"$(gettext "Invalid
command name
'%s' specified.
")" "$cmd"
457 tmpdir
=$
(mktemp
-d /tmp
/repo-tools.XXXXXXXXXX
) ||
(\
458 error
"$(gettext "Cannot create temp directory
for database building.
")"; \
462 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
463 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
464 trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR
470 -q|
--quiet) QUIET
=1;;
471 -d|
--delta) DELTA
=1;;
473 if [[ -z $REPO_DB_FILE ]]; then
475 LOCKFILE
="$REPO_DB_FILE.lck"
479 repo-add
) add
$arg && success
=1 ;;
480 repo-remove
) remove
$arg && success
=1 ;;
487 # if at least one operation was a success, re-zip database
488 if (( success
)); then
489 msg
"$(gettext "Creating updated database
file '%s'")" "$REPO_DB_FILE"
491 case "$REPO_DB_FILE" in
492 *tar.gz
) TAR_OPT
="z" ;;
493 *tar.bz2
) TAR_OPT
="j" ;;
494 *tar.xz
) TAR_OPT
="J" ;;
495 *) warning
"$(gettext "'%s' does not have a valid archive extension.
")" \
499 filename
=$
(basename "$REPO_DB_FILE")
502 if [[ -n $
(ls) ]]; then
503 bsdtar
-c${TAR_OPT}f
"$filename" *
505 # we have no packages remaining? zip up some emptyness
506 warning
"$(gettext "No packages remain
, creating empty database.
")"
507 bsdtar
-c${TAR_OPT}f
"$filename" -T /dev
/null
511 [[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
512 [[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE"
513 dblink
="${REPO_DB_FILE%.tar.*}"
514 target
=${REPO_DB_FILE##*/}
515 ln -sf "$target" "$dblink" 2>/dev
/null || \
516 ln -f "$target" "$dblink" 2>/dev
/null || \
517 cp "$REPO_DB_FILE" "$dblink"
519 msg
"$(gettext "No packages modified
, nothing to
do.
")"
524 # vim: set ts=2 sw=2 noet: