"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"