tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

postinstall vs. obsolete libs



Martin's bin/58697 made me look at postinstall again, which reminded
me that _obsolete_libs has an awk script that is unnecessarily opaque
(with variable names like "res", "result", "line", a function "digit"
that actually returns a number, not necessarily single-digit, etc).
Since I had to dig into that awk script anyway, I thought it might be
a good time to fix it, so that I don't need to re-do that work of
untabgling it the next time.

While there, I noticed that Christos attempt to protect new old libs
when downgrading never really worked b/c it filters by filename, but
the awk script emits absolute pathnames.

Here's the patch, only very lightly tested.  It's a context diff, b/c
the unfied version is not very readable.

Feedback is welcome.


*** postinstall.in.~1.63.~	2024-04-27 02:31:54.577307347 +0300
--- postinstall.in	2024-09-27 00:19:43.813013871 +0300
***************
*** 608,664 ****
  
  	(
  
! 	if [ ! -e "${DEST_DIR}/${dir}" ]
! 	then
! 		return 0
! 	fi
! 
  	cd "${DEST_DIR}/${dir}" || err 2 "can't cd to ${DEST_DIR}/${dir}"
! 	echo lib*.so.* \
! 	| tr ' ' '\n' \
! 	| ${AWK} -v LibDir="${dir}/" '
  #{
  
! function digit(v, c, n) { return (n <= c) ? v[n] : 0 }
  
! function checklib(results, line, regex) {
! 	if (! match(line, regex))
  		return
! 	lib = substr(line, RSTART, RLENGTH)
! 	rev = substr($0, RLENGTH+1)
! 	if (! (lib in results)) {
! 		results[lib] = rev
  		return
  	}
! 	orevc = split(results[lib], orev, ".")
! 	nrevc = split(rev, nrev, ".")
! 	maxc = (orevc > nrevc) ? orevc : nrevc
! 	for (i = 1; i <= maxc; i++) {
! 		res = digit(orev, orevc, i) - digit(nrev, nrevc, i)
! 		if (res < 0) {
! 			print LibDir lib results[lib]
! 			results[lib] = rev
  			return
! 		} else if (res > 0) {
! 			print LibDir lib rev
  			return
  		}
  	}
  }
  
! /^lib.*\.so\.[0-9]+\.[0-9]+(\.[0-9]+)?(\.debug)?$/ {
! 	if (AllLibs)
! 		checklib(minor, $0, "^lib.*\\.so\\.")
! 	else
! 		checklib(found, $0, "^lib.*\\.so\\.[0-9]+\\.")
! }
! 
! /^lib.*\.so\.[0-9]+$/ {
! 	if (AllLibs)
! 		checklib(major, $0, "^lib.*\\.so\\.")
! }
! 
! #}' | exclude_libs
  
  	)
  }
--- 608,693 ----
  
  	(
  
! 	[ -e "${DEST_DIR}/${dir}" ] || return 0
  	cd "${DEST_DIR}/${dir}" || err 2 "can't cd to ${DEST_DIR}/${dir}"
! 
! 	# TODO: make this selectable with a command line option?
! 	local maybe_purge_major
! 	#maybe_purge_major='-v PurgeOldMajor=1'
! 
! 	printf '%s\n' lib*.so.* | ${AWK} ${maybe_purge_major} '
  #{
  
! BEGIN {
! 	BASE_REGEX  = "^lib.*\\.so\\."
! 	MAJOR_REGEX = (BASE_REGEX "[0-9]+\\.")
! 
! 	# in the usual case different major versions of the same
! 	# library are considered different stems and do not compete
! 	# with each other, we keep one of each, but you may request to
! 	# purge old majors, in which case all versions compete for the
! 	# single basename stem
! 	if (PurgeOldMajor)
! 		keepone = BASE_REGEX
! 	else
! 		keepone = MAJOR_REGEX
! }
! 
! # major version symlink
! PurgeOldMajor && /^lib.*\.so\.[0-9]+$/ {
! 	checklib(major, $0, BASE_REGEX)
! }
! 
! # specific minor version of a library
! /^lib.*\.so\.[0-9]+\.[0-9]+(\.[0-9]+)?(\.debug)?$/ {
! 	checklib(minor, $0, keepone)
! }
  
! function checklib(latest, libname, stem_regex) {
! 	if (! match(libname, stem_regex))
  		return
! 	stem = substr(libname, RSTART, RLENGTH)
! 	vers = substr(libname, RLENGTH + 1)
! 
! 	# first time we see this stem? just record the version
! 	if (! (stem in latest)) {
! 		latest[stem] = vers
  		return
  	}
! 
! 	# split version suffixes into the list of numeric components
! 	oversc = split(latest[stem], overs, ".")
! 	nversc = split(vers,         nvers, ".")
! 	maxc = (oversc > nversc) ? oversc : nversc
! 
! 	# is the new version "later" than the one we have seen?
! 	for (i = 1; i <= maxc; ++i) {
! 		cmp = (overs[i]+0) - (nvers[i]+0)
! 
! 		if (cmp < 0) {
! 			# the one we have seen is older, so report it
! 			# as obsolete and update the latest seen
! 			# version to this new one
! 			print stem latest[stem]
! 			latest[stem] = vers
  			return
! 		}
! 		else if (cmp > 0) {
! 			# the one we have just read is older than the
! 			# one we have seen previously, so report this
! 			# "new" one as obsolete
! 			print libname
  			return
  		}
  	}
  }
  
! 	# the ouput if further filtered by exclude_libs that protects
! 	# libraries that have symlinks pointing to them, which one
! 	# encounters when downgrading
! #}'	\
! 	| exclude_libs \
! 	| ${SED} "s|^|${dir}/|"
  
  	)
  }

-uwe


Home | Main Index | Thread Index | Old Index