pkgsrc-Users archive

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

a possible fix for pkg_alternatives (with patch)



Hi,

A while ago, I was having problems with pkg_alternatives on non-netbsd systems (OS X in particular). Commands like `tr' and `sed' would choke on a Latin-1 character that is in the original version 1.4, if the locale didn't match ISO-8859-1.

It was discussed for a while and the discussion went off on a tangent about efficiency of shell command constructs etc. The thread is here:

  http://mail-index.netbsd.org/pkgsrc-users/2008/07/20/msg007671.html


Since this came up again for me, I decided to try and refactor the pkg_alternatives.sh and wrapper.sh myself.

I've changed them to use awk for a bunch of stuff; staying away from `read' the "evil" `cat' `grep' and `cut' as much as possible. I *think* it will be better.

It works anyway and is no longer encumbered by the strange use of a Latin-1 character. It was the negation character 0xac.

If the patch gets mangled in email, I can send it along in a file.

Please let me know if this will do the trick. I'm quite sure it's not perfect and I haven't tested it through all possibilities as yet.

Also the Makefile is unchanged, so the version probably would need to be fixed etc.

Thanks,

Louis





cvs diff: Diffing pkgtools/pkg_alternatives
cvs diff: Diffing pkgtools/pkg_alternatives/files
Index: pkgtools/pkg_alternatives/files/pkg_alternatives.sh
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_alternatives/files/pkg_alternatives.sh,v
retrieving revision 1.6
diff -u -r1.6 pkg_alternatives.sh
--- pkgtools/pkg_alternatives/files/pkg_alternatives.sh 15 Jan 2007 02:50:06 -0000 1.6 +++ pkgtools/pkg_alternatives/files/pkg_alternatives.sh 16 Oct 2009 22:48:35 -0000
@@ -56,11 +56,8 @@
     validate_package ${1}
     pkg=${PKG_DBDIR}/${1}*/+ALTERNATIVES

-    set -- $(cat ${pkg} | tr ' ' '¬')
-    while [ ${#} -gt 0 ]; do
-        action_auto_wrapper $(echo ${1} | cut -d '¬' -f 1)
-        shift
-    done
+    eval "$(awk '{ print "action_auto_wrapper " $1 }' $pkg )"
+
 }

# -------------------------------------------------------------------------
@@ -161,11 +158,8 @@
     validate_package ${1}
     pkg=${PKG_DBDIR}/${1}*/+ALTERNATIVES

-    set -- $(cat ${pkg} | tr ' ' '¬')
-    while [ ${#} -gt 0 ]; do
-        action_manual_wrapper $(echo ${1} | tr '¬' ' ')
-        shift
-    done
+    eval "$(awk '{ print "action_manual_wrapper " $0 }' $pkg )"
+
 }

# -------------------------------------------------------------------------
@@ -229,13 +223,10 @@
# Each line should follow the semantics expected by action_register_wrapper.
 #
 action_register_package() {
+
     validate_args register ${#} -eq 1
+    eval "$(awk '{ print "action_register_wrapper " $0 }' $1 )"

-    set -- $(cat ${1} | tr ' ' '¬')
-    while [ ${#} -gt 0 ]; do
-        action_register_wrapper $(echo ${1} | tr '¬' ' ')
-        shift
-    done
 }

# -------------------------------------------------------------------------
@@ -308,11 +299,8 @@
     validate_package ${1}
     pkg=${PKG_DBDIR}/${1}*/+ALTERNATIVES

-    set -- $(cat ${pkg} | tr ' ' '¬')
-    while [ ${#} -gt 0 ]; do
-        action_status_wrapper $(echo ${1} | cut -d '¬' -f 1)
-        shift
-    done
+    eval "$(awk '{ print "action_status_wrapper " $1 }' $pkg )"
+
 }

# -------------------------------------------------------------------------
@@ -322,6 +310,7 @@
 # Shows the current status for the given wrapper.
 #
 action_status_wrapper() {
+
     validate_args status ${#} -eq 1
     validate_wrapper ${1} yes

@@ -331,25 +320,22 @@
     userconf=~/.pkg_alternatives${Prefix}/${wbase}

     [ $(id -un) = @ROOT_USER@ ] && userconf=
- alts=$(cat ${userconf} ${sysconf} ${dbconf} 2>/dev/null | grep -v '^#' | \
-           tr ' ' '¬')
-
-    found=
-    for a in ${alts}; do
-        prog=$(echo ${a} | cut -d '¬' -f 1)
-        if [ -x ${prog} ]; then
-            found=$(echo ${a} | tr '¬' ' ')
-            break
-        fi
-    done

-    [ -n "${found}" ] ||
-        err "the wrapper \`${wbase}' exists but has no valid alternatives"
+    awk '
+        BEGIN{
+          print "Wrapper alternatives for " wbase
+        }
+
+        !/^[ \t]*#/{
+          print "    Candidate: " $0
+        }
+
+        END{
+          if ( NR == 0 )
+              print "the wrapper " wbase " exists but has not alternatives"
+      }
+    ' wbase="$wbase" $userconf $sysconf $dbconf

-    echo "\`${wbase}' points to \`${found}'"
-    for a in $(echo ${alts} | tr ' ' '\n' | sort | uniq); do
-        echo "    candidate: $(echo ${a} | tr '¬' ' ')"
-    done
 }

# -------------------------------------------------------------------------
@@ -360,13 +346,10 @@
 # removes all associated alternatives from their respective wrappers.
 #
 action_unregister_package() {
+
     validate_args unregister ${#} -eq 1
+    eval "$(awk '{ print "action_unregister_wrapper " $0 }' $1 )"

-    set -- $(cat ${1} | tr ' ' '¬')
-    while [ ${#} -gt 0 ]; do
-        action_unregister_wrapper $(echo ${1} | tr '¬' ' ')
-        shift
-    done
 }

# -------------------------------------------------------------------------
@@ -428,37 +411,17 @@
 # given wrapper, returns whether it is accepted or ignored.
 #
 filter() {
+
     [ ! -f @CONFDIR@/filter.conf ] && return 0

-    if [ ${Filter_Read} = no ]; then
-        Filter=$(cat @CONFDIR@/filter.conf | grep -v '^#' | tr ' ' '¬')
-        Filter_Read=yes
-    fi
-
-    [ -z "${Filter}" ] && return 0
-
-    for f in ${Filter}; do
-        what=$(echo ${f} | cut -d '¬' -f 1)
-        case ${what} in
-            accept)
-                name=$(echo ${f} | cut -d '¬' -f 2- | tr '¬' ' ')
-                if echo ${1} | grep "${name}" >/dev/null; then
-                    info "filter accepts \`${1}'"
-                    return 0
-                fi
-                ;;
-            ignore)
-                name=$(echo ${f} | cut -d '¬' -f 2- | tr '¬' ' ')
-                if echo ${1} | grep "${name}" >/dev/null; then
-                    info "filter ignores \`${1}'"
-                    return 1
-                fi
-                ;;
-            *)
-                warn "unknown filter type \`${what}'; ignoring"
-                ;;
-        esac
-    done
+    # the second field in filter.conf is a regular expression.
+
+    eval "$(awk '
+      /^[ \t]*#/ || /^[ \t]*$/ { next }
+ !/^accept/ && !/^ignore/ { print "warn No Such Filter Action: " $1 ; next }
+      { action=$1 ; sub ( "^" $1 FS "*" , "" ) }
+      to_check ~ $0 { print "info filter " action "s " to_check }
+    ' to_check="$1" @CONFDIR@/filter.conf)"

     true
 }
@@ -715,4 +678,3 @@

 main "${@}"

-# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4
Index: pkgtools/pkg_alternatives/files/wrapper.sh
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_alternatives/files/wrapper.sh,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 wrapper.sh
--- pkgtools/pkg_alternatives/files/wrapper.sh 25 Jan 2005 13:00:46 -0000 1.1.1.1
+++ pkgtools/pkg_alternatives/files/wrapper.sh  16 Oct 2009 22:48:36 -0000
@@ -1,4 +1,4 @@
-#!__SH__
+#!@SH@
 #
 # $NetBSD: wrapper.sh,v 1.1.1.1 2005/01/25 13:00:46 jmmv Exp $
 #
@@ -44,21 +44,20 @@
 else
     userfile=~/.pkg_alternatives/${wrapper}
 fi
-alternatives=$(cat ${userfile} __CONF_FILE__ __DB_FILE__ 2>/dev/null | \
-               grep -v "^#" | tr ' ' '¬')

-found=
-for a in ${alternatives}; do
-    prog=$(echo ${a} | cut -d '¬' -f 1)
-    if [ -x ${prog} ]; then
-        found=$(echo ${a} | tr '¬' ' ')
-       break
-    fi
-done
+flist=
+[ -f "$userfile" ] && flist="$userfile"
+[ -f "__CONF_FILE__" ] && flist="$flist __CONF_FILE__"
+[ -f "__DB_FILE__" ]   && flist="$flist __DB_FILE__"
+
+eval "$(awk '{
+  cmd=$0
+  if ( "test -x " $1 " && echo 1" | getline ) {
+    print "exec " cmd " $@"
+    exit
+  }
+}' $flist )"
+

-if [ -z "${found}" ]; then
-    echo "${progname}: no alternatives found" 1>&2
-    exit 1
-fi
-
-exec ${found} "${@}"
+echo "${progname}: no alternatives found" >&2
+exit 1


Home | Main Index | Thread Index | Old Index