LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices


Reply
  Search this Thread
Old 01-25-2009, 07:36 AM   #1
nobody25145147
LQ Newbie
 
Registered: Jan 2009
Posts: 4

Rep: Reputation: 2
Solution to have svn managed file-permissions and ownership


From: http://www.abmh.de/en/papers/linux/a...rmissions.html

asvn - svn including file permissions and ownership

If you want to control somethink like /etc with svn you definitely need svn to take care of file permissions. I found this asvn script which works good after I spend some time to sort out all this patch-chaos. I found nowhere an up-to-date version. So I decided to put it up here.

This script was written by Ross Mark (rossm at controllingedge.com.au), I downloaded it from http://svn.collab.net/repos/svn/trun...ient-side/asvn. That I patched it with http://markmail.org/message/rqitgigeh2ep5dsw and made it working. So I hope its going to help you.

Code:
#!/bin/bash
#-------------------------------------------------------------------------
#    Author:		Ross Mark (rossm@controllingedge.com.au)
#    Date:		Tue Mar 11 10:02:57 EST 2003
#
#    Copyright (C) 2003-2004 Ross Mark
#
#-------------------------------------------------------------------------

#    This script was written by Ross Mark (rossm at
#    controllingedge.com.au), I (Andreas Hofmeier, http://www.abmh.de/)
#    downloaded it from
#    http://svn.collab.net/repos/svn/trunk/contrib/client-side/asvn. Than
#    I patched it with http://markmail.org/message/rqitgigeh2ep5dsw and
#    made it working. So I hope its going to help you.

#    Description:
#    Archive SVN (asvn) will allow the recording of file types not
#    normally handled by svn. Currently this includes devices,
#    symlinks and file ownership/permissions.
#
#    Every file and directory has a 'file:permissions' property set and
#    every directory has a 'dir:devices' and 'dir:symlinks' for
#    recording the extra information.
#	
#    Run this script instead of svn with the normal svn arguments.
#
#
#    Licensing:
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# http://svn.collab.net/repos/svn/trunk/contrib/client-side/asvn
#-------------------------------------------------------------------------

# $HeadURL$
# $LastChangedDate$
# $LastChangedBy$
# $LastChangedRevision$

SVN=/usr/bin/svn
ACTION=""
DEV_PROP="dir:devices"
SYM_PROP="dir:symlinks"
FILE_PROP="file:permissions"
TMPFILE=/tmp/asvn.tmp.$$
TMPFILE1=/tmp/asvn.tmp1.$$
TMPFILE2=/tmp/asvn.tmp2.$$
PCWD=`/bin/pwd`
SKIPSVN='\( -name .svn -prune -false \)'
PRINTDETAILS="-printf \"file='%p' mode=%m user=%u(%U) group=%g(%G)\n\""

trap cleanup 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

function cleanup()
{
    rm -f $TMPFILE $TMPFILE1 $TMPFILE2
}

function basedirname()
{
    refname="$1"
    dir="`dirname \"$2\"`"
    ref="`expr \"$dir\" : \"$refname/\(.*\)\"`"
    if [ -z "$ref" ]
    then
        echo .
    else
        echo $ref
    fi
}

# Escapes all "special" filename characters.  SED magic was modified from
# the original found at the website:
#   http://elonen.iki.fi/code/misc-notes/remove-duplicate-files/index.html
#
function escapename()
{
       echo "`echo $1 | sed -r 's/([^a-zA-Z0-9./_-])/\\\\\1/g'`"
}

#
# Modifies TMPFILE2
#
function addignorefile()
{
    file="`basename \"$1\"`"
    dir="`dirname \"$1\"`"

    #efile="`echo $file |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`"
    #gefile="`echo $efile |sed -e 's!\(\\\\\)!\\\\\\\\\1!g'`"
    efile="`escapename \"$file\"`"
    gefile="`echo $efile |sed -e 's!\([\\]\)!\1\1!g'`"

    if ! ($SVN propget svn:ignore "$dir" | grep -q "^$gefile\$")
    then
        $SVN propget svn:ignore "$dir"  |sed -e '/^$/d' >$TMPFILE2
        echo "$efile" >>$TMPFILE2 
        $SVN propset svn:ignore -F $TMPFILE2 "$dir" > /dev/null 2>&1
#        $SVN propset svn:ignore -F $TMPFILE2 "$dir"
#        echo setting ignore
        #cat $TMPFILE2 >&2
    fi
}

function deleteignorefile()
{
#    file="`basename \"$1\"`"
#    dir="`dirname \"$1\"`"
#    efile="`echo $file |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`"
#    gefile="`echo $efile |sed -e 's!\(\\\\\)!\\\\\\\\\1!g'`"

      file=`basename "$1"`
      dir=`dirname "$1"`
      efile="`escapename \"$file\"`"
      gefile="`echo $efile |sed -e 's!\([\\]\)!\1\1!g'`"

    echo "deleting ignore setting for '$file'"
    if ($SVN propget svn:ignore "$dir" | grep -q "^$gefile\$")
    then
        $SVN propget svn:ignore "$dir" |sed -e '/^$/d'  |grep -v "^$gefile\$" >$TMPFILE2
#       $SVN propset svn:ignore -F $TMPFILE2 "$dir"
	$SVN propset svn:ignore -F $TMPFILE2 "$dir" > /dev/null 2>&1
        #cat $TMPFILE2 >&2
    fi
}

function recorddirinfo
{
#    eval "find $PCWD $SKIPSVN -o \( -type d ! -name .svn  -print \)" |while read dirlist
    find "$PCWD" \( -type d -name .svn -print \) |  sed -e 's/\/\.svn//' | while read dirlist
    do
#        updatedirsymlinks $1 "$dirlist"
#        updatedirdevices $1 "$dirlist"
 	recordpermissions $1 "$dirlist"
    done
}

function updatedirdevices()
{
    CHECKIN=false
    if [ "$1" = "-ci" ]
    then
        CHECKIN=true
        shift
    fi
    dir="$1"

    echo checking $dir for devices
    #
    # Obtain the list of devices in this directory
    #
#    find "$dir" \( \( -type b -o -type c -o -type p \) -print \)  -o  -type d ! -name "`basename \"$dir\"`" -prune | while read file

	find "$dir" -maxdepth 1 \( -type b -o -type c -o -type p \) -printf "file='%p' mode=%m user=%u(%U) group=%g(%G)\n" |
	sed -r 's#\\#\\\\#g' | sort | while read devinfo
    do
#       echo -n `find "$file" -printf "file='%f' mode=%m user=%u(%U) group=%g(%G)"`
#       [ -b "$file" ] && echo -n ' type=b'
#       [ -c "$file" ] && echo -n ' type=c'
#       [ -p "$file" ] && echo ' type=p'
#       if [ -b "$file" -o -c "$file" ] 
       file=`expr "$devinfo" : "file='\(.*\)' mode"`
       echo -n "$devinfo"
       [ -b "$file" ] && echo -n ' type=b'
       [ -c "$file" ] && echo -n ' type=c'
       [ -p "$file" ] && echo ' type=p'
       if [ -b "$file" -o -c "$file" ]
        then
            ls -l "$file" |
                sed -e 's/^[-lcpbrdwxXstugoTS]* *[0-9] [^ ]* *[^ ]* *\([0-9]*\), *\([0-9]*\) .*/ major=\1 minor=\2/'
        fi
        # In this case file is the full path.
        addignorefile "$file"

    done | sort >$TMPFILE

    #
    # Obtain the currently defined devices
    #
    $SVN propget $DEV_PROP "$dir" >$TMPFILE1

    #
    # If the two list are the same then there is nothing to do.
    #
    if /usr/bin/cmp $TMPFILE1 $TMPFILE >/dev/null
    then
        return
    fi

    if [ -s $TMPFILE ]
    then
        # There are devices in this directory
        if [ "$CHECKIN" = "true" ]
        then
            # Add the current devices to the property
            $SVN propset $DEV_PROP "$dir" -F $TMPFILE
        else
            # Delete all the unwanted devices ie not in TMPFILE1
            cat $TMPFILE |while read line
            do
                file="`expr \"$line\" : \"file='\(.*\)' mode\"`"
                if ! grep -q "file='$file'" $TMPFILE1
                then
                    rm "$file"
                    deleteignorefile "$file"
                fi
            done
        fi
    else
        # There are no devices in this directory
        if [ "$CHECKIN" = "true" ]
        then
            $SVN propdel $DEV_PROP "$dir"
        fi
    fi

    #
    # If we are not a checkin then make sure all the devices are defined
    #
    if [ "$CHECKIN" != "true" ]
    then
        cat $TMPFILE1 |while read info
        do
            #echo info = $info
            [ -z "$info" ] && continue
            grep -q "$info" $TMPFILE && continue # This line still matches
            file="`expr \"$info\" : \"file='\(.*\)' \"`"
            mode=`expr "$info" : ".*' mode=\([0-9]*\) "`
            user=`expr "$info" : ".* user=\([^(]*\)("`
            uid=`expr "$info" : ".* user=[^(]*(\([0-9]*\) "`
            group=`expr "$info" : ".* group=\([^(]*\)("`
            gid=`expr "$info" : ".* group=[^(]*(\([0-9]*\) "`
            type=`expr "$info" : ".* type=\(.\)"`
            major=`expr "$info" : ".* major=\([0-9]*\)"`
            minor=`expr "$info" : ".* minor=\([0-9]*\)"`
            #
            # This file is either missing or wrong
            # Delete the old and create it anew.
            #
            rm -f "$dir/$file"
            mknod --mode=$mode "$dir/$file" $type $major $minor
            chown $user:$group "$dir/$file"
            addignorefile "$dir/$file"
        done
    fi
}


# No longer needed.
function updatedirsymlinks()
{
    CHECKIN=false
    if [ "$1" = "-ci" ]
    then
        CHECKIN=true
        shift
    fi
    dir="$1"

    echo checking $dir for symlinks
    cp /dev/null $TMPFILE
    #
    # Obtain the list of symlinks in this directory
    #
    find "$dir" \( -type l -printf "file='%f' dest='%l'\n" \)  -o  -type d ! -name "`basename \"$dir\"`" -prune |
        sort >$TMPFILE
    
    #
    # Make sure all the symlinks are being ignored.
    #
    cat $TMPFILE |while read line
    do
        file="`expr \"$line\" : \"file='\(.*\)' dest\"`"
        addignorefile "$dir/$file"
    done
    
    #
    # Obtain the currently defined symlinks
    #
    $SVN propget $SYM_PROP "$dir" >$TMPFILE1

    #
    # If the two list are the same then there is nothing to do.
    #
    if cmp $TMPFILE1 $TMPFILE >/dev/null
    then
        return
    fi

    if [ -s $TMPFILE ]
    then
        # There are symlinks in this directory
        if [ "$CHECKIN" = "true" ]
        then
            # Add the current symlinks to the property
            $SVN propset $SYM_PROP "$dir" -F $TMPFILE
        else
            # Delete all the unwanted symlinks
            cat $TMPFILE |while read line
            do
                file="`expr \"$line\" : \"file='\(.*\)' dest\"`"
                efile="`echo \"$file\" |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`"
                if ! grep -q "file='$efile'" $TMPFILE1
                then
                    rm "$dir/$file"
                    deleteignorefile "$dir/$file"
                fi
            done
        fi
    else
        # There are no symlinks in this directory
        if [ "$CHECKIN" = "true" ]
        then
            $SVN propdel $SYM_PROP "$dir"
        fi
    fi

    #
    # If we are not a checkin then make sure all the symlinks are defined
    #
    if [ "$CHECKIN" != "true" ]
    then
        cat $TMPFILE1 |while read info
        do
            [ -z "$info" ] && continue
            file="`expr \"$info\" : \"file='\(.*\)' dest\"`"
            dest="`expr \"$info\" : \".*' dest='\(.*\)'$\"`"

            if [ -L "$dir/$file" ]
            then
                [ "`find \"$dir/$file\" -printf '%l'`" = "$dest" ] && continue
            fi 
            rm -f "$dir/$file"
            ln -s "$dest" "$dir/$file"
        done
    fi
}

function recordpermissions()
{
    CHECKIN=false
    if [ "$1" = "-ci" ]
    then
        CHECKIN=true
        shift
    fi

    dir="$1"

    echo checking $dir for permissions

    cp /dev/null $TMPFILE

#    eval "find $PCWD $SKIPSVN -o \( \( -type d ! -name .svn  \) -o -type f \) $PRINTDETAILS" | while read info
       #
       # Obtain the list of files and subdirectories in this directory
       #   We also need to fix the backslash characters before the 'while read' or
       #   they will get interepreted within the read.
       #
       find "$dir" -maxdepth 1 \( -type f -o \( -type d ! -name \.svn \) \) -printf "file='%p' mode=%m user=%u(%U) group=%g(%G)\n" |
       sed -r 's#\\#\\\\#g' | sort | while read info
    do
        device=`expr "$info" : "file='\(.*\)' mode"`
	file=`expr "$info" : "file='\(.*\)' mode"`
	info=`expr "$info" : "file='.*' \(mode.*\)"`

#        if [ "$PCWD" = "$device" ]
	if [ "$PCWD" = "$file" ]
        then
            dir="."
            file=""
        else
#            dir="`basedirname \"$PCWD\" \"$device\"`"
#            file="`basename \"$device\"`"
             dir="`basedirname \"$PCWD\" \"$file\"`"
             file="`basename \"$file\"`"
             # All chars except spaces and tabs seem to be handled correctly
             # within the double quotes, so we just fix the spaces and tabs
# this leads to an error: sed: -e expression #1, char 26: invalid reference \1 on `s' command's RHS

#             file="`echo \"$file\" | sed -r 's#\([\ \        ]\)#\\\\\1#g'`"
        fi

       props="`$SVN propget $FILE_PROP \"$dir/$file\"`"
       if [ $? -eq 0 ]
       then
               #file is under svn control

        # see if the properties have changed.
#        if [ "`$SVN propget $FILE_PROP \"$dir/$file\"`" != "$info" ]
        if [ "$props" != "$info" ]
        then
            if [ "$CHECKIN" = "true" ]
            then
		$SVN propset $FILE_PROP  "$info" "$dir/$file"
            else
                info=`$SVN propget $FILE_PROP "$dir/$file"`
                mode=`expr "$info" : "mode=\([0-9]*\) "`
                user=`expr "$info" : ".* user=\([^(]*\)("`
                uid=`expr "$info" : ".* user=[^(]*(\([0-9]*\) "`
                group=`expr "$info" : ".* group=\([^(]*\)("`
                gid=`expr "$info" : ".* group=[^(]*(\([0-9]*\) "`

                if  [ "$user" = "" -o "$group" = ""  -o "$mode" = "" ]
                then
#                    echo "property $FILE_PROP not set for $dir/$file"
		    echo "property $FILE_PROP not set for \"$dir/$file\""
                else
#                    chown $user:$group  "$dir/$file"
#                    chmod $mode "$dir/$file"
                     echo "changing owner/group mode on \"$dir/$file\""
                     chown $user:$group  "$dir/$file"
                     chmod $mode "$dir/$file"
                fi
            fi
        fi

       else
               #file is not under svn control
               # echo -n "" is just a no-op allowing this else block to exist
               echo -n ""
       fi

    done
}


function pre_checkin()
{
    echo this is the pre checkin process
    recorddirinfo -ci
# recordpermissions is called from recorddirinfo now
#   recordpermissions -ci
}

function post_checkout()
{
    echo this is the post checkout process
    if [ "$CHDIR" = "true" ]
    then
        shift $(($# -1))
        cd "`basename \"$1\"`"
        PCWD="$PCWD/`basename \"$1\"`"
    fi
    recorddirinfo 
#    recordpermissions 
# recordpermissions is called from recorddirinfo now

}

CHDIR=false
DOSVN=true
case "$1" in
  checkout|co)      CHDIR=true; ACTION="post";;
  commit|ci)        ACTION="pre";;
  import)                        ACTION="pre";;
  prework|pre)   DOSVN=false; ACTION="pre";;
  switch|sw)        ACTION="post";;
  update|up)        ACTION="post";;
  *);;
esac

[ "$ACTION" =  "pre" ] && pre_checkin $@

#$SVN $@
if [ "$DOSVN" = "true" ]
then
       echo $SVN "$@"
       $SVN "$@"
fi


[ $? = 0 -a "$ACTION" = "post" ] && post_checkout $@

cleanup
#
# vim: set ai ts=8 sw=4
#
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
anon svn read-only over apache: '.svn/entries': No such file hedpe Linux - Software 2 04-29-2009 05:31 AM
cannot execute binary file, though ownership and permissions are set correctly :( rahmmandel Linux - Software 6 01-11-2007 08:45 AM
File permissions and ownership all screwed up Haiyadragon Linux - General 6 09-20-2004 01:09 PM
Apache/Samba file permissions/ownership seedsca Linux - Networking 0 03-28-2004 09:07 PM
CVS - file permissions and file ownership Osten Linux - Software 3 01-18-2004 04:08 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Software

All times are GMT -5. The time now is 02:26 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration