#! /bin/sh # repo2solv # # this is a shell implementation of repo2solv that makes use of # the different parser utilities # # give it a directory of a local mirror of a repo and this # tries to detect the repo type and generate one SOLV file on stdout get_DESCRDIR () { local d=$(grep '^DESCRDIR' content | sed 's/^DESCRDIR[[:space:]]\+\(.*[^[:space:]]\)[[:space:]]*$/\1/') if test -z "$d"; then echo suse/setup/descr else echo ${d} fi } test_susetags() { if test -s content; then DESCR=$(get_DESCRDIR) test -d $DESCR return $? else return 1 fi } repomd_findfile() { local t=$1 local p=$2 local f if test -n "$t" -a -s repomd.xml ; then f=`repomdxml2solv -q "$t:location" < repomd.xml 2>/dev/null` f=${f##*/} if test -f "$f" ; then echo "$f" return fi fi if test -f "$p.bz2" ; then echo "$p.bz2" elif test -f "$p.gz" ; then echo "$p.gz" elif test -f "$p" ; then echo "$p" fi } repomd_types() { test -s repomd.xml && repomdxml2solv -q type < repomd.xml } repomd_decompress() { case $1 in *.gz) gzip -dc "$1" ;; *.bz2) bzip2 -dc "$1" ;; *.lzma) lzma -dc "$1" ;; *.xz) xz -dc "$1" ;; *) cat "$1" ;; esac } susetags_findfile() { if test -s "$1.xz" ; then echo "$1.xz" elif test -s "$1.lzma" ; then echo "$1.lzma" elif test -s "$1.bz2" ; then echo "$1.bz2" elif test -s "$1.gz" ; then echo "$1.gz" fi } susetags_findfile_cat() { if test -s "$1.xz" ; then xz -dc "$1.xz" elif test -s "$1.lzma" ; then lzma -dc "$1.lzma" elif test -s "$1.bz2" ; then bzip2 -dc "$1.bz2" elif test -s "$1.gz" ; then gzip -dc "$1.gz" elif test -s "$1" ; then cat "$1" fi } # signal an error if there is a problem set -e LANG=C unset CDPATH parser_options=${PARSER_OPTIONS:-} findopt="-prune" repotype= addautooption= while true ; do if test "$1" = "-o" ; then exec > "$2" shift shift elif test "$1" = "-R" ; then # recursive findopt= repotype=plaindir shift elif test "$1" = "-X" ; then addautooption=-X shift elif test "$1" = "-A" ; then shift else break fi done dir="$1" cd "$dir" || exit 1 if test -z "$repotype" ; then # autodetect repository type if test -d repodata -o -f repomd.xml; then repotype=rpmmd elif test_susetags ; then repotype=susetags else repotype=plaindir fi fi if test "$repotype" = rpmmd ; then test -d repodata && { cd repodata || exit 2 } primfile= primxml=`repomd_findfile primary primary.xml` if test -n "$primxml" -a -s "$primxml" ; then primfile=`mktemp` || exit 3 ( # fake tag to combine primary.xml and extensions # like susedata.xml, other.xml, filelists.xml echo '' if test -f $primxml ; then repomd_decompress $primxml # add a newline echo fi susedataxml=`repomd_findfile susedata susedata.xml` if test -f "$susedataxml" ; then repomd_decompress "$susedataxml" fi # all the languages as well for t in `repomd_types` ; do case "$t" in susedata.*) susedataxml=`repomd_findfile "$t" "$t.xml"` if test -f "$susedataxml" ; then repomd_decompress "$susedataxml" fi ;; esac done echo '' ) | sed 's/]*>//g' | sed '1i\' | rpmmd2solv $parser_options > $primfile || exit 4 fi prodfile= prodxml=`repomd_findfile products products.xml` if test -z "$prodxml" ; then prodxml=`repomd_findfile product product.xml` fi if test -n "$prodxml" -a -s "$prodxml" ; then prodfile=`mktemp` || exit 3 repomd_decompress "$prodxml" | rpmmd2solv $parser_options > $prodfile || exit 4 fi patternfile= patternxml=`repomd_findfile 'patterns' patterns.xml` if test -n "$patternxml" -a -s "$patternxml" ; then patternfile=`mktemp` || exit 3 repomd_decompress "$patternxml" | rpmmd2solv $parser_options > $patternfile || exit 4 fi # This contains repomd.xml # for now we only read some keys like timestamp repomdfile= repomdxml=`repomd_findfile '' repomd.xml` if test -n "$repomdxml" -a -s "$repomdxml" ; then repomdfile=`mktemp` || exit 3 repomd_decompress "$repomdxml" | repomdxml2solv $parser_options > $repomdfile || exit 4 fi # This contains suseinfo.xml, which is an extension to repomd.xml # for now we only read some keys like expiration and products suseinfofile= suseinfoxml=`repomd_findfile suseinfo suseinfo.xml` if test -n "$suseinfoxml" -a -s "$suseinfoxml" ; then suseinfofile=`mktemp` || exit 3 repomd_decompress "$suseinfoxml" | repomdxml2solv $parser_options > $suseinfofile || exit 4 fi # This contains a updateinfo.xml* and maybe patches updateinfofile= updateinfoxml=`repomd_findfile updateinfo updateinfo.xml` if test -n "$updateinfoxml" -a -s "$updateinfoxml" ; then updateinfofile=`mktemp` || exit 3 repomd_decompress "$updateinfoxml" | updateinfoxml2solv $parser_options > $updateinfofile || exit 4 fi # This contains a deltainfo.xml* deltainfofile= deltainfoxml=`repomd_findfile deltainfo deltainfo.xml` if test -z "$deltainfoxml"; then deltainfoxml=`repomd_findfile prestodelta prestodelta.xml` fi if test -n "$deltainfoxml" -a -s "$deltainfoxml" ; then deltainfofile=`mktemp` || exit 3 repomd_decompress "$deltainfoxml" | deltainfoxml2solv $parser_options > $deltainfofile || exit 4 fi # This contains appdata appdataxml= appdatafile= if test -x /usr/bin/appdata2solv ; then appdataxml=`repomd_findfile appdata appdata.xml` fi if test -n "$appdataxml" -a -s "$appdataxml" ; then appdatafile=`mktemp` || exit 3 repomd_decompress "$appdataxml" | appdata2solv $parser_options > $appdatafile || exit 4 fi # Now merge primary, patches, updateinfo, and deltainfo mergesolv $addautooption $repomdfile $suseinfofile $primfile $prodfile $patternfile $updateinfofile $deltainfofile $appdatafile rm -f $repomdfile $suseinfofile $primfile $patternfile $prodfile $updateinfofile $deltainfofile $appdatafile elif test "$repotype" = susetags ; then olddir=`pwd` DESCR=$(get_DESCRDIR) cd ${DESCR} || exit 2 appdataxml= appdatafile= if test -x /usr/bin/appdata2solv ; then appdataxml=`susetags_findfile appdata.xml` fi if test -n "$appdataxml" ; then appdatafile=`mktemp` || exit 3 repomd_decompress "$appdataxml" | appdata2solv $parser_options > $appdatafile || exit 4 parser_options="-M $appdatafile $parser_options" fi ( # First packages susetags_findfile_cat packages # DU susetags_findfile_cat packages.DU # Now default language susetags_findfile_cat packages.en # DL (delta rpms) susetags_findfile_cat packages.DL # Now patterns. Not simply those files matching *.pat{,.gz,bz2}, # but only those mentioned in the file 'patterns' if test -f patterns ; then for i in `cat patterns`; do if test -s "$i" ; then repomd_decompress "$i" fi done fi # Now all other packages.{lang}. Needs to come last as it switches # languages for all following susetags files for i in packages.* ; do case $i in *.gz|*.bz2|*.xz|*.lzma) name="${i%.*}" ;; *) name="$i" ;; esac case $name in # ignore files we handled already *.DU | *.en | *.FL | *.DL | packages ) continue ;; *) suff=${name#packages.} echo "=Lan: $suff" repomd_decompress "$i" esac done ) | susetags2solv $addautooption -c "${olddir}/content" $parser_options || exit 4 test -n "$appdatafile" && rm -f "$appdatafile" cd "$olddir" elif test "$repotype" = plaindir ; then find * -name .\* -prune -o $findopt -name \*.delta.rpm -o -name \*.patch.rpm -o -name \*.rpm -a -type f -print0 | rpms2solv $addautooption -0 -m - else echo "unknown repository type '$repotype'" >&2 exit 1 fi