#!/bin/sh # $XTermId: sinstall.sh,v 1.16 2008/03/02 23:35:02 tom Exp $ # # Install program setuid if the installer is running as root, and if xterm is # already installed on the system with setuid privilege. This is a safeguard # for ordinary users installing xterm for themselves on systems where the # setuid is not needed to access a PTY, but only for things like utmp. # # Options: # u+s, g+s as in chmod # -u, -g and -m as in install. If any options are given, $3 is ignored. # # Parameters: # $1 = program to invoke as "install" # $2 = program to install # $3 = previously-installed program, for reference # $4 = final installed-path, if different from reference trace=: trace=echo # override locale... # (otherwise GNU ls displays date column in a locale-dependent manner). LANG=C; export LANG LANGUAGE=C; export LANGUAGE LC_ALL=C; export LC_ALL LC_CTYPE=C; export LC_CTYPE OPTS_SUID= OPTS_SGID= OPTS_MODE= OPTS_USR= OPTS_GRP= while test $# != 0 do case $1 in -*) OPT="$1" shift if test $# != 0 then case $OPT in -u) OPTS_USR="$1"; shift;; -g) OPTS_GRP="$1"; shift;; -m) OPTS_MODE="$1"; shift;; esac else break fi ;; u+s) shift; OPTS_SUID=4000;; g+s) shift; OPTS_SGID=2000;; *) break ;; esac done SINSTALL="$1" SRC_PROG="$2" REF_PROG="$3" DST_PROG="$4" test -z "$SINSTALL" && SINSTALL=install test -z "$SRC_PROG" && SRC_PROG=xterm test -z "$REF_PROG" && REF_PROG=/usr/bin/X11/xterm test -z "$DST_PROG" && DST_PROG="$REF_PROG" test -n "$OPTS_SUID" && test -n "$OPTS_USR" && REF_PROG= test -n "$OPTS_SGID" && test -n "$OPTS_GRP" && REF_PROG= echo checking for presumed installation-mode PROG_SUID= PROG_SGID= PROG_MODE= PROG_USR= PROG_GRP= if test -z "$REF_PROG" ; then $trace "... reference program not used" elif test -f "$REF_PROG" ; then cf_option="-l -L" MYTEMP=${TMPDIR-/tmp}/sinstall$$ # Expect listing to have fields like this: #-r--r--r-- 1 user group 34293 Jul 18 16:29 pathname ls $cf_option $REF_PROG ls $cf_option $REF_PROG >$MYTEMP read cf_mode cf_links cf_usr cf_grp cf_size cf_date1 cf_date2 cf_date3 cf_rest <$MYTEMP $trace "... if \"$cf_rest\" is null, try the ls -g option" if test -z "$cf_rest" ; then cf_option="$cf_option -g" ls $cf_option $REF_PROG ls $cf_option $REF_PROG >$MYTEMP read cf_mode cf_links cf_usr cf_grp cf_size cf_date1 cf_date2 cf_date3 cf_rest <$MYTEMP fi rm -f $MYTEMP # If we have a pathname, and the date fields look right, assume we've # captured the group as well. $trace "... if \"$cf_rest\" is null, we do not look for group" if test -n "$cf_rest" ; then cf_test=`echo "${cf_date2}${cf_date3}" | sed -e 's/[0-9:]//g'` $trace "... if we have date in proper columns ($cf_date1 $cf_date2 $cf_date3), \"$cf_test\" is null" if test -z "$cf_test" ; then PROG_USR=$cf_usr; PROG_GRP=$cf_grp; fi fi $trace "... derived user \"$PROG_USR\", group \"$PROG_GRP\" of previously-installed $SRC_PROG" $trace "... see if mode \"$cf_mode\" has s-bit set" case ".$cf_mode" in #(vi .???s??s*) #(vi $trace "... both setuid/setgid" PROG_SUID=4000 PROG_SGID=2000 ;; .???s*) #(vi $trace "... setuid" PROG_SUID=4000 PROG_GRP= ;; .??????s*) $trace "... setgid" PROG_SGID=2000 PROG_USR= ;; esac PROG_MODE=`echo ".$cf_mode" | sed -e 's/^..//' -e 's/rw./7/g' -e 's/r-./5/g' -e 's/---/0/g' -e 's/--[sxt]/1/g' -e 's/+//g'` fi # passed-in options override the reference test -n "$OPTS_SUID" && PROG_SUID="$OPTS_SUID" test -n "$OPTS_SGID" && PROG_SGID="$OPTS_SGID" test -n "$OPTS_MODE" && PROG_MODE="$OPTS_MODE" test -n "$OPTS_USR" && PROG_USR="$OPTS_USR" test -n "$OPTS_GRP" && PROG_GRP="$OPTS_GRP" # we always need a mode test -z "$PROG_MODE" && PROG_MODE=755 if test -n "${PROG_USR}${PROG_GRP}" ; then cf_uid=`id | sed -e 's/^[^=]*=//' -e 's/(.*$//'` cf_usr=`id | sed -e 's/^[^(]*(//' -e 's/).*$//'` cf_grp=`id | sed -e 's/^.* gid=[^(]*(//' -e 's/).*$//'` $trace "... installing $SRC_PROG as user \"$cf_usr\", group \"$cf_grp\"" if test "$cf_uid" != 0 ; then PROG_SUID= PROG_SGID= PROG_USR="" PROG_GRP="" fi test "$PROG_USR" = "$cf_usr" && PROG_USR="" test "$PROG_GRP" = "$cf_grp" && PROG_GRP="" fi test -n "${PROG_SUID}${PROG_SGID}" && PROG_MODE=`expr $PROG_MODE % 1000` test -n "$PROG_SUID" && PROG_MODE=`expr $PROG_SUID + $PROG_MODE` test -n "$PROG_SGID" && PROG_MODE=`expr $PROG_SGID + $PROG_MODE` test -n "$PROG_USR" && PROG_USR="-o $PROG_USR" test -n "$PROG_GRP" && PROG_GRP="-g $PROG_GRP" echo "$SINSTALL -m $PROG_MODE $PROG_USR $PROG_GRP $SRC_PROG $DST_PROG" eval "$SINSTALL -m $PROG_MODE $PROG_USR $PROG_GRP $SRC_PROG $DST_PROG"