#! /usr/local/bin/bash # Shell script to copy files and directories, stripping things appropriately. # Executable programs are stripped completely, and library archives # have debugging symbols removed. usage() { echo >&2 "Usage: $0 [-N NEWER-THAN-FILE] SOURCE-DIR TARGET-DIR" exit 1 } # If non-null, only copy files newer than this file when copying directories. newer_than='' while :; do case "$1" in -N) newer_than="$2"; shift 2 if test -r "$newer_than"; then case "$newer_than" in [!/]*) newer_than=`pwd`/"$newer_than" esac else # There is no such file, so don't try to use it newer_than='' fi;; -*) usage;; *) break;; esac done if [ $# -lt 2 ]; then usage fi OBJCOPY=${OBJCOPY:-i386-gnu-objcopy} check_inode() { inode=`ls -dli "$1" | awk '{ print $1 }'` eval "old_inode=\${inode_${inode}}" eval "inode_${inode}=$2" } # Prints the files in DIR, only using those newer than $newer_than if # it's non-null dir_files() { case "$newer_than" in "") test='';; *) test="-newer $newer_than";; esac find $1 -maxdepth 1 \( ! -type d $test -print \) \ | sed "s@^$1/@@" } copy() { local from=$1 local to=$2 copyattrs() { local ls="`ls -l $from`" local owner="`echo "$ls" | awk '{print $3 "." $4}'`" local mode="`echo "$ls" | sed -e 's/^.\(...\)\(...\)\(...\).*$/u=\1,g=\2,o=\3/' -e 's/-//g' -e 's/s/xs/g'`" chown "$owner" $to chmod "$mode" $to } plaincopy() { rm -f $to echo "$from -> $to" if ! ln -f $from $to 2>/dev/null; then install -m 644 -c $from $to copyattrs fi } objcopy() { if $OBJCOPY --strip-debug $from $to; then echo "strip-debug $from -> $to" copyattrs else plaincopy fi } copysymlink () { linkto="`ls -ld $from | awk '{ print $NF }'`" if test -L $to; then oldlinkto="`ls -ld $to | awk '{ print $NF }'`" else oldlinkto=not-the-value-of-any-real-symlink fi if test $linkto != $oldlinkto; then rm -f $to echo "making symlink $to -> $linkto" ln -s $linkto $to fi } makelocalhardlink () { if test -e $to; then fromino=`ls -dli "$from" | awk '{ print $1 }'` toino=`ls -dli "$to" | awk '{print $1 }'` if test $fromino != $toino; then echo "$to linked to $old_inode" ln -f $old_inode $to fi else echo "$to linked to $old_inode" ln -f $old_inode $to fi } check_inode $from $to # Not necessary; the other bits already do necessary deletion. # test -d $to || { test -e $to && rm -f $to } if test -L $from; then copysymlink elif test "$old_inode"; then makelocalhardlink elif test -d $from; then if test ! -d $to; then echo making $to mkdir -p $to fi for file in `dir_files $from` ..; do test "$file" = .. && continue copy $from/$file $to/$file done else case $from in *.a) read p l o g size rest </dev/null; then echo "strip $from -> $to" copyattrs else plaincopy fi else plaincopy fi ;; esac fi } if [ $# -gt 2 ]; then eval "todir=\${$#}" test -d $todir || { echo >&2 With multiple args, last must be a directory. exit 1; } while [ $# -gt 1 ]; do copy $1 $todir/`basename $1` shift done else copy $1 $2 fi