Hi, I'm fighting with current fixfiles script. This script is called on Debian from init scripts (/etc/init.d/selinux-basics) when autorelabeling is requested in the following shape: /sbin/fixfiles -f -F relabel > /dev/null || true With current version r2760, this never succeed at least on Debian. It seems to me, that getopts is used with shifting arguments improperly. Help for getopts says, that successive calls to getopts sets OPTIND on next option. When arguments are shifted without reasigning OPTIND to 1, bad argument is processed. Please consider my patch. I distiled this code from some autoconf output. This supports long options and leaves only non option arguments. No bashism. Code needs review. I'm not certain how effective code should be for very long argument list. If this patch is not usable, original code can be fixed by removing shift commands from processing or reasigning 1 to OPTIND, but man page should be fixed, so that options must precede command. Cheers. -- Zito
Index: fixfiles =================================================================== --- fixfiles (revision 2790) +++ fixfiles (working copy) @@ -20,6 +20,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +progname=$(basename $0) + # # Set global Variables # @@ -186,60 +188,61 @@ esac } usage() { - echo $"Usage: $0 [-l logfile ] [-o outputfile ] { check | restore|[-F] relabel } [[dir] ... ] " + echo $"Usage: $progname [-l logfile ] [-o outputfile ] { check | restore|[-F] relabel } [[dir] ... ] " echo or - echo $"Usage: $0 -R rpmpackage[,rpmpackage...] -C PREVIOUS_FILECONTEXT [-l logfile ] [-o outputfile ] { check | restore }" + echo $"Usage: $progname -R rpmpackage[,rpmpackage...] -C PREVIOUS_FILECONTEXT [-l logfile ] [-o outputfile ] { check | restore }" } -if [ $# = 0 ]; then - usage - exit 1 -fi # See how we were called. -while getopts "C:Ffo:R:l:" i; do - case "$i" in - f) - fullFlag=1 - shift 1 - ;; - R) - RPMFILES=$OPTARG - shift 2 - ;; - o) - OUTFILES=$OPTARG - shift 2 - ;; - l) - LOGFILE=$OPTARG - shift 2 - ;; - C) - PREFC=$OPTARG - shift 2 - ;; - F) - FORCEFLAG="-F" - shift 1 - ;; - *) - usage - exit 1 -esac +opt_prev= +i=0 +for arg +do + let i=i+1 + if test -n "$opt_prev" + then + eval "$opt_prev=\$arg" + opt_prev= + continue + fi + case $arg in + -f|--full) fullFlag=1 ;; + -R|--rpm-files) opt_prev=RPMFILES ;; + -o|--out-file) opt_prev=OUTFILES ;; + -l|--log-file) opt_prev=LOGFILE ;; + -C|--prev-fc) opt_prev=PREFC ;; + -F|--force) FORCEFLAG="-F" ;; + -h|--help) usage; exit 0 ;; + -*) + echo "$progname: error: unrecognized option: $arg +Try \`$progname --help' for more information." >&2 + exit 1 + ;; + *) noa="$noa \${$i}" ;; + esac done +eval set -- $noa + +if test $# -lt 1 +then + usage + exit 1 +fi + # Check for the command -command=$1 -if [ -z $command ]; then +command="$1" +if [ -z "$command" ]; then usage + exit 1 fi +shift 1 # # check if they specified both DIRS and RPMFILES # -shift 1 if [ ! -z "$RPMFILES" ]; then process $command if [ $# -gt 0 ]; then