#!/bin/sh
#---------------------------------------------------------------------- 
# NOM                                        
#    fchown = Changement recursif des droits de fichiers particuliers.
# 
# SYNTAXE                                    
#    fchown -h|H          (aide)   
#    fchown [-v] [-o old_user] [-u new_user] [fichiers]
# 
#---------------------------------------------------------------------- 
# VERSION
#    1.0
# 
# DESCRIPTION
#    * Changement recursif des droits (propietes) pour un utilisateur
#    particulier. A la difference de la commande Chown -R, cette
#    procedure peut effectuer le changement de proprietes a partir de la
#    designation d'un nom precis d'utilisateur. Dans le cas ou pour une
#    meme arborescence, il existe des fichiers d'utilisateurs differents,
#    la procedure modifie uniquement les fichiers designes par
#    l'option -u
# 
#    * Cette procedure est pratique via une utilisation en tant que
#    super utilisateur (root).
# 
# OPTIONS
#    -h|H        aide courte ou longue.        
#                                            
#    -v          Mode verbose, par defaut la procedure n'affiche pas les
#                informations d'execution sur la sortie standard.
#                Cette option permet de valider cet affichage.
#                                            
#    -o user     Effectue les modifications pour un utilisateur bien
#                precis. Seul les fichiers appartenant a cet utilisateur
#                sont concernes par la modification. Option tres
#                importante puisqu'elle justifie l'existance de la
#                procedure vis a vis de : chown -R
#                Sauf si desormais cette possibilite est integree
#                a la commande chown(1M), mais peu importe la
#                procedure fait bien son travail !
# 
#    -u user     Le nom du nouveau utilisateur a affecte aux fichiers
#                et aux repertoires.
# 
#    fichiers    Les noms des repertoires et/ou fichiers de depart des
#                modifications. Par defaut, lLa procedure utilise le 
#                repertoire courant (.).
# 
# 
# EXEMPLE(S)
#    * Lancement de l'application avec affichage de l'aide longue:
#        $ fchown -H
# 
#    * Liste l'ensemble des fichiers appartenant a l'utilisateur
#      courant, sans l'option -u aucune modification n'est effectuee,
#      la procedure se transforme alors en commande ls(1M) un peu
#      particuliere :
#        $ fchown /home 
# 
#    * Modifie tous les fichiers du repertoire courant de l'utilisateur
#      other vers l'utilisateur root :
#        $ fchown -u root -o other
# 
# 
# DEPENDANCE(S)
#    find(1M), ls(1M), chown(1M), awk(1M) ou nawk(1M).
#                                            
# VOIR AUSSI
#    chown(1M).
#                                            
# AUTEUR
#    Copyright (c) 1998 Bertrand LE QUELLEC, All Rigths Reserved.
# 
# CONTACT
#   eMail : blq@mygale.org ou blq@wanadoo.fr
#   Url   : http://www.mygale.org/09/blq/ ou http://perso.wanadoo.fr/blq/
#
# Cree : 24/03/98
#---------------------------------------------------------------------- 
# Permission to use, copy, modify, distribute, and sell this software
# and its documentation for any purpose is hereby granted without fee,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of Bertrand LE QUELLEC    
# not be used in advertising or publicity pertaining to distribution 
# of the software without specific, written prior permission. Bertrand 
# LE QUELLEC makes no representations about the suitability of
# this software for any purpose. It is provided "as is" without
# express or implied warranty.
#
# THIS SOFTWARE IS PROVIDED BY Bertrand LE QUELLEC `AS IS' AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bertrand LE QUELLEC BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE)	 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#---------------------------------------------------------------------- 

# ------------------------------------------ 
# ZONE DE DEFINITION DES VARIABLES GLOBALES:
# ------------------------------------------
NOM_PROCEDURE=`basename $0`
LA_PROCEDURE=$0
CD=`pwd`
AWK=`[ -f /usr/bin/nawk ] && echo "nawk" || echo "awk" `


##
## Variables particulieres:
##
DATE=`date "+%d/%m/%y"`
MODE_COULEUR=0
VISU_HTML=netscape


##
## Les variables concernant l'utilisateur:
##
DEFAUT_AUTEUR=`whoami`
DEFAUT_EDITEUR=${EDITOR}
DEFAUT_SHELL=${SHELL}


#---------------------------------------------------------------------- 
# ----------------------------------------- 
# ZONE DE DEFINITION DES FONCTIONS LOCALES:
# -----------------------------------------
# La fonction doit etre precedee d'un commentaire avec en debut de ligne
# le caractere # (diese) repete deux fois.

##
## En cas d'une interruption la fonction suivante est executee.
## Les interruptions sont des signaux envoyes au processus du script,
## par la commande Unix: kill(1). La "capture" de ces signaux est
## identifiee par la commande Shell: trap definie apres la zone des
## options.
##
TrapInterrup()
{
    # Vous pouvez executer des instructions avant une sortie 
    # par signal (ou brutale!).
    exit 1
}


##
## Renvoie le PATH et nom d'un ou plusieurs executables.
## Si le ou les executables sont introuvables la fonction ne renvoie rien.
## Dans le cas d'un alias la fonction ne renvoie rien, car le PATH n'est
## pas recuperable.
##
Type()
{
    [ $# -ne 0 ] && type $* | ${AWK} '$2=="is" && $4!="alias" {print $NF}'
}


##
## Affiche l'aide indiquee en en-tete du script shell.
## Ne pas supprimer car cette fonction est utilisee a l'appel de la
## procedure avec les options -H ou -H
##
AideProc()
{
    fichier=$1
    niveau=$2

    [ -z "$fichier" ] && {
        Erreur "AideProc(): nombre d'argument incorect."
        return 0
	}

    [ ! -f "$fichier" ] && {
		[ -f "`basename $fichier`" ] && fichier=`basename $fichier` || {
        	Erreur "AideProc(): impossible d'atteindre le fichier $fichier."
        	return 0
    	}
    }

    [ ${niveau:=2} = 2 ] && {
        ${AWK} 'BEGIN {i=2}
			/^#[-]+/{
                if(--i<=0)exit
                next
            }
            /^#[     ]*[A-Z]*[     ]*$/{
                next
            }
            /^#[^!]/{
                print substr($0,1,80)
            }
            /^#[ \t]*$/{
                print ""
            }
        ' $fichier | sed -e 's/^#[     ]*//'
    } || {
        ${AWK} '\
			/^#[-]+/{
                if(--i<=0) exit
                next
            }
            /^#[^!]/{
                print substr($0,2,80)
            }
            /^#[ \t]*$/{
                print ""
            }
        ' i=$niveau $fichier | pg -e
    }
}

##
## Renvoie le type de la machine ou l'on se trouve et surtout le
## systeme d'exploitation en cours. La fonction renvoie un des numero
## suivant en reponse:
##
##    inconue            0
##
##    SunOs            1
##    Sun Solaris        2
##    HP s700            3
##    HP s800            4
##    HP s300            5
##    Silicon Graphic     6
##    IBM AIX            7
##
## Pour recuperer le code retour de la fonction, utilisez la variable $?
##
Machine()
{
    os=`uname`

    [ "$os" = "Solaris" ] && return 2

    [ "$os" = "SunOS" ] && {
        [ -f /vmunix ] && return 1 || return 2
    }
    
    [ "$os" = "HP-UX" ] && {
		if uname -a | grep "PA-RISC" 1> /dev/null
		then
			return 3
		elif uname -a | grep "HP-PA" 1> /dev/null
			return 4
		then
			return 5
		fi
    }

    [ "$os" = "IRIX" ] && return 6

    [ "$os" = "AIX" ] && return 7

    return 0
}


##
## Affiche un message en rouge si l'on se trouve dans une fenetre hpterm
## et se met en attente de 2 secondes.
## Il est possible de recuperer le code retour de la fonction.
##
Erreur()
{
    [ $# -eq 0 ] && return -1

    echo "\n\t${ROUGE}$*${NORMAL}"
    sleep 2

    return 0
}


##
## Permet de visualiser un fichier HTML avec le bon executable:
##    netscape ou mosaic
##
VoirHTML ()
{
    fichier="$*"

    [ -z "$VISU_HTML" ] && VISU_HTML=mosaic

    chemin=`Type $VISU_HTML`
    [ -z "$chemin" ] && VISU_HTML=netscape

    chemin=`Type $VISU_HTML`
    [ -z "$chemin" ] && {
        Erreur "Executable du visualiseur HTML non accessible !"
        return 0
    }

    $VISU_HTML $fichier &
    return 1
}


#---------------------------------------------------------------------- 
# ---------------------------------------------- 
# DEFENITION DES VARIABLES LOCALES AU PROGRAMME:
# ----------------------------------------------

LE_USER=${DEFAUT_AUTEUR}
OLD_USER=
LE_GROUP=
LE_DIR="."
VERBOSE=0


#---------------------------------------------------------------------- 
# ---------------------------------------------- 
# DEFENITION DES FONCTIONS LOCALES AU PROGRAMME:
# ----------------------------------------------



#---------------------------------------------------------------------- 
# ------------------------- 
# RECUPERATION DES OPTIONS:
# -------------------------
set -- `getopt hHxvu:o: $*`                
for opt in $*                                            
do                                                             
    case $opt in                                           
        -h) AideProc $LA_PROCEDURE    ; exit 0 ;;
        -H) AideProc $LA_PROCEDURE 3  ; exit 0 ;;

		-x) set -x ; shift ;;

	    -u)	LE_USER="$2" ; shift ; shift ;;
	    -o)	OLD_USER="-user $2" ; shift ; shift ;;
	    -v)	VERBOSE=1 ; shift ;;

        --) shift ; LE_DIR="$*" ; break ;;
    esac                                                        
done                                                          


#----------------------------------------------------------------------
# AUTRES DEFINITIONS:
# -------------------
trap TrapInterrup 3 2 15    # Recuperation des interruptions 3, 2 et 15


#----------------------------------------------------------------------
# DEBUT ZONE DU PROGRAMME:
# ------------------------
for un_dir in `echo $LE_DIR`
do
	[ $un_dir != "--" ] && {
		# Traitement recursif sur un repertoire/fichier.
		# Le awk permet de traiter les noms de fichiers avec des espaces, ils sont
		# quelques fois utilises et autorises par certaines applications.
		find $un_dir $OLD_USER -print | awk '{ 
			gsub(/ /, "\\\\ ", $0)
			print $0
		}' | while read file		# L'utilisation du While et non du For est ici importante !
		do
			[ $VERBOSE -eq 1 ] && {
				echo ""
				echo ">> `ls -ld "$file" | ${AWK} '{ printf(\"%s %s %s\", $1, $3, $4) }'`\t$file"
			}

			[ ! -z "$LE_USER" ] && {
				chown $LE_USER "$file"

				[ $VERBOSE -eq 1 ] && {
					echo "<< `ls -ld "$file" | ${AWK} '{ printf(\"%s %s %s\", $1, $3, $4) }'`\t$file"
				}
			}
		done
	}
done

