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] [-f] [-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")"
82 Use the
-f/--files flag to update a database including
file entries.
\n\n")"
83 echo "$(gettext "Example
: repo-add
/path
/to
/repo.db.
tar.gz pacman-3.0
.0.pkg.
tar.gz
")"
84 echo "$(gettext "Example
: repo-remove
/path
/to
/repo.db.
tar.gz kernel26
")"
88 printf "repo-add, repo-remove (pacman) %s\n\n" "$myver"
90 Copyright
(C
) 2006-2008 Aaron Griffin
<aaron@archlinux.org
>.
\n\
91 Copyright
(c
) 2007-2008 Dan McGee
<dan@archlinux.org
>.
\n\n\
92 This is free software
; see the
source for copying conditions.
\n\
93 There is NO WARRANTY
, to the extent permitted by law.
\n")"
99 # arg3 - File to write to
111 for pkgentry
in $tmpdir/$pkgname*; do
113 if [[ ${name%-*-*} = $pkgname ]]; then
121 # Get the package name from the delta filename
122 get_delta_pkgname
() {
129 # write a delta entry
130 # arg1 - path to delta file
134 pkgname
="$(get_delta_pkgname $deltafile)"
136 pkgentry
=$
(find_pkgentry
$pkgname)
137 if [[ -z $pkgentry ]]; then
138 error
"$(gettext "No database entry
for package
'%s'.
")" "$pkgname"
141 deltas
="$pkgentry/deltas"
142 if [[ ! -f $deltas ]]; then
143 echo -e "%DELTAS%" >$deltas
145 # get md5sum and compressed size of package
146 md5sum="$(openssl dgst -md5 "$deltafile")"
147 md5sum="${md5sum##* }"
148 csize
=$
(@SIZECMD@
"$deltafile")
150 oldfile
=$
(xdelta3 printhdr
$deltafile |
grep "XDELTA filename (source)" |
sed 's/.*: *//')
151 newfile
=$
(xdelta3 printhdr
$deltafile |
grep "XDELTA filename (output)" |
sed 's/.*: *//')
153 if grep -q "$oldfile.*$newfile" $deltas; then
154 sed -i.backup
"/$oldfile.*$newfile/d" $deltas && rm -f $deltas.backup
156 msg2
"$(gettext "Adding
'deltas' entry
: %s
-> %s
")" "$oldfile" "$newfile"
157 echo ${deltafile##*/} $md5sum $csize $oldfile $newfile >> $deltas
160 } # end db_write_delta
162 # remove a delta entry
163 # arg1 - path to delta file
167 filename
=${deltafile##*/}
168 pkgname
="$(get_delta_pkgname $deltafile)"
170 pkgentry
=$
(find_pkgentry
$pkgname)
171 if [[ -z $pkgentry ]]; then
174 deltas
="$pkgentry/deltas"
175 if [[ ! -f $deltas ]]; then
178 if grep -q "$filename" $deltas; then
179 sed -i.backup
"/$filename/d" $deltas && rm -f $deltas.backup
180 msg2
"$(gettext "Removing existing entry
'%s'...
")" "$filename"
185 } # end db_remove_delta
187 # write an entry to the pacman database
188 # arg1 - path to package
191 # blank out all variables
193 local pkgname pkgver pkgdesc epoch csize size
md5sum url arch builddate packager force \
194 _groups _licenses _replaces _depends _conflicts _provides _optdepends
197 # IFS (field separator) is only the newline character
201 # read info from the zipped package
203 for line
in $
(bsdtar
-xOqf "$pkgfile" .PKGINFO |
204 grep -v '^#' |
sed 's|\(\w*\)\s*=\s*\(.*\)|\1 \2|'); do
205 # bash awesomeness here- var is always one word, val is everything else
210 group
) _groups
="$_groups$group\n" ;;
211 license
) _licenses
="$_licenses$license\n" ;;
212 replaces
) _replaces
="$_replaces$replaces\n" ;;
213 depend
) _depends
="$_depends$depend\n" ;;
214 conflict
) _conflicts
="$_conflicts$conflict\n" ;;
215 provides
) _provides
="$_provides$provides\n" ;;
216 optdepend
) _optdepends
="$_optdepends$optdepend\n" ;;
222 # get md5sum and compressed size of package
223 md5sum="$(openssl dgst -md5 "$pkgfile")"
224 md5sum="${md5sum##* }"
225 csize
=$
(@SIZECMD@
"$pkgfile")
227 # ensure $pkgname and $pkgver variables were found
228 if [[ -z $pkgname ||
-z $pkgver ]]; then
229 error
"$(gettext "Invalid package
file '%s'.
")" "$pkgfile"
233 pushd "$tmpdir" >/dev
/null
234 if [[ -d $pkgname-$pkgver ]]; then
235 warning
"$(gettext "An entry
for '%s' already existed
")" "$pkgname-$pkgver"
238 pkgentry
=$
(find_pkgentry
$pkgname)
239 if [[ -n $pkgentry ]]; then
240 local oldfilename
=$
(grep -A1 FILENAME
$pkgentry/desc |
tail -n1)
241 local oldfile
="$(dirname $1)/$oldfilename"
246 # remove an existing entry if it exists, ignore failures
247 db_remove_entry
"$pkgname"
249 # create package directory
250 mkdir
"$pkgname-$pkgver"
251 pushd "$pkgname-$pkgver" >/dev
/null
253 # restore an eventual deltas file
254 [[ -f ..
/$pkgname.deltas
]] && mv "../$pkgname.deltas" deltas
257 msg2
"$(gettext "Creating
'desc' db entry...
")"
258 echo -e "%FILENAME%\n$(basename "$1")\n" >>desc
259 echo -e "%NAME%\n$pkgname\n" >>desc
260 [[ -n $pkgbase ]] && echo -e "%BASE%\n$pkgbase\n" >>desc
261 echo -e "%VERSION%\n$pkgver\n" >>desc
262 [[ -n $pkgdesc ]] && echo -e "%DESC%\n$pkgdesc\n" >>desc
263 write_list_entry
"GROUPS" "$_groups" "desc"
264 [[ -n $csize ]] && echo -e "%CSIZE%\n$csize\n" >>desc
265 [[ -n $size ]] && echo -e "%ISIZE%\n$size\n" >>desc
268 msg2
"$(gettext "Computing md5 checksums...
")"
269 echo -e "%MD5SUM%\n$md5sum\n" >>desc
271 [[ -n $url ]] && echo -e "%URL%\n$url\n" >>desc
272 write_list_entry
"LICENSE" "$_licenses" "desc"
273 [[ -n $arch ]] && echo -e "%ARCH%\n$arch\n" >>desc
274 [[ -n $builddate ]] && echo -e "%BUILDDATE%\n$builddate\n" >>desc
275 [[ -n $packager ]] && echo -e "%PACKAGER%\n$packager\n" >>desc
276 write_list_entry
"REPLACES" "$_replaces" "desc"
277 # remain backward-compatible for now; put a force entry in the database
278 if [[ -n $epoch ]]; then
279 echo -e "%EPOCH%\n#epoch\n" >>desc
280 echo -e "%FORCE%\n" >>desc
282 [[ -n $force ]] && echo -e "%FORCE%\n" >>desc
284 # create depends entry
285 msg2
"$(gettext "Creating
'depends' db entry...
")"
286 # create the file even if it will remain empty
288 write_list_entry
"DEPENDS" "$_depends" "depends"
289 write_list_entry
"CONFLICTS" "$_conflicts" "depends"
290 write_list_entry
"PROVIDES" "$_provides" "depends"
291 write_list_entry
"OPTDEPENDS" "$_optdepends" "depends"
296 # create files file if wanted
297 if (( WITHFILES
)); then
298 msg2
"$(gettext "Creating
'files' db entry...
")"
299 local files_path
="$tmpdir/$pkgname-$pkgver/files"
300 echo "%FILES%" >$files_path
301 bsdtar
--exclude='.*' -tf "$pkgfile" >>$files_path
304 # create a delta file
306 if [[ -n $oldfilename ]]; then
307 if [[ -f $oldfile ]]; then
308 delta
=$
(pkgdelta
-q $oldfile $1)
309 if [[ -f $delta ]]; then
310 db_write_delta
$delta
313 warning
"$(gettext "Old package
file not found
: %s
")" "$oldfilename"
319 } # end db_write_entry
321 # remove existing entries from the DB
322 # arg1 - package name
326 local pkgentry
=$
(find_pkgentry
$pkgname)
327 while [[ -n $pkgentry ]]; do
329 if [[ -f $pkgentry/deltas
]]; then
330 mv "$pkgentry/deltas" "$tmpdir/$pkgname.deltas"
332 msg2
"$(gettext "Removing existing entry
'%s'...
")" \
333 "$(basename $pkgentry)"
335 pkgentry
=$
(find_pkgentry
$pkgname)
338 } # end db_remove_entry
343 if ( set -o noclobber
; echo "$$" > "$LOCKFILE") 2> /dev
/null
; then
346 error
"$(gettext "Failed to acquire lockfile
: %s.
")" "$LOCKFILE"
347 [[ -f $LOCKFILE ]] && error
"$(gettext "Held by process
%s
")" "$(cat $LOCKFILE)"
351 if [[ -f $REPO_DB_FILE ]]; then
352 # there are two situations we can have here- a DB with some entries,
353 # or a DB with no contents at all.
354 if ! bsdtar
-tqf "$REPO_DB_FILE" '*/desc' >/dev
/null
2>&1; then
356 if [[ -n $
(bsdtar
-tqf "$REPO_DB_FILE" '*' 2>/dev
/null
) ]]; then
357 error
"$(gettext "Repository
file '%s' is not a proper pacman database.
")" "$REPO_DB_FILE"
361 msg
"$(gettext "Extracting database to a temporary location...
")"
362 bsdtar
-xf "$REPO_DB_FILE" -C "$tmpdir"
366 error
"$(gettext "Repository
file '%s' was not found.
")" "$REPO_DB_FILE"
370 # check if the file can be created (write permission, directory existence, etc)
371 if ! touch "$REPO_DB_FILE"; then
372 error
"$(gettext "Repository
file '%s' could not be created.
")" "$REPO_DB_FILE"
375 rm -f "$REPO_DB_FILE"
383 if [[ ! -f $1 ]]; then
384 error
"$(gettext "File
'%s' not found.
")" "$1"
388 if [[ ${1##*.} == "delta" ]]; then
390 msg
"$(gettext "Adding delta
'%s'")" "$deltafile"
391 if ! type xdelta3
&>/dev
/null
; then
392 error
"$(gettext "Cannot
find the xdelta3 binary
! Is xdelta3 installed?
")"
395 if db_write_delta
"$deltafile"; then
403 if ! bsdtar
-tqf "$pkgfile" .PKGINFO
>/dev
/null
2>&1; then
404 error
"$(gettext "'%s' is not a package
file, skipping
")" "$pkgfile"
408 msg
"$(gettext "Adding package
'%s'")" "$pkgfile"
410 db_write_entry
"$pkgfile"
415 if [[ ${1##*.} == "delta" ]]; then
417 msg
"$(gettext "Searching
for delta
'%s'...
")" "$deltafile"
418 if db_remove_delta
"$deltafile"; then
421 error
"$(gettext "Delta matching
'%s' not found.
")" "$deltafile"
427 msg
"$(gettext "Searching
for package
'%s'...
")" "$pkgname"
429 if db_remove_entry
"$pkgname"; then
430 rm -f "$tmpdir/$pkgname.deltas"
433 error
"$(gettext "Package matching
'%s' not found.
")" "$pkgname"
448 [[ -d $tmpdir ]] && rm -rf "$tmpdir"
449 (( CLEAN_LOCK
)) && [[ -f $LOCKFILE ]] && rm -f "$LOCKFILE"
456 # determine whether we have gettext; make it a no-op if we do not
457 if ! type gettext &>/dev
/null
; then
464 -h|
--help) usage
; exit 0;;
465 -V|
--version) version
; exit 0;;
468 # figure out what program we are
470 if [[ $cmd != "repo-add" && $cmd != "repo-remove" ]]; then
471 error
"$(gettext "Invalid
command name
'%s' specified.
")" "$cmd"
475 tmpdir
=$
(mktemp
-d /tmp
/repo-tools.XXXXXXXXXX
) ||
(\
476 error
"$(gettext "Cannot create temp directory
for database building.
")"; \
480 trap 'trap_exit "$(gettext "TERM signal caught. Exiting...")"' TERM HUP QUIT
481 trap 'trap_exit "$(gettext "Aborted by user! Exiting...")"' INT
482 trap 'trap_exit "$(gettext "An unknown error has occured. Exiting...")"' ERR
488 -q|
--quiet) QUIET
=1;;
489 -d|
--delta) DELTA
=1;;
490 -f|
--files) WITHFILES
=1;;
492 if [[ -z $REPO_DB_FILE ]]; then
494 LOCKFILE
="$REPO_DB_FILE.lck"
498 repo-add
) add
$arg && success
=1 ;;
499 repo-remove
) remove
$arg && success
=1 ;;
506 # if at least one operation was a success, re-zip database
507 if (( success
)); then
508 msg
"$(gettext "Creating updated database
file '%s'")" "$REPO_DB_FILE"
510 case "$REPO_DB_FILE" in
511 *tar.gz
) TAR_OPT
="z" ;;
512 *tar.bz2
) TAR_OPT
="j" ;;
513 *tar.xz
) TAR_OPT
="J" ;;
514 *) warning
"$(gettext "'%s' does not have a valid archive extension.
")" \
518 filename
=$
(basename "$REPO_DB_FILE")
520 pushd "$tmpdir" >/dev
/null
521 if [[ -n $
(ls) ]]; then
522 bsdtar
-c${TAR_OPT}f
"$filename" *
524 # we have no packages remaining? zip up some emptyness
525 warning
"$(gettext "No packages remain
, creating empty database.
")"
526 bsdtar
-c${TAR_OPT}f
"$filename" -T /dev
/null
530 [[ -f $REPO_DB_FILE ]] && mv -f "$REPO_DB_FILE" "${REPO_DB_FILE}.old"
531 [[ -f $tmpdir/$filename ]] && mv "$tmpdir/$filename" "$REPO_DB_FILE"
532 dblink
="${REPO_DB_FILE%.tar.*}"
533 target
=${REPO_DB_FILE##*/}
534 ln -sf "$target" "$dblink" 2>/dev
/null || \
535 ln -f "$target" "$dblink" 2>/dev
/null || \
536 cp "$REPO_DB_FILE" "$dblink"
538 msg
"$(gettext "No packages modified
, nothing to
do.
")"
543 # vim: set ts=2 sw=2 noet: