"Fossies" - the Fresh Open Source Software Archive

Member "fou4s-0.16.0/gpd.sh" (4 Jun 2006, 13953 Bytes) of package /linux/privat/old/fou4s-0.16.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bash source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #!/bin/bash
    2 #
    3 # SVN Info:
    4 # $Author: markus $
    5 # $Date: 2006-06-04 10:06:05 +0200 (Sun, 04 Jun 2006) $
    6 # $Rev: 183 $
    7 #
    8 # Patch description generator by Lars Ellenberg <l.g.e@web.de>
    9 # see list_suse_updates by the same author, and
   10 # fou4s by Markus Gaugusch, see http://fou4s.gaugusch.at/
   11 # or probably even yast2 online update, if you can tell it to look
   12 # at those patch descriptions in the first place.
   13 #
   14 # Written in bash, not perl, since Markus likes bash better :)
   15 #
   16 # gpd uses rsync to generate the recursive directory listings, so this
   17 # obviously only works with rsync enabled servers...
   18 #
   19 
   20 function print_patch_description ()
   21 {
   22     # purpose of the update might be in the *.info or .link/*.en files
   23     # which I try to get into the LONGDESC
   24 
   25     cat <<-__EOP__
   26     ##
   27     ## Patch description of patch $name
   28     ##
   29 
   30     Kind: ${KIND:-generated}
   31 
   32     Shortdescription.english: ${SUMMARY:-no summary available}
   33 
   34     Longdescription.english:
   35     This update is available from
   36     $RSYNCSERVER/
   37     $path
   38 
   39     This patch description was generated automaticaly from recursive
   40     directory listings by the fou4s patch description generator.
   41 
   42     Comments, requests for features, and bug reports, go to
   43     fou4s-devel@gaugusch.at
   44 
   45     ${LONGDESC:-No further information available}
   46     Hsilgne.noitpircsedgnol:
   47 
   48     Size: $((size/1024))
   49 
   50     ## file timestamp on ftp server: $date $time
   51     Buildtime: $unix_time
   52 
   53     MinYaST1Version:
   54     MinYaST2Version:
   55 
   56     Packages:
   57     ##
   58     ## -----> $name <-----
   59     ##
   60     Filename: $name.rpm
   61     Label: $SUMMARY
   62     Series: $ARCH
   63     InstPath: $full_path
   64     Size: 0 $size
   65     Buildtime: $unix_time
   66     BuiltFrom:
   67     Flag:
   68     RpmGroup:${GROUP:+ $GROUP}
   69     Copyright:
   70     Version: $version
   71     StartCommand:
   72     Obsoletes:
   73     Requires:
   74     Provides:
   75     Segakcap:
   76     __EOP__
   77 }
   78 
   79 # expects path in the environment, splits it up into
   80 # name, ver, rel, version=$ver-$rel
   81 # -lge: path remains unchanged for now
   82 function extract_version ()
   83 {
   84     name=${path##*/}
   85     # path=${path%/*}
   86     rel=${name##*-}
   87     [ "$rel" == "$name" ] && return 1 # no '-' found
   88     rel=${rel%.rpm}  # strip rpm extension
   89     rel=${rel%.*}    # strip arch extension, if any
   90     name=${name%-*}
   91     ver=${name##*-}
   92     [ "$ver" == "$name" ] && return 1 # no second '-' found
   93     name=${name%-*}
   94     version=$ver-$rel
   95 }
   96 
   97 function grep_most_recent_versions() {
   98     # in case you wonder:
   99     # '$'\\\[tn]'' because older sed do not support \t\n in
  100     # replacement text...
  101     sed -ne '
  102     /^-/!d          ; # delete if not plain file
  103     /\.rpm$/!d      ; # or not rpm
  104     /\.src\.rpm$/d  ; # or .src.rpm
  105     /\.nosrc\.rpm$/d; # or .nosrc.rpm
  106     ;# /\.x86_64\.rpm$/d; # or .x86_64.rpm
  107     s/^[^ ]* *//    ; # strip permissions
  108     s/ \+/'$'\t''/g ; # squeeze blanks into tabs
  109     s/.rpm$//
  110     ;# I take it that extension (arch) is always present, and does
  111         ;# not contain extra dots; release of non-SuSE packages may contain
  112     ;# dots and alphanums! this is no good, but anyways...
  113     ;# anything/ name- version -  release     extension
  114     s/^\(.*\)\/\(.*-\)\([^-]\+-\)\([0-9.A-Za-z]\+\)\(\.[^-.]*\)\?$/\1|\2|\
  115 \3\
  116 |\4|\5.rpm/p' \
  117     | sed -ne '
  118         1~3h ; # hold it
  119         ; # insert space separators around version numbers
  120         2~3{s/\([0-9]\+\)/ \1 /g;H;}
  121         ; # and print it
  122         3~3{H;x;s/'$'\\\n''//g;p;}' \
  123     | sort -t "|" -k 4,4nr |
  124     # the even fields are numeric parts of the version/release
  125     # the odd  fields are non numeric, but should be use for
  126     # sorting, too, since it could be 2.05b, 0.9.7c etc... 
  127     # non existing fields are ignored, I truncate at 25 ;)
  128       sort -t " " -s \
  129         -k2,2nr -k3,3r -k4,4nr -k5,5r -k6,6nr -k7,7r -k8,8nr -k9,9r \
  130         -k10,10nr -k11,11r -k12,12nr -k13,13r -k14,14nr -k15,15r \
  131         -k16,16nr -k17,17r -k18,18nr -k19,19r -k20,20nr -k21,21r -k22,22nr \
  132         -k23,23r -k24,24nr -k25,25r \
  133     | sort -t "|" -s -k 2,2 \
  134     | sed 's/|/\//; s/[ |]//g;'
  135 }
  136 
  137 # just for fun :)
  138 _pgd_c=0
  139 _pgd_total=0
  140 function progressdot() {
  141     (( $VERBOSE )) || return
  142     if [ $VERBOSE -ge 2 ] ; then
  143         echo $*
  144     elif [ -t 1 ] ; then
  145         if [ $# -eq 0 ] ; then
  146             printf "%$(( 60 - _pgd_c - (_pgd_c+9)/ 10 ))d\n" $_pgd_total
  147             _pgd_total=0
  148             _pgd_c=0
  149         else
  150             if [ $_pgd_c -ge 50 ] ; then
  151                 printf "%5d\n" $_pgd_total
  152                 _pgd_c=0
  153             fi
  154             test ${_pgd_c: -1:1} = 0 && echo -n " "
  155             echo -n .
  156             let _pgd_c+=1
  157             let _pgd_total+=1
  158         fi
  159     fi
  160 }
  161 
  162 get_info()
  163 # gets LONGDESC from supplementary *.info files if possible
  164 {
  165     #
  166     # for known http/ftp urls (i.e. you provided a correct --prefix
  167     # we could do
  168     #  rpm -qip --changelog $url
  169     # and put this into LONGDESC
  170     # this transfers only 50--150KB for a several MB rpm, obviously it
  171     # truncates after the rpm "header" ...
  172     # since doing so for many packages is considerable bandwidth
  173     # anyways, I won't do it now.
  174     #  FIXME maybe introduce an option to do so.
  175     #
  176     local ret=0 in=$listing.mr out=$listing.infofiles
  177     rm -f $out || return
  178     sed -ne 's,.*\t,,;h;
  179          # no useful info in here:
  180          # s,^\(.*\)/\([^/]*\)-[^-]*-[^-]*$,\1/.link/\2.en,p;g;
  181          s,\.patch\.rpm$,_en.info,p
  182          s,\.rpm$,_en.info,p' < "$in" |
  183     fgrep -f - "$listing" |
  184     sed -ne 's,^.* ,+ /,
  185          :l1;/+ ../{p;s,/$,,;s,[^/]*$,,;b l1;};' | 
  186     sort -u > "$out"
  187     if [[ -s $out ]]; then
  188         echo "- *" >> "$out"
  189         rsync $RSYNCOPTS -rL --include-from="$out" \
  190             "$RSYNCSERVER/" "$DESTPATH/"
  191         ret=$?
  192     fi
  193     rm -f "$out"
  194     return $ret
  195 }
  196 
  197 function parse_listing ()
  198 {
  199     local listing=$1
  200     local size date time full_path path name ver rel
  201     local version unix_time
  202     local hash_part rpm_info LONGDESC SUMMARY GOUP 
  203 
  204     if ! $RESUME && [[ -d $DESTPATH/patches ]] ; then
  205         rm -rf "$DESTPATH/patches.old" || {
  206             myError 0 "Could not rm -rf $DESTPATH/patches.old"
  207             exit 1
  208         }
  209         myEcho 1 "moving patches/ to patches.old/"
  210         mv $DESTPATH/patches{,.old} &&
  211         mkdir "$DESTPATH/patches" || {
  212             myError 0 "Could not backup and recreate patches/ dir"
  213             exit 1
  214         }
  215     fi
  216 
  217     myEcho 1 "Generating new patch descriptions to $DESTPATH"
  218 
  219     # only consider the most recent version per basename
  220     grep_most_recent_versions < "$listing" > "$listing.mr"
  221 
  222     # get LONGDESC from description files if available
  223     # if you think this is a performance hit, comment it out.
  224     # since there are no *.info files for most locations,
  225     # this is probably a noop anyways.
  226     # use this if you want to generate the descriptions for the
  227     # "normal" update tree with gpd.sh: there we have *.info files!
  228     cp "$listing.mr" "$listing.mr2"
  229     get_info
  230 
  231     cat "$listing.mr" |
  232     { # this brace is only for the total status of progressdot :)
  233     while read size date time path ; do
  234         arch=${path%%.rpm}
  235         arch=${arch##*.}
  236         ARCH=$arch
  237 
  238         # strip unwanted leading slash if present
  239         path=${path#/}
  240         if [[ $path = update/$SUSEVERSION/* ]] ; then
  241             # NOTE that I ignore PREFIX here
  242             # this is for the update trees
  243             # should come up with something similar as the
  244             # descriptions in the patches{,.cont} directories
  245             full_path=${path#update/$SUSEVERSION/}
  246         else
  247             full_path=$PREFIX$path
  248         fi
  249 
  250         # if we cannot guess the version, ignore this file
  251         extract_version || continue
  252         test $VERBOSE -ge 3 && printf "%-40s  %-16s %s\n" $name $ver-$rel ${path%/*}
  253 
  254         # if we have an old p15n with same version and instpath,
  255         # keep it.
  256         oldp15n="$DESTPATH/patches.old/$name-$arch-$DESC_SERIAL"
  257         if [[ -e $oldp15n ]] &&
  258            grep -q "^Version: $version\$" "$oldp15n" &&
  259            grep -q "^InstPath: $full_path\$" "$oldp15n"
  260         then
  261             mv "$oldp15n" "$DESTPATH/patches/"
  262             progressdot Skip existing $name-$arch-$DESC_SERIAL
  263             continue
  264         fi
  265 
  266         # since we reached this, we have to create a new p15n
  267 
  268         # is --utc a correct assumption?
  269         # it is a rough guess, anyways...
  270         unix_time=`date --utc -d "$date $time" +%s`
  271         LONGDESC=''
  272         SUMMARY=''
  273         GROUP=''
  274         KIND=''
  275         rpm_info=''
  276 
  277         # try to get some info about this update
  278         # ??? are there other variants of info files ???
  279         #
  280         for info in "${path%.patch.rpm}_en.info" "${path%.rpm}_en.info" 
  281             # no useful info in here:
  282             # "${path%/*}/.link/$name.en"
  283         do
  284             break
  285             info=$DESTPATH/$info
  286             [[ -r $info ]] || continue
  287             LONGDESC=$(<$info)
  288             # test -n "$LONGDESC" && echo longdesc "$LONGDESC"
  289             break
  290         done
  291 
  292         # try to get some more info from the ARCHIVES or rpmdb
  293         IFS=$'\n'
  294         if [[ -e $ARCHIVES ]] ; then
  295             # echo calling get_info with $name
  296             set -- $($mypath/get_info_from_ARCHIVES.pl $name 2>/dev/null)
  297         else
  298             set -- $(rpm -q --queryformat \
  299                  "%{GROUP}\n%{SUMMARY}\n%{ARCH}\n%{DESCRIPTION}" \
  300                  $name 2>/dev/null)
  301         fi
  302         if [[ $# != 0 ]] ; then
  303             GROUP=$1
  304             SUMMARY=$2
  305             # ARCH=$3
  306             : ${LONGDESC:="${*: 4}"}
  307         fi
  308         IFS=$' \t\n'
  309 
  310         case "$LONGDESC" in
  311             # TODO add all kind of patterns here
  312             *[Ss]ecurity\ update*) KIND=security;;
  313             *[Ss]ecurity:\ Yes*) KIND=security;;
  314         esac
  315         # echo $name $version $full_path $size $unix_time $SUMMARY $GROUP
  316         progressdot Generating $name-$arch-$DESC_SERIAL
  317         print_patch_description > $DESTPATH/patches/$name-$arch-$DESC_SERIAL
  318     done
  319     progressdot
  320     }
  321     [[ -d "$DESTPATH/patches.old" ]] && rm -rf "$DESTPATH/patches.old"
  322     # rm -f "$listing.mr"
  323 }
  324 shopt -s extglob
  325 
  326 RESUME=false # to resume a previously interupted run
  327 unset PREFIX # prefix for url in descriptions, including any slashes.
  328 CONFIG=
  329 DESTPATH=
  330 GPDQUIET=false
  331 GPDVERBOSE=0
  332 GPDLIST=
  333 RSYNCSERVER=
  334 RSYNCOPTS=
  335 RSYNC_SERVER=   # commandline override
  336 while [ $# -gt 0 ] ; do
  337     case $1 in
  338     --) shift; break;;
  339     --config) CONFIG="$1 $2"; shift;;
  340     --resume) RESUME=true;;
  341     --prefix) PREFIX=$2; shift;;
  342     --server) RSYNC_SERVER=$2; shift;;
  343     --destpath) DESTPATH=$2; shift;;
  344     -q|--quiet) GPDQUIET=true; [[ $2 = 1 ]] && shift ;;
  345     --verbose)  GPDVERBOSE=$2; shift;;
  346     -v) if [[ $2 == [0-9] ]]; then
  347             GPDVERBOSE=$2; shift
  348         else
  349             let GPDVERBOSE+=1
  350         fi ;;
  351     -+(v))  let GPDVERBOSE=${#1}-1;;
  352     -v[0-9])let GPDVERBOSE=${1#-v};;
  353     *) break;;
  354     esac
  355     shift
  356 done
  357 
  358 # use an already retrieved listing and don't get it with rsync
  359 # this test by coincidence does the right thing when $1 is not set,
  360 # since it is not quoted
  361 LISTING=${1-}
  362 if [ ! -f $LISTING ] ; then
  363     echo "Listing file $LISTING not found!"
  364     exit 1
  365 fi
  366 
  367 # get fou4s common functions
  368 # actually I do only need the variables
  369 for fou4s in `dirname $0`/fou4s ./fou4s /usr/sbin/fou4s ; do
  370     test -x $fou4s && source $fou4s --rightsok $CONFIG --commonfuncs && break
  371 done
  372 VERBOSE=$GPDVERBOSE
  373 $GPDQUIET && VERBOSE=0
  374 
  375 # command line override for RSYNCSERVER
  376 if [ -n "$RSYNC_SERVER" ] ; then
  377     RSYNCSERVER=$RSYNC_SERVER
  378     GPDLIST="FAKE" # fake empty content
  379 fi
  380 # strip trailing slashes
  381 RSYNCSERVER=${RSYNCSERVER%%*(/)}
  382 
  383 # markus original fou4s and my fou4s-lge differ, among other things,
  384 # slightly in variable names...
  385 server=${RSYNCSERVER#rsync://}
  386 server=${server%%/*}
  387 : ${DLPATH:=$DLBASE}
  388 : ${SERVERPATH:=$UPDATEPATH}
  389 test -z "$DESTPATH" && DESTPATH=${DLPATH}/$server/$SERVERPATH
  390 for mypath in `dirname $0` . /usr/bin ; do
  391     test -x $mypath/get_info_from_ARCHIVES.pl && break
  392 done
  393 
  394 if [ -z "$GPDLIST" -a -z "$LISTING" ] ; then
  395     echo "Please edit $CONFIGFILE and put something into GpdList!!"
  396     exit 1
  397 fi
  398 
  399 if [[ ${PREFIX-unset} = unset ]] ; then
  400     PREFIX=""
  401     if [[ $RSYNCSERVER = */suse/$ARCH ]]; then
  402         PREFIX=../../
  403     elif [[ $GPDLIST != @(FAKE|update/$SUSEVERSION) ]]; then
  404         cat <<-___
  405         Could not guess the prefix for the URL. Please help me with
  406         ${0##*/} --prefix something
  407         If you really do not want a prefix, e.g. when you use different
  408         config files, and this is completely outside the suse update tree:
  409         ${0##*/} --prefix ""
  410         ___
  411         exit 1
  412     fi
  413 fi
  414 # if prefix is given, I want it to include the trailing slash
  415 [[ $PREFIX == ?*[^/] ]] && PREFIX=$PREFIX/
  416 
  417 # you may want to include DESC_SERIAL and RSYNCSERVER into fou4s config
  418 # if not defined, they are defined here.
  419 # ARCHIVES=$ARCHIVESDIR/ARCHIVES # fixme put into dlpath/.../suseversion!/
  420 # or ARCHIVES="ARCHIVES-$SUSEVERSION" ?
  421 for a in ${ARCHIVES:=} ./ARCHIVES `dirname $0`/ARCHIVES /var/cache/fou4s/ARCHIVES ; do
  422     test -f $a && ARCHIVES=$a && break
  423 done
  424 if ! [[ -x $mypath/get_info_from_ARCHIVES.pl ]] ; then
  425     ARCHIVES=
  426 elif [[ ! -f $ARCHIVES ]] ; then
  427     myEcho 1 "\nHINT: Copy ARCHIVES.gz to ${ARCHIVES%/*}, and gunzip it. This will make gpd.sh write better readable patch descriptions." | fmt
  428     ARCHIVES=
  429 fi
  430 DESC_SERIAL=G
  431 myEcho 1 "Will use -$DESC_SERIAL as description serial number"
  432 # RSYNCSERVER=rsync://ftp.gwdg.de/SuSE/ftp.suse.com/suse/$ARCH # fixme put into fou4s.conf
  433 
  434 if [ $VERBOSE -ge 1 ] ; then
  435     cat << _EOF
  436 
  437           Warning!
  438              
  439           Updates from this tree are NOT necessarily 
  440           UPDATED,  EVEN WHEN VULNERABLE TO SECURITY 
  441           HOLES!
  442 
  443 _EOF
  444 fi
  445 
  446 
  447 # if ! mkdir -p $DLPATH/$server/$SERVERPATH/patches ; then
  448 if [ ! -d $DESTPATH/patches ] ; then
  449     echo "No directory $DESTPATH/patches"
  450     echo "Please run/configure fou4s to create it auomatically. (fou4s -u)"
  451     exit 1
  452 fi
  453 
  454 start_time=$SECONDS
  455 if [ -n "$LISTING" ] ; then
  456     echo "reading $LISTING"
  457     parse_listing "$LISTING"
  458 else
  459     LISTING=`mktemp $DLPATH/tmp.rsync.list.XXXXXX`
  460     if [ ! -f "$LISTING"  ] ; then
  461         echo "Error creating tempfile in $DLPATH!!"
  462         exit 2
  463     fi
  464     # how about: trap "rm $LISTING" EXIT ... ... ?
  465 
  466     echo "# $ARCH $SUSEVERSION $RSYNCSERVER $DESTPATH/patches" > $LISTING
  467     myEcho 1 "Connecting to rsync server $RSYNCSERVER"
  468     for PACKAGE_PATH in $GPDLIST ; do
  469         PACKAGE_PATH=${PACKAGE_PATH##*(/)}  # no leading
  470         PACKAGE_PATH=${PACKAGE_PATH%%*(/)}/ # but one trailing slash
  471         PACKAGE_PATH=${PACKAGE_PATH#FAKE/}  # nothing for FAKE ...
  472         myEcho 1 "Getting descriptions from $PACKAGE_PATH"
  473         echo "# $PACKAGE_PATH" >> $LISTING
  474         rsync $RSYNCOPTS -rL $RSYNCSERVER/$PACKAGE_PATH \
  475         | grep -v kernel | grep -v " zq1/" \
  476         | sed 's/^\(.*\) \(.*\)$/\1 '${PACKAGE_PATH//\//\\/}'\2/' >> $LISTING
  477         ret=${PIPESTATUS[0]}
  478         # seems like rsync returns 11 for server response "no such directory"
  479         # some of the example locations are not available for all
  480         # arch/releases, so just warn
  481         test $ret -eq 0 -o $ret -eq 11 || exit -1
  482         test $ret -eq 11 && echo "$PACKAGE_PATH NOT FOUND!"
  483     done
  484     end_time=$SECONDS
  485     myEcho 1 "Downloaded in $((end_time-start_time)) seconds"
  486     start_time=$SECONDS
  487     parse_listing "$LISTING"
  488     test $VERBOSE -ge 2 && echo "Kept $LISTING" || rm $LISTING
  489 fi
  490 end_time=$SECONDS
  491 myEcho 1 "Generated in $((end_time-start_time)) seconds"