#!/bin/sh -efu # http://developer.mozilla.org/en/docs/install.rdf # http://developer.mozilla.org/en/docs/Toolkit_version_format # http://developer.mozilla.org/en/docs/Enhanced_Extension_Installation # http://kb.mozillazine.org/Install.rdf . shell-args . shell-error . shell-regexp show_help() { cat <<-EOF Usage: $PROG [Options] install.rdf Options: -q, --query=STRING query value in install.rdf info; -t, --target[=STRING] show product rpm requires; -i, --info show common info from the install.rdf; -H, --human show product name instead UID; -v, --verbose print a message for each action; -V, --version print program version and exit; -h, --help show this text and exit. Report bugs to gladkov.alexey@gmail.com EOF exit } print_version() { cat < Copyright (C) 2008 Alexey Gladkov This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. EOF exit } TEMP=`getopt -n $PROG -o H,q:,t::,i,v,V,h -l human,info,target::,query:,verbose,version,help -- "$@"` || show_usage eval set -- "$TEMP" param= mode= show_human= while :; do case "$1" in -q|--query) shift param="$1" mode='query' ;; -t|--target) shift param="$1" show_human=1 mode='target' ;; -i|--info) mode='info' ;; -H|--human) show_human=1 ;; -v|--verbose) verbose=-v ;; -V|--version) print_version ;; -h|--help) show_help ;; --) shift; break ;; *) fatal "Unrecognized option: $1" ;; esac shift done if [ "$#" -eq 0 ]; then fatal 'Not enough arguments.' elif [ "$#" -gt 1 ]; then fatal 'Too many arguments.' fi installrdf="$(readlink -ev "$1")" out="$(rapper "$installrdf" 2>/dev/null)" urn='' url='http://www.mozilla.org/2004/em-rdf' targetapp="$(quote_sed_regexp "$urn <$url#targetApplication>")" app="$(quote_sed_regexp "$urn <$url")" uidtbl=' {ec8030f7-c20a-464f-9b0e-13a3a9e97384} firefox {3550f703-e582-4d05-9a08-453d09bdfdc6} tanderbird {136c295a-4a5a-41cf-bf24-5cee526720d5} nvu {86c18b42-e466-45a9-ae7a-9b95ba6f5640} mozilla {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} seamonkey {718e30fb-e89b-41dd-9da7-e25a45638b28} sunbird {3db10fab-e461-4c80-8b97-957ad5f8ea47} netscape {a463f10c-3994-11da-9945-000d60ca027b} flock ' uid3tbl=' toolkit@mozilla.org firefox ' rdf_query() { local value value="$(quote_sed_regexp "$1")" printf '%s\n' "$out" | sed -n -e "s@^$app#$value> \"\([^\"]\+\)\" \.@\1@p" } human_type() { case "$1" in 2) echo 'Extension' ;; 4) echo 'Theme' ;; 8) echo 'Locale' ;; 32) echo 'Multiple Item Package' ;; esac } uid2name() { local uid="`printf %s "$1" |tr '[A-Z]' '[a-z]'`" printf '%s\n' "$uidtbl$uid3tbl" | grep "^$uid " | cut -d\ -f2 } name2uid() { local name="`printf %s "$1" |tr '[A-Z]' '[a-z]'`" printf '%s\n' "$uidtbl" | grep " $name\$" | cut -d\ -f1 } rdf_info() { printf '%s\n' "$out" | sed -n -e "s@^$app#\(id\|version\|type\|name\|description\|creator\|contributor\|developer\|translator\|homepageURL\|updateInfoURL\)> \"\([^\"]\+\)\" \.@\1 \2@p" | while read -r param value; do if [ "$param" = 'type' ]; then [ -n "$show_human" ] && printf '%s\t%s\n' "$param" "`human_type $value`" || printf '%s\t%s\n' "$param" "$value" else printf '%s\t%s\n' "$param" "$value" fi done } round_min() { min_cmp='>=' min_version= local n= p= for p in `printf '%s\n' "$1" | sed -e 's/^\([0-9\.]\+\).*/\1/' -e 's/[.[:space:]]\+/ /g'`; do if n="$(printf '%g' "$p" 2>/dev/null)"; then [ "$n" -ge 0 ] || n=0 p="$n" fi min_version="$min_version.$p" done min_version="${min_version#\.}" } round_max() { max_cmp='<=' max_version= local n= p= prev= for p in `printf '%s\n' "$1" |tr '.' ' '`; do if printf '%s' "$p" |egrep -qs '^[0-9]+(\+|[A-Za-z]+)'; then max_cmp='<' n="${p%%'+'*}" n="${p%%[A-Za-z]*}" max_version="$max_version.$(($n+1))" break elif printf '%s' "$p" |egrep -qs '^[0-9]+\*'; then max_cmp='<' n="${p%%'*'*}" max_version="$max_version.$(($n+1))" break elif printf '%s' "$p" |egrep -qs '^(\+|\*|[A-Za-z]+)$'; then max_cmp='<' max_version="${max_version%\.*}.$(($prev+1))" break elif n="$(printf '%g' "$p" 2>/dev/null)"; then max_version="$max_version.$n" prev="$n" fi done max_version="${max_version#\.}" } show_requires() { local rc min_version min_cmp max_version max_cmp round_min "$min" round_max "$max" if [ "$min_version" != "$max_version" ]; then rc="$(rpmevrcmp "$max_version" "$min_version")" case "$rc" in 1) verbose "$p minVersion=[$min], maxVersion=[$max]: [$p $min_cmp $min_version], [$p $max_cmp $max_version]" printf 'Requires: %s\n' "$p $min_cmp $min_version" printf 'Requires: %s\n' "$p $max_cmp $max_version" ;; 0) verbose "$p minVersion=[$min], maxVersion=[$max]: [$p = $min_version]" printf 'Requires: %s\n' "$p = $min_version" ;; *) fatal "Error: $p: minVersion=$min_version > maxVersion=$max_version" ;; esac else verbose "$p minVersion=[$min], maxVersion=[$max]: [$p = $min_version]" printf 'Requires: %s\n' "$p = $min_version" fi } rdf_target() { local uid [ -z "${1-}" ] || uid="`name2uid "$1"`" printf '%s\n' "$out" | sed -n -e "s@^$targetapp \([^ ]\+\) \.@\1@p" | while read -r id; do id="$(quote_sed_regexp "$id")" printf '%s\n' "$out" | sed -n -e "s@^$id <$url#\(id\|minVersion\|maxVersion\)> \"\([^\"]\+\)\" \.@\1 \2@p" | while read -r param value; do case "$param" in id) id="$value" [ -n "$show_human" ] && p="`uid2name "$id"`" || p="$id" ;; minVersion) min="$value" ;; maxVersion) max="$value" ;; esac if [ -n "${p-}" -a -n "${min-}" -a -n "${max-}" ]; then if [ -n "$uid" -a "$uid" != "$id" ]; then p= id= min= max= continue fi show_requires p= id= min= max= fi done done } case "$mode" in info) rdf_info ;; target) rdf_target "$param" ;; query) rdf_query "$param" ;; esac exit # Add missing requires rapper -v rpmevrcmp