1#!/bin/sh 2# 3# installFile.tcl - a Tcl version of install-sh 4# that copies a file and preserves its permission bits. 5# This also optimizes out installation of existing files 6# that have the same size and time stamp as the source. 7# 8# \ 9exec tclsh8.3 "$0" ${1+"$@"} 10 11set doCopy 0 ;# Rename files instead of copy 12set doStrip 0 ;# Strip the symbols from installed copy 13set verbose 0 14set src "" 15set dst "" 16 17# Process command line arguments, compatible with install-sh 18 19for {set i 0} {$i < $argc} {incr i} { 20 set arg [lindex $argv $i] 21 switch -- $arg { 22 -c { 23 set doCopy 1 24 } 25 -m { 26 incr i 27 # Assume UNIX standard "644", etc, so force Tcl to think octal 28 set permissions 0[lindex $argv $i] 29 } 30 -o { 31 incr i 32 set owner [lindex $argv $i] 33 } 34 -g { 35 incr i 36 set group [lindex $argv $i] 37 } 38 -s { 39 set doStrip 1 40 } 41 -v { 42 set verbose 1 43 } 44 default { 45 set src $arg 46 incr i 47 set dst [lindex $argv $i] 48 break 49 } 50 } 51} 52if {[string length $src] == 0} { 53 puts stderr "$argv0: no input file specified" 54 exit 1 55} 56if {[string length $dst] == 0} { 57 puts stderr "$argv0: no destination file specified" 58 exit 1 59} 60 61# Compatibility with CYGNUS-style pathnames 62regsub {^/(cygdrive)?/(.)/(.*)} $src {\2:/\3} src 63regsub {^/(cygdrive)?/(.)/(.*)} $dst {\2:/\3} dst 64 65if {$verbose && $doStrip} { 66 puts stderr "Ignoring -s (strip) option for $dst" 67} 68if {[file isdirectory $dst]} { 69 set dst [file join $dst [file tail $src]] 70} 71 72# Temporary file name 73 74set dsttmp [file join [file dirname $dst] #inst.[pid]#] 75 76# Optimize out install if the file already exists 77 78set actions "" 79if {[file exists $dst] && 80 ([file mtime $src] == [file mtime $dst]) && 81 ([file size $src] == [file size $dst])} { 82 83 # Looks like the same file, so don't bother to copy. 84 # Set dsttmp in case we still need to tweak mode, group, etc. 85 86 set dsttmp $dst 87 lappend actions "already installed" 88} else { 89 if {"[file type $src]" == "link"} { 90 # Perfom a true copy. 91 set in [open $src r] 92 set out [open $dsttmp w] 93 fcopy $in $out 94 close $in 95 close $out 96 } else { 97 file copy -force $src $dsttmp 98 } 99 lappend actions copied 100} 101 102# update the modification time of the target file 103file mtime $dsttmp [clock seconds] 104 105# At this point "$dsttmp" is installed, but might not have the 106# right permissions and may need to be renamed. 107 108 109foreach attrName {owner group permissions} { 110 upvar 0 $attrName attr 111 112 if {[info exists attr]} { 113 if {![catch {file attributes $dsttmp -$attrName} dstattr]} { 114 115 # This system supports "$attrName" kind of attributes 116 117 if {($attr != $dstattr)} { 118 file attributes $dsttmp -$attrName $attr 119 lappend actions "set $attrName to $attr" 120 } 121 } 122 } 123} 124 125if {[string compare $dst $dsttmp] != 0} { 126 file rename -force $dsttmp $dst 127} 128if {$verbose} { 129 puts stderr "$dst: [join $actions ", "]" 130} 131exit 0 132