Mon, 20 Apr 2009 19:23:01 +0200
Add fingerprints config for client certificate based authentication.
1 #!@l_prefix@/lib/openpkg/bash
2 ##
3 ## lsync -- Access Layer Synchronization Tool
4 ## Copyright (c) 2000-2007 OpenPKG Foundation e.V. <http://openpkg.net/>
5 ## Copyright (c) 2000-2007 Ralf S. Engelschall <http://engelschall.com/>
6 ##
7 ## Permission to use, copy, modify, and distribute this software for
8 ## any purpose with or without fee is hereby granted, provided that
9 ## the above copyright notice and this permission notice appear in all
10 ## copies.
11 ##
12 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
13 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
14 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
15 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
16 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
17 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
18 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
22 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 ## SUCH DAMAGE.
24 ##
26 ##
27 ## filesystem hierarchy configuration
28 ##
30 # program name and version/date
31 progname="lsync"
32 progvers="1.0.4"
33 progdate="04-Aug-2001"
35 # root directory
36 # (if empty, .lsyncrc files provide default)
37 root=""
39 # subdirectory where packages are physically installed
40 pkgdir="PKG"
42 # subdirectories which are synchronized between physically
43 # installed package areas and access layer
44 subdirs="bin,sbin,man,info,include,lib"
46 ##
47 ## command line option parsing
48 ##
50 # default run-time modes
51 nop=0
52 quiet=0
53 trace=0
54 help=''
55 init=0
56 uninstall=0
57 local=0
59 # be aware of .lsyncrc files
60 cwd=`pwd`
61 while [ 1 ]; do
62 if [ -f "$cwd/.lsyncrc" ]; then
63 set -- `cat $cwd/.lsyncrc` "$@"
64 fi
65 [ ".$cwd" = ./ ] && break
66 cwd=`echo $cwd | sed -e 's;/[^/]*$;;' -e 's;^$;/;'`
67 done
68 if [ ".$HOME" != . -a -f "$HOME/.lsyncrc" ]; then
69 set -- `cat $HOME/.lsyncrc` "$@"
70 fi
72 # iterate over argument line
73 for opt
74 do
75 case $opt in
76 -*=*) arg=`echo "$opt" | sed 's/^[-_a-zA-Z0-9]*=//'` ;;
77 *) arg='' ;;
78 esac
79 case $opt in
80 -n|--nop ) nop=1 ;;
81 -q|--quiet ) quiet=1 ;;
82 -t|--trace ) trace=1 ;;
83 -v|--version ) version=1 ;;
84 -h|--help ) help="Usage" ;;
85 -i|--init ) init=1 ;;
86 -u|--uninstall ) uninstall=1 ;;
87 -l|--local ) local=1 ;;
88 --root=* ) root=$arg ;;
89 --pkgdir=* ) pkgdir=$arg ;;
90 --subdirs=* ) subdirs=$arg ;;
91 * ) help="Invalid option \`$opt'"; break ;;
92 esac
93 done
95 # error or usage message
96 if [ ".$help" != . ]; then
97 if [ ".$help" != ".Usage" ]; then
98 echo "$progname:ERROR: $help" 1>&2
99 fi
100 cat 1>&2 <<EOT
101 Usage: $progname [options]
103 Global options:
104 --version, -v display tool version information
105 --help, -h display usage information
106 --init, -i create an initial directory hierarchy
108 Run-time options:
109 --nop, -n perform no filesystem operations
110 --quiet, -q display no verbose messages
111 --trace, -t display performed filesystem operations
112 --local, -l process a local package area only
113 --uninstall, -u uninstall all files
115 Filesystem options:
116 --root=DIR override root directory
117 --pkgdir=DIR override package sub-directory
118 --subdirs=DIR override synchronized sub-directories
120 Current configuration:
121 root directory: $root
122 package root subdir: $pkgdir
123 synchronized subdirs: $subdirs
124 EOT
125 if [ ".$help" != ".Usage" ]; then
126 exit 2
127 else
128 exit 0
129 fi
130 fi
132 # version information
133 if [ ".$version" = .1 ]; then
134 echo "$progname $progvers ($progdate)"
135 exit 0
136 fi
138 # make sure a root directory was found or specified
139 if [ ".$root" = . ]; then
140 echo "$progname:ERROR: no root directory specified!" 1>&2
141 echo "$progname:HINT: use --root=DIR option explicitly on command line" 1>&2
142 echo "$progname:HINT: or implicitly inside an .lsyncrc file in your home" 1>&2
143 echo "$progname:HINT: directory or in any parent directory." 1>&2
144 exit 3
145 fi
147 ##
148 ## helper functions
149 ##
151 display_hd () {
152 if [ ".$headline" != . ]; then
153 if [ ".$quiet" = .0 ]; then
154 echo "$headline"
155 fi
156 headline=''
157 fi
158 }
160 display_op () {
161 if [ ".$quiet" = .0 ]; then
162 echo " $@"
163 fi
164 }
166 display_warning () {
167 echo "$progname:WARNING: $*" 1>&2
168 }
170 display_error () {
171 echo "$progname:ERROR: $*" 1>&2
172 }
174 perform_op () {
175 if [ ".$trace" = .1 ]; then
176 echo " \$ $@"
177 fi
178 if [ ".$nop" = .0 ]; then
179 eval "$@"
180 fi
181 }
183 ##
184 ## main processing
185 ##
187 # extend a "man" subdir to a complete list with subdirs
188 # in order to avoid special cases in the loop processing
189 manex=''
190 if [ ".$init" = .1 ]; then
191 manex='man'
192 fi
193 for i in 1 2 3 4 5 6 7 8; do
194 manex="$manex,man/man$i"
195 done
196 manex=`echo $manex | sed -e 's;^,;;'`
197 subdirs=`echo $subdirs | sed -e "s;man;$manex;"`
199 # special processing: create initial hierarchy
200 if [ ".$init" = .1 ]; then
201 if [ ! -d $root ]; then
202 echo "creating $root"
203 perform_op "mkdir $root" || exit 1
204 fi
205 for subdir in $pkgdir `IFS=,; echo $subdirs`; do
206 if [ ! -d "$root/$subdir" ]; then
207 echo "creating $root/$subdir"
208 perform_op "mkdir $root/$subdir" || exit 1
209 fi
210 done
211 exit 0
212 fi
214 # make sure the root directory actually exists
215 if [ ! -d "$root" ]; then
216 display_warning "root directory \`$root' does not exist"
217 exit 3
218 fi
220 # if processing is restricted to a local package area, pre-determine its name
221 if [ ".$local" = .1 ]; then
222 realroot=`cd $root; pwd`
223 realthis=`pwd`
224 pkgname=`expr "$realthis" : "^$realroot/$pkgdir/\\([^/]*\\).*"`
225 if [ ".$pkgname" = . ]; then
226 display_error "you are not staying under a local package sub-directory"
227 exit 3
228 fi
229 fi
231 # now perform the synchronization for each sub-directory...
232 for subdir in `IFS=,; echo $subdirs`; do
233 headline="$root/$subdir:"
235 # make sure the subdir actually exists in the access layer
236 if [ ! -d "$root/$subdir" ]; then
237 display_warning "access layer directory \`$root/$subdir' does not exist"
238 continue
239 fi
241 #
242 # PASS 1: remove dangling symbolic links in access layer
243 #
245 # iterate over all symlinks in the access layer subdir
246 for link in . `ls "$root/$subdir/" | sed -e "s;^$root/$subdir/*;;g"`; do
247 test ".$link" = ".." && continue
249 # determine the target file of the symlink
250 target=`ls -l "$root/$subdir/$link" 2>/dev/null | sed -e 's;.*-> *;;'`
251 if [ ".$target" = . ]; then
252 display_warning "$root/$subdir/$link seems to be not a symbolic link"
253 continue
254 fi
256 # (optionally) make sure that link target points into local package area
257 if [ ".$local" = .1 -a .`expr $target : "../$pkgdir/$pkgname/.*"` = .0 ]; then
258 continue
259 fi
261 # check whether link is valid, i.e., points to
262 # an existing target file or directory
263 if [ ".$uninstall" = .1 ] ||\
264 [ ! -f "$root/$subdir/$target" -a \
265 ! -d "$root/$subdir/$target" ]; then
266 # target no longer exists, so remove dangling symlink
267 display_hd
268 display_op "remove: $link -> $target"
269 perform_op "rm -f $root/$subdir/$link"
270 fi
271 done
273 # if we are uninstalling only, our work is now done
274 if [ ".$uninstall" = ".1" ]; then
275 continue
276 fi
278 #
279 # PASS 2: create new symbolic links in access layer
280 #
282 # calculate the corresponding reverse directory for the current subdir
283 revdir=`echo $subdir | sed -e 's;[^/][^/]*;..;g'`
285 # iterate over all package directories
286 for dir in . `ls "$root/$pkgdir/" | sed -e "s;^$root/$pkgdir/*;;g"`; do
287 test ".$dir" = ".." && continue
289 # (optionally) make sure that we operate only for the local package area
290 if [ ".$local" = .1 -a ".$dir" != ".$pkgname" ]; then
291 continue
292 fi
294 # skip all directories with appended version numbers
295 # in order to support manual versioning of packages
296 case $dir in
297 *-[0-9]* ) continue ;;
298 esac
300 # skip if package directory or package sub-directories has sticky bit set
301 if [ ".`ls -l -d $root/$pkgdir/$dir 2>/dev/null | cut -c10`" = .t ] ||\
302 [ ".`ls -l -d $root/$pkgdir/$dir/$subdir 2>/dev/null | cut -c10`" = .t ]; then
303 continue
304 fi
306 # check whether the processed subdir exists in package area
307 if [ -d "$root/$pkgdir/$dir/$subdir" ]; then
309 # iterate over all files/directories in package's subdir
310 for file in . `ls "$root/$pkgdir/$dir/$subdir/" |\
311 sed -e "s;^$root/$pkgdir/$dir/$subdir/*;;g"`; do
312 test ".$file" = ".." && continue
314 # calculate the access layer symlink target
315 target="$revdir/$pkgdir/$dir/$subdir/$file"
317 # check whether a possibly conflicting symlink exists
318 exlink=`ls -l $root/$subdir/$file 2>/dev/null`
319 if [ ".$exlink" != . ]; then
320 extarget=`echo $exlink | sed -e 's;.*-> *;;'`
321 if [ ".$extarget" = . ]; then
322 display_warning "$root/$subdir/$file exits, but seems to be not a symbolic link"
323 elif [ ".$extarget" != ".$target" ]; then
324 display_hd
325 display_op "conflict: $file -> $extarget [existing]"
326 display_op " $file -> $target [alternative]"
327 fi
328 continue
329 fi
331 # create new symlink in access layer
332 display_hd
333 display_op "create: $file -> $target"
334 perform_op "cd $root/$subdir && ln -s $target $file"
335 done
336 fi
337 done
338 done