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@'
36 # ensure we have a sane umask set
41 printf "==> ${mesg}\n" "$@" >&1
47 printf " -> ${mesg}\n" "$@" >&1
52 printf "==> $(gettext "WARNING
:") ${mesg}\n" "$@" >&2
57 printf "==> $(gettext "ERROR
:") ${mesg}\n" "$@" >&2
60 # print usage instructions
62 printf "repo-add, repo-remove (pacman) %s\n\n" "$myver"
63 printf "$(gettext "Usage
: repo-add
[-q] <path-to-db
> <package|delta
> ...
\n")"
64 printf "$(gettext "Usage
: repo-remove
[-q] <path-to-db
> <packagename|delta
> ...
\n\n")"
66 repo-add will update a package database by reading a package
file.
\n\
67 Multiple packages to add can be specified on the
command line.
\n\n")"
69 repo-remove will update a package database by removing the package name
\n\
70 specified on the
command line from the given repo database. Multiple
\n\
71 packages to remove can be specified on the
command line.
\n\n")"
73 Use the
-q/--quiet flag to minimize output to basic messages
, warnings
,\n\
75 echo "$(gettext "Example
: repo-add
/path
/to
/repo.db.
tar.gz pacman-3.0
.0.pkg.
tar.gz
")"
76 echo "$(gettext "Example
: repo-remove
/path
/to
/repo.db.
tar.gz kernel26
")"
80 printf "repo-add, repo-remove (pacman) %s\n\n" "$myver"
82 Copyright
(C
) 2006-2008 Aaron Griffin
<aaron@archlinux.org
>.
\n\
83 Copyright
(c
) 2007-2008 Dan McGee
<dan@archlinux.org
>.
\n\n\
84 This is free software
; see the
source for copying conditions.
\n\
85 There is NO WARRANTY
, to the extent permitted by law.
\n")"
91 # arg3 - File to write to
103 for pkgentry
in $tmpdir/$pkgname*; do
105 if [[ ${name%-*-*} = $pkgname ]]; then
113 # Get the package name from the delta filename
114 get_delta_pkgname
() {
121 # write a delta entry
122 # arg1 - path to delta file
126 pkgname
="$(get_delta_pkgname $deltafile)"
128 pkgentry
=$
(find_pkgentry
$pkgname)
129 if [[ -z $pkgentry ]]; then
132 deltas
="$pkgentry/deltas"
133 # create deltas file if it does not already exist
134 if [[ ! -f $deltas ]]; then
135 msg2
"$(gettext "Creating
'deltas' db entry...
")"
136 echo -e "%DELTAS%" >>$deltas
138 # get md5sum and compressed size of package
139 md5sum="$(openssl dgst -md5 "$deltafile")"
140 md5sum="${md5sum##* }"
141 csize
=$
(@SIZECMD@
"$deltafile")
143 oldfile
=$
(xdelta3 printhdr
$deltafile |
grep "XDELTA filename (source)" |
sed 's/.*: *//')
144 newfile
=$
(xdelta3 printhdr
$deltafile |
grep "XDELTA filename (output)" |
sed 's/.*: *//')
146 if grep -q "$oldfile.*$newfile" $deltas; then
147 warning
"$(gettext "An entry
for '%s' already existed
")" "$deltafile"
148 sed -i.backup
"/$oldfile.*$newfile/d" $deltas && rm -f $deltas.backup
149 msg2
"$(gettext "Removing existing entry
'%s'...
")" "$deltafile"
151 echo ${deltafile##*/} $md5sum $csize $oldfile $newfile >> $deltas
154 } # end db_write_delta
156 # remove a delta entry
157 # arg1 - path to delta file
161 filename
=${deltafile##*/}
162 pkgname
="$(get_delta_pkgname $deltafile)"
164 pkgentry
=$
(find_pkgentry
$pkgname)
165 if [[ -z $pkgentry ]]; then
168 deltas
="$pkgentry/deltas"
169 if [[ ! -f $deltas ]]; then
172 if grep -q "$filename" $deltas; then
173 sed -i.backup
"/$filename/d" $deltas && rm -f $deltas.backup
174 msg2
"$(gettext "Removing existing entry
'%s'...
")" "$filename"
179 } # end db_remove_delta
181 # write an entry to the pacman database
182 # arg1 - path to package
185 # blank out all variables
187 local pkgname pkgver pkgdesc csize size
md5sum url arch builddate packager force \
188 _groups _licenses _replaces _depends _conflicts _provides _optdepends
191 # IFS (field separator) is only the newline character
195 # read info from the zipped package
197 for line
in $
(bsdtar
-xOqf "$pkgfile" .PKGINFO |
198 grep -v '^#' |
sed 's|\(\w*\)\s*=\s*\(.*\)|\1 \2|'); do
199 # bash awesomeness here- var is always one word, val is everything else
204 group
) _groups
="$_groups$group\n" ;;
205 license
) _licenses
="$_licenses$license\n" ;;
206 replaces
) _replaces
="$_replaces$replaces\n" ;;
207 depend
) _depends
="$_depends$depend\n" ;;
208 conflict
) _conflicts
="$_conflicts$conflict\n" ;;
209 provides
) _provides
="$_provides$provides\n" ;;
210 optdepend
) _optdepends
="$_optdepends$optdepend\n" ;;
216 # get md5sum and compressed size of package
217 md5sum="$(openssl dgst -md5 "$pkgfile")"
218 md5sum="${md5sum##* }"
219 csize
=$
(@SIZECMD@
"$pkgfile")
221 # ensure $pkgname and $pkgver variables were found
222 if [[ -z $pkgname ||
-z $pkgver ]]; then
223 error
"$(gettext "Invalid package
file '%s'.
")" "$pkgfile"
229 if [[ -d $pkgname-$pkgver ]]; then
230 warning
"$(gettext "An entry
for '%s' already existed
")" "$pkgname-$pkgver"
233 # remove an existing entry if it exists, ignore failures
234 db_remove_entry
"$pkgname"
236 # create package directory
237 mkdir
"$pkgname-$pkgver"
238 cd "$pkgname-$pkgver"
240 # restore an eventual deltas file
241 [[ -f ..
/$pkgname.deltas
]] && mv "../$pkgname.deltas" deltas
244 msg2
"$(gettext "Creating
'desc' db entry...
")"
245 echo -e "%FILENAME%\n$(basename "$1")\n" >>desc
246 echo -e "%NAME%\n$pkgname\n" >>desc
247 [[ -n $pkgbase ]] && echo -e "%BASE%\n$pkgbase\n" >>desc
248 echo -e "%VERSION%\n$pkgver\n" >>desc
249 [[ -n $pkgdesc ]] && echo -e "%DESC%\n$pkgdesc\n" >>desc
250 write_list_entry
"GROUPS" "$_groups" "desc"
251 [[ -n $csize ]] && echo -e "%CSIZE%\n$csize\n" >>desc
252 [[ -n $size ]] && echo -e "%ISIZE%\n$size\n" >>desc
255 msg2
"$(gettext "Computing md5 checksums...
")"
256 echo -e "%MD5SUM%\n$md5sum\n" >>desc
258 [[ -n $url ]] && echo -e "%URL%\n$url\n" >>desc
259 write_list_entry
"LICENSE" "$_licenses" "desc"
260 [[ -n $arch ]] && echo -e "%ARCH%\n$arch\n" >>desc
261 [[ -n $builddate ]] && echo -e "%BUILDDATE%\n$builddate\n" >>desc
262 [[ -n $packager ]] && echo -e "%PACKAGER%\n$packager\n" >>desc
263 write_list_entry
"REPLACES" "$_replaces" "desc"
264 [[ -n $force ]] && echo -e "%FORCE%\n" >>desc
266 # create depends entry
267 msg2
"$(gettext "Creating
'depends' db entry...
")"
268 # create the file even if it will remain empty
270 write_list_entry
"DEPENDS" "$_depends" "depends"
271 write_list_entry
"CONFLICTS" "$_conflicts" "depends"
272 write_list_entry
"PROVIDES" "$_provides" "depends"
273 write_list_entry
"OPTDEPENDS" "$_optdepends" "depends"
278 } # end db_write_entry
280 # remove existing entries from the DB
281 # arg1 - package name
285 local pkgentry
=$
(find_pkgentry
$pkgname)
286 while [[ -n $pkgentry ]]; do
288 if [[ -f $pkgentry/deltas
]]; then
289 mv "$pkgentry/deltas" "$tmpdir/$pkgname.deltas"
291 msg2
"$(gettext "Removing existing entry
'%s'...
")" \
292 "$(basename $pkgentry)"
294 pkgentry
=$
(find_pkgentry
$pkgname)
297 } # end db_remove_entry
302 if ( set -o noclobber
; echo "$$" > "$LOCKFILE") 2> /dev
/null
; then
305 error
"$(gettext "Failed to acquire lockfile
: %s.
")" "$LOCKFILE"
306 [[ -f $LOCKFILE ]] && error
"$(gettext "Held by process
%s
")" "$(cat $LOCKFILE)"
310 if [[ -f $REPO_DB_FILE ]]; then
311 # there are two situations we can have here- a DB with some entries,
312 # or a DB with no contents at all.
313 if ! bsdtar
-tqf "$REPO_DB_FILE" '*/desc' >/dev
/null
2>&1; then
315 if [[ -n $
(bsdtar
-tqf "$REPO_DB_FILE" '*' 2>/dev
/null
) ]]; then
316 error
"$(gettext "Repository
file '%s' is not a proper pacman database.
")" "$REPO_DB_FILE"
320 msg
"$(gettext "Extracting database to a temporary location...
")"
321 bsdtar
-xf "$REPO_DB_FILE" -C "$tmpdir"
325 error
"$(gettext "Repository
file '%s' was not found.
")" "$REPO_DB_FILE"
329 # check if the file can be created (write permission, directory existence, etc)
330 if ! touch "$REPO_DB_FILE"; then
331 error
"$(gettext "Repository
file '%s' could not be created.
")" "$REPO_DB_FILE"
334 rm -f "$REPO_DB_FILE"
342 if [[ ! -f $1 ]]; then
343 error
"$(gettext "File
'%s' not found.
")" "$1"
347 if [[ ${1##*.} == "delta" ]]; then
349 msg
"$(gettext "Adding delta
'%s'")" "$deltafile"
350 if ! type xdelta3
&>/dev
/null
; then
351 error
"$(gettext "Cannot
find the xdelta3 binary
! Is xdelta3 installed?
")"
354 if db_write_delta
"$deltafile"; then
362 if ! bsdtar
-tqf "$pkgfile" .PKGINFO
>/dev
/null
2>&1; then
363 error
"$(gettext "'%s' is not a package
file, skipping
")" "$pkgfile"
367 msg
"$(gettext "Adding package
'%s'")" "$pkgfile"
369 db_write_entry
"$pkgfile"
374 if [[ ${1##*.} == "delta" ]]; then
376 msg
"$(gettext "Searching
for delta
'%s'...
")" "$deltafile"
377 if db_remove_delta
"$deltafile"; then
380 error
"$(gettext "Delta matching
'%s' not found.
")" "$deltafile"
386 msg
"$(gettext "Searching
for package
'%s'...
")" "$pkgname"
388 if db_remove_entry
"$pkgname"; then
389 rm -f "$tmpdir/$pkgname.deltas"
392 error
"$(gettext "Package matching
'%s' not found.
")" "$pkgname"
408 [[ -d $tmpdir ]] && rm -rf "$tmpdir"
409 (( CLEAN_LOCK
)) && [[ -f $LOCKFILE ]] && rm -f "$LOCKFILE"
416 # determine whether we have gettext; make it a no-op if we do not
417 if ! type gettext &>/dev
/null
; then
424 -h|
--help) usage
; exit 0;;
425 -V|
--version) version
; exit 0;;
428 # figure out what program we are
430 if [[ $cmd != "repo-add" && $cmd != "repo-remove" ]]; then
431 error
"$(gettext "Invalid
command name
'%s' specified.
")" "$cmd"
435 tmpdir
=$
(mktemp
-d /tmp
/repo-tools.XXXXXXXXXX
) ||
(\
436 error
"$(gettext "Cannot create temp directory
for database building.
")"; \
440 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
441 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
442 trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR
448 -q|
--quiet) QUIET
=1;;
450 if [[ -z $REPO_DB_FILE ]]; then
452 LOCKFILE
="$REPO_DB_FILE.lck"
456 repo-add
) add
$arg && success
=1 ;;
457 repo-remove
) remove
$arg && success
=1 ;;
464 # if at least one operation was a success, re-zip database
465 if (( success
)); then
466 msg
"$(gettext "Creating updated database
file '%s'")" "$REPO_DB_FILE"
468 case "$REPO_DB_FILE" in
469 *tar.gz
) TAR_OPT
="z" ;;
470 *tar.bz2
) TAR_OPT
="j" ;;
471 *tar.xz
) TAR_OPT
="J" ;;
472 *) warning
"$(gettext "'%s' does not have a valid archive extension.
")" \
476 filename
=$
(basename "$REPO_DB_FILE")
479 if [[ -n $
(ls) ]]; then
480 bsdtar
-c${TAR_OPT}f
"$filename" *
482 # we have no packages remaining? zip up some emptyness
483 warning
"$(gettext "No packages remain
, creating empty database.
")"
484 bsdtar
-c${TAR_OPT}f
"$filename" -T /dev
/null
488 [[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
489 [[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE"
490 ln -sf "$REPO_DB_FILE" "${REPO_DB_FILE%.tar.*}"
492 msg
"$(gettext "No packages modified
, nothing to
do.
")"
497 # vim: set ts=2 sw=2 noet: