This diff has been collapsed as it changes many lines, (527 lines changed) Show them Hide them | |||||
@@ -0,0 +1,527 | |||||
|
1 | #!/bin/sh | |||
|
2 | # install - install a program, script, or datafile | |||
|
3 | ||||
|
4 | scriptversion=2011-01-19.21; # UTC | |||
|
5 | ||||
|
6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was | |||
|
7 | # later released in X11R6 (xc/config/util/install.sh) with the | |||
|
8 | # following copyright and license. | |||
|
9 | # | |||
|
10 | # Copyright (C) 1994 X Consortium | |||
|
11 | # | |||
|
12 | # Permission is hereby granted, free of charge, to any person obtaining a copy | |||
|
13 | # of this software and associated documentation files (the "Software"), to | |||
|
14 | # deal in the Software without restriction, including without limitation the | |||
|
15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |||
|
16 | # sell copies of the Software, and to permit persons to whom the Software is | |||
|
17 | # furnished to do so, subject to the following conditions: | |||
|
18 | # | |||
|
19 | # The above copyright notice and this permission notice shall be included in | |||
|
20 | # all copies or substantial portions of the Software. | |||
|
21 | # | |||
|
22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
|
23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
|
24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
|
25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
|
26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- | |||
|
27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
|
28 | # | |||
|
29 | # Except as contained in this notice, the name of the X Consortium shall not | |||
|
30 | # be used in advertising or otherwise to promote the sale, use or other deal- | |||
|
31 | # ings in this Software without prior written authorization from the X Consor- | |||
|
32 | # tium. | |||
|
33 | # | |||
|
34 | # | |||
|
35 | # FSF changes to this file are in the public domain. | |||
|
36 | # | |||
|
37 | # Calling this script install-sh is preferred over install.sh, to prevent | |||
|
38 | # `make' implicit rules from creating a file called install from it | |||
|
39 | # when there is no Makefile. | |||
|
40 | # | |||
|
41 | # This script is compatible with the BSD install script, but was written | |||
|
42 | # from scratch. | |||
|
43 | ||||
|
44 | nl=' | |||
|
45 | ' | |||
|
46 | IFS=" "" $nl" | |||
|
47 | ||||
|
48 | # set DOITPROG to echo to test this script | |||
|
49 | ||||
|
50 | # Don't use :- since 4.3BSD and earlier shells don't like it. | |||
|
51 | doit=${DOITPROG-} | |||
|
52 | if test -z "$doit"; then | |||
|
53 | doit_exec=exec | |||
|
54 | else | |||
|
55 | doit_exec=$doit | |||
|
56 | fi | |||
|
57 | ||||
|
58 | # Put in absolute file names if you don't have them in your path; | |||
|
59 | # or use environment vars. | |||
|
60 | ||||
|
61 | chgrpprog=${CHGRPPROG-chgrp} | |||
|
62 | chmodprog=${CHMODPROG-chmod} | |||
|
63 | chownprog=${CHOWNPROG-chown} | |||
|
64 | cmpprog=${CMPPROG-cmp} | |||
|
65 | cpprog=${CPPROG-cp} | |||
|
66 | mkdirprog=${MKDIRPROG-mkdir} | |||
|
67 | mvprog=${MVPROG-mv} | |||
|
68 | rmprog=${RMPROG-rm} | |||
|
69 | stripprog=${STRIPPROG-strip} | |||
|
70 | ||||
|
71 | posix_glob='?' | |||
|
72 | initialize_posix_glob=' | |||
|
73 | test "$posix_glob" != "?" || { | |||
|
74 | if (set -f) 2>/dev/null; then | |||
|
75 | posix_glob= | |||
|
76 | else | |||
|
77 | posix_glob=: | |||
|
78 | fi | |||
|
79 | } | |||
|
80 | ' | |||
|
81 | ||||
|
82 | posix_mkdir= | |||
|
83 | ||||
|
84 | # Desired mode of installed file. | |||
|
85 | mode=0755 | |||
|
86 | ||||
|
87 | chgrpcmd= | |||
|
88 | chmodcmd=$chmodprog | |||
|
89 | chowncmd= | |||
|
90 | mvcmd=$mvprog | |||
|
91 | rmcmd="$rmprog -f" | |||
|
92 | stripcmd= | |||
|
93 | ||||
|
94 | src= | |||
|
95 | dst= | |||
|
96 | dir_arg= | |||
|
97 | dst_arg= | |||
|
98 | ||||
|
99 | copy_on_change=false | |||
|
100 | no_target_directory= | |||
|
101 | ||||
|
102 | usage="\ | |||
|
103 | Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE | |||
|
104 | or: $0 [OPTION]... SRCFILES... DIRECTORY | |||
|
105 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... | |||
|
106 | or: $0 [OPTION]... -d DIRECTORIES... | |||
|
107 | ||||
|
108 | In the 1st form, copy SRCFILE to DSTFILE. | |||
|
109 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. | |||
|
110 | In the 4th, create DIRECTORIES. | |||
|
111 | ||||
|
112 | Options: | |||
|
113 | --help display this help and exit. | |||
|
114 | --version display version info and exit. | |||
|
115 | ||||
|
116 | -c (ignored) | |||
|
117 | -C install only if different (preserve the last data modification time) | |||
|
118 | -d create directories instead of installing files. | |||
|
119 | -g GROUP $chgrpprog installed files to GROUP. | |||
|
120 | -m MODE $chmodprog installed files to MODE. | |||
|
121 | -o USER $chownprog installed files to USER. | |||
|
122 | -s $stripprog installed files. | |||
|
123 | -t DIRECTORY install into DIRECTORY. | |||
|
124 | -T report an error if DSTFILE is a directory. | |||
|
125 | ||||
|
126 | Environment variables override the default commands: | |||
|
127 | CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG | |||
|
128 | RMPROG STRIPPROG | |||
|
129 | " | |||
|
130 | ||||
|
131 | while test $# -ne 0; do | |||
|
132 | case $1 in | |||
|
133 | -c) ;; | |||
|
134 | ||||
|
135 | -C) copy_on_change=true;; | |||
|
136 | ||||
|
137 | -d) dir_arg=true;; | |||
|
138 | ||||
|
139 | -g) chgrpcmd="$chgrpprog $2" | |||
|
140 | shift;; | |||
|
141 | ||||
|
142 | --help) echo "$usage"; exit $?;; | |||
|
143 | ||||
|
144 | -m) mode=$2 | |||
|
145 | case $mode in | |||
|
146 | *' '* | *' '* | *' | |||
|
147 | '* | *'*'* | *'?'* | *'['*) | |||
|
148 | echo "$0: invalid mode: $mode" >&2 | |||
|
149 | exit 1;; | |||
|
150 | esac | |||
|
151 | shift;; | |||
|
152 | ||||
|
153 | -o) chowncmd="$chownprog $2" | |||
|
154 | shift;; | |||
|
155 | ||||
|
156 | -s) stripcmd=$stripprog;; | |||
|
157 | ||||
|
158 | -t) dst_arg=$2 | |||
|
159 | # Protect names problematic for `test' and other utilities. | |||
|
160 | case $dst_arg in | |||
|
161 | -* | [=\(\)!]) dst_arg=./$dst_arg;; | |||
|
162 | esac | |||
|
163 | shift;; | |||
|
164 | ||||
|
165 | -T) no_target_directory=true;; | |||
|
166 | ||||
|
167 | --version) echo "$0 $scriptversion"; exit $?;; | |||
|
168 | ||||
|
169 | --) shift | |||
|
170 | break;; | |||
|
171 | ||||
|
172 | -*) echo "$0: invalid option: $1" >&2 | |||
|
173 | exit 1;; | |||
|
174 | ||||
|
175 | *) break;; | |||
|
176 | esac | |||
|
177 | shift | |||
|
178 | done | |||
|
179 | ||||
|
180 | if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then | |||
|
181 | # When -d is used, all remaining arguments are directories to create. | |||
|
182 | # When -t is used, the destination is already specified. | |||
|
183 | # Otherwise, the last argument is the destination. Remove it from $@. | |||
|
184 | for arg | |||
|
185 | do | |||
|
186 | if test -n "$dst_arg"; then | |||
|
187 | # $@ is not empty: it contains at least $arg. | |||
|
188 | set fnord "$@" "$dst_arg" | |||
|
189 | shift # fnord | |||
|
190 | fi | |||
|
191 | shift # arg | |||
|
192 | dst_arg=$arg | |||
|
193 | # Protect names problematic for `test' and other utilities. | |||
|
194 | case $dst_arg in | |||
|
195 | -* | [=\(\)!]) dst_arg=./$dst_arg;; | |||
|
196 | esac | |||
|
197 | done | |||
|
198 | fi | |||
|
199 | ||||
|
200 | if test $# -eq 0; then | |||
|
201 | if test -z "$dir_arg"; then | |||
|
202 | echo "$0: no input file specified." >&2 | |||
|
203 | exit 1 | |||
|
204 | fi | |||
|
205 | # It's OK to call `install-sh -d' without argument. | |||
|
206 | # This can happen when creating conditional directories. | |||
|
207 | exit 0 | |||
|
208 | fi | |||
|
209 | ||||
|
210 | if test -z "$dir_arg"; then | |||
|
211 | do_exit='(exit $ret); exit $ret' | |||
|
212 | trap "ret=129; $do_exit" 1 | |||
|
213 | trap "ret=130; $do_exit" 2 | |||
|
214 | trap "ret=141; $do_exit" 13 | |||
|
215 | trap "ret=143; $do_exit" 15 | |||
|
216 | ||||
|
217 | # Set umask so as not to create temps with too-generous modes. | |||
|
218 | # However, 'strip' requires both read and write access to temps. | |||
|
219 | case $mode in | |||
|
220 | # Optimize common cases. | |||
|
221 | *644) cp_umask=133;; | |||
|
222 | *755) cp_umask=22;; | |||
|
223 | ||||
|
224 | *[0-7]) | |||
|
225 | if test -z "$stripcmd"; then | |||
|
226 | u_plus_rw= | |||
|
227 | else | |||
|
228 | u_plus_rw='% 200' | |||
|
229 | fi | |||
|
230 | cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; | |||
|
231 | *) | |||
|
232 | if test -z "$stripcmd"; then | |||
|
233 | u_plus_rw= | |||
|
234 | else | |||
|
235 | u_plus_rw=,u+rw | |||
|
236 | fi | |||
|
237 | cp_umask=$mode$u_plus_rw;; | |||
|
238 | esac | |||
|
239 | fi | |||
|
240 | ||||
|
241 | for src | |||
|
242 | do | |||
|
243 | # Protect names problematic for `test' and other utilities. | |||
|
244 | case $src in | |||
|
245 | -* | [=\(\)!]) src=./$src;; | |||
|
246 | esac | |||
|
247 | ||||
|
248 | if test -n "$dir_arg"; then | |||
|
249 | dst=$src | |||
|
250 | dstdir=$dst | |||
|
251 | test -d "$dstdir" | |||
|
252 | dstdir_status=$? | |||
|
253 | else | |||
|
254 | ||||
|
255 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command | |||
|
256 | # might cause directories to be created, which would be especially bad | |||
|
257 | # if $src (and thus $dsttmp) contains '*'. | |||
|
258 | if test ! -f "$src" && test ! -d "$src"; then | |||
|
259 | echo "$0: $src does not exist." >&2 | |||
|
260 | exit 1 | |||
|
261 | fi | |||
|
262 | ||||
|
263 | if test -z "$dst_arg"; then | |||
|
264 | echo "$0: no destination specified." >&2 | |||
|
265 | exit 1 | |||
|
266 | fi | |||
|
267 | dst=$dst_arg | |||
|
268 | ||||
|
269 | # If destination is a directory, append the input filename; won't work | |||
|
270 | # if double slashes aren't ignored. | |||
|
271 | if test -d "$dst"; then | |||
|
272 | if test -n "$no_target_directory"; then | |||
|
273 | echo "$0: $dst_arg: Is a directory" >&2 | |||
|
274 | exit 1 | |||
|
275 | fi | |||
|
276 | dstdir=$dst | |||
|
277 | dst=$dstdir/`basename "$src"` | |||
|
278 | dstdir_status=0 | |||
|
279 | else | |||
|
280 | # Prefer dirname, but fall back on a substitute if dirname fails. | |||
|
281 | dstdir=` | |||
|
282 | (dirname "$dst") 2>/dev/null || | |||
|
283 | expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ | |||
|
284 | X"$dst" : 'X\(//\)[^/]' \| \ | |||
|
285 | X"$dst" : 'X\(//\)$' \| \ | |||
|
286 | X"$dst" : 'X\(/\)' \| . 2>/dev/null || | |||
|
287 | echo X"$dst" | | |||
|
288 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ | |||
|
289 | s//\1/ | |||
|
290 | q | |||
|
291 | } | |||
|
292 | /^X\(\/\/\)[^/].*/{ | |||
|
293 | s//\1/ | |||
|
294 | q | |||
|
295 | } | |||
|
296 | /^X\(\/\/\)$/{ | |||
|
297 | s//\1/ | |||
|
298 | q | |||
|
299 | } | |||
|
300 | /^X\(\/\).*/{ | |||
|
301 | s//\1/ | |||
|
302 | q | |||
|
303 | } | |||
|
304 | s/.*/./; q' | |||
|
305 | ` | |||
|
306 | ||||
|
307 | test -d "$dstdir" | |||
|
308 | dstdir_status=$? | |||
|
309 | fi | |||
|
310 | fi | |||
|
311 | ||||
|
312 | obsolete_mkdir_used=false | |||
|
313 | ||||
|
314 | if test $dstdir_status != 0; then | |||
|
315 | case $posix_mkdir in | |||
|
316 | '') | |||
|
317 | # Create intermediate dirs using mode 755 as modified by the umask. | |||
|
318 | # This is like FreeBSD 'install' as of 1997-10-28. | |||
|
319 | umask=`umask` | |||
|
320 | case $stripcmd.$umask in | |||
|
321 | # Optimize common cases. | |||
|
322 | *[2367][2367]) mkdir_umask=$umask;; | |||
|
323 | .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; | |||
|
324 | ||||
|
325 | *[0-7]) | |||
|
326 | mkdir_umask=`expr $umask + 22 \ | |||
|
327 | - $umask % 100 % 40 + $umask % 20 \ | |||
|
328 | - $umask % 10 % 4 + $umask % 2 | |||
|
329 | `;; | |||
|
330 | *) mkdir_umask=$umask,go-w;; | |||
|
331 | esac | |||
|
332 | ||||
|
333 | # With -d, create the new directory with the user-specified mode. | |||
|
334 | # Otherwise, rely on $mkdir_umask. | |||
|
335 | if test -n "$dir_arg"; then | |||
|
336 | mkdir_mode=-m$mode | |||
|
337 | else | |||
|
338 | mkdir_mode= | |||
|
339 | fi | |||
|
340 | ||||
|
341 | posix_mkdir=false | |||
|
342 | case $umask in | |||
|
343 | *[123567][0-7][0-7]) | |||
|
344 | # POSIX mkdir -p sets u+wx bits regardless of umask, which | |||
|
345 | # is incompatible with FreeBSD 'install' when (umask & 300) != 0. | |||
|
346 | ;; | |||
|
347 | *) | |||
|
348 | tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ | |||
|
349 | trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 | |||
|
350 | ||||
|
351 | if (umask $mkdir_umask && | |||
|
352 | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 | |||
|
353 | then | |||
|
354 | if test -z "$dir_arg" || { | |||
|
355 | # Check for POSIX incompatibilities with -m. | |||
|
356 | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or | |||
|
357 | # other-writeable bit of parent directory when it shouldn't. | |||
|
358 | # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. | |||
|
359 | ls_ld_tmpdir=`ls -ld "$tmpdir"` | |||
|
360 | case $ls_ld_tmpdir in | |||
|
361 | d????-?r-*) different_mode=700;; | |||
|
362 | d????-?--*) different_mode=755;; | |||
|
363 | *) false;; | |||
|
364 | esac && | |||
|
365 | $mkdirprog -m$different_mode -p -- "$tmpdir" && { | |||
|
366 | ls_ld_tmpdir_1=`ls -ld "$tmpdir"` | |||
|
367 | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" | |||
|
368 | } | |||
|
369 | } | |||
|
370 | then posix_mkdir=: | |||
|
371 | fi | |||
|
372 | rmdir "$tmpdir/d" "$tmpdir" | |||
|
373 | else | |||
|
374 | # Remove any dirs left behind by ancient mkdir implementations. | |||
|
375 | rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null | |||
|
376 | fi | |||
|
377 | trap '' 0;; | |||
|
378 | esac;; | |||
|
379 | esac | |||
|
380 | ||||
|
381 | if | |||
|
382 | $posix_mkdir && ( | |||
|
383 | umask $mkdir_umask && | |||
|
384 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" | |||
|
385 | ) | |||
|
386 | then : | |||
|
387 | else | |||
|
388 | ||||
|
389 | # The umask is ridiculous, or mkdir does not conform to POSIX, | |||
|
390 | # or it failed possibly due to a race condition. Create the | |||
|
391 | # directory the slow way, step by step, checking for races as we go. | |||
|
392 | ||||
|
393 | case $dstdir in | |||
|
394 | /*) prefix='/';; | |||
|
395 | [-=\(\)!]*) prefix='./';; | |||
|
396 | *) prefix='';; | |||
|
397 | esac | |||
|
398 | ||||
|
399 | eval "$initialize_posix_glob" | |||
|
400 | ||||
|
401 | oIFS=$IFS | |||
|
402 | IFS=/ | |||
|
403 | $posix_glob set -f | |||
|
404 | set fnord $dstdir | |||
|
405 | shift | |||
|
406 | $posix_glob set +f | |||
|
407 | IFS=$oIFS | |||
|
408 | ||||
|
409 | prefixes= | |||
|
410 | ||||
|
411 | for d | |||
|
412 | do | |||
|
413 | test X"$d" = X && continue | |||
|
414 | ||||
|
415 | prefix=$prefix$d | |||
|
416 | if test -d "$prefix"; then | |||
|
417 | prefixes= | |||
|
418 | else | |||
|
419 | if $posix_mkdir; then | |||
|
420 | (umask=$mkdir_umask && | |||
|
421 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break | |||
|
422 | # Don't fail if two instances are running concurrently. | |||
|
423 | test -d "$prefix" || exit 1 | |||
|
424 | else | |||
|
425 | case $prefix in | |||
|
426 | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; | |||
|
427 | *) qprefix=$prefix;; | |||
|
428 | esac | |||
|
429 | prefixes="$prefixes '$qprefix'" | |||
|
430 | fi | |||
|
431 | fi | |||
|
432 | prefix=$prefix/ | |||
|
433 | done | |||
|
434 | ||||
|
435 | if test -n "$prefixes"; then | |||
|
436 | # Don't fail if two instances are running concurrently. | |||
|
437 | (umask $mkdir_umask && | |||
|
438 | eval "\$doit_exec \$mkdirprog $prefixes") || | |||
|
439 | test -d "$dstdir" || exit 1 | |||
|
440 | obsolete_mkdir_used=true | |||
|
441 | fi | |||
|
442 | fi | |||
|
443 | fi | |||
|
444 | ||||
|
445 | if test -n "$dir_arg"; then | |||
|
446 | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && | |||
|
447 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && | |||
|
448 | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || | |||
|
449 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 | |||
|
450 | else | |||
|
451 | ||||
|
452 | # Make a couple of temp file names in the proper directory. | |||
|
453 | dsttmp=$dstdir/_inst.$$_ | |||
|
454 | rmtmp=$dstdir/_rm.$$_ | |||
|
455 | ||||
|
456 | # Trap to clean up those temp files at exit. | |||
|
457 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 | |||
|
458 | ||||
|
459 | # Copy the file name to the temp name. | |||
|
460 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && | |||
|
461 | ||||
|
462 | # and set any options; do chmod last to preserve setuid bits. | |||
|
463 | # | |||
|
464 | # If any of these fail, we abort the whole thing. If we want to | |||
|
465 | # ignore errors from any of these, just make sure not to ignore | |||
|
466 | # errors from the above "$doit $cpprog $src $dsttmp" command. | |||
|
467 | # | |||
|
468 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && | |||
|
469 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && | |||
|
470 | { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && | |||
|
471 | { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && | |||
|
472 | ||||
|
473 | # If -C, don't bother to copy if it wouldn't change the file. | |||
|
474 | if $copy_on_change && | |||
|
475 | old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && | |||
|
476 | new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && | |||
|
477 | ||||
|
478 | eval "$initialize_posix_glob" && | |||
|
479 | $posix_glob set -f && | |||
|
480 | set X $old && old=:$2:$4:$5:$6 && | |||
|
481 | set X $new && new=:$2:$4:$5:$6 && | |||
|
482 | $posix_glob set +f && | |||
|
483 | ||||
|
484 | test "$old" = "$new" && | |||
|
485 | $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 | |||
|
486 | then | |||
|
487 | rm -f "$dsttmp" | |||
|
488 | else | |||
|
489 | # Rename the file to the real destination. | |||
|
490 | $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || | |||
|
491 | ||||
|
492 | # The rename failed, perhaps because mv can't rename something else | |||
|
493 | # to itself, or perhaps because mv is so ancient that it does not | |||
|
494 | # support -f. | |||
|
495 | { | |||
|
496 | # Now remove or move aside any old file at destination location. | |||
|
497 | # We try this two ways since rm can't unlink itself on some | |||
|
498 | # systems and the destination file might be busy for other | |||
|
499 | # reasons. In this case, the final cleanup might fail but the new | |||
|
500 | # file should still install successfully. | |||
|
501 | { | |||
|
502 | test ! -f "$dst" || | |||
|
503 | $doit $rmcmd -f "$dst" 2>/dev/null || | |||
|
504 | { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && | |||
|
505 | { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } | |||
|
506 | } || | |||
|
507 | { echo "$0: cannot unlink or rename $dst" >&2 | |||
|
508 | (exit 1); exit 1 | |||
|
509 | } | |||
|
510 | } && | |||
|
511 | ||||
|
512 | # Now rename the file to the real destination. | |||
|
513 | $doit $mvcmd "$dsttmp" "$dst" | |||
|
514 | } | |||
|
515 | fi || exit 1 | |||
|
516 | ||||
|
517 | trap '' 0 | |||
|
518 | fi | |||
|
519 | done | |||
|
520 | ||||
|
521 | # Local variables: | |||
|
522 | # eval: (add-hook 'write-file-hooks 'time-stamp) | |||
|
523 | # time-stamp-start: "scriptversion=" | |||
|
524 | # time-stamp-format: "%:y-%02m-%02d.%02H" | |||
|
525 | # time-stamp-time-zone: "UTC" | |||
|
526 | # time-stamp-end: "; # UTC" | |||
|
527 | # End: |
@@ -9,16 +9,21 AC_CONFIG_HEADERS([src/rs232config.h]) | |||||
9 |
|
9 | |||
10 | AC_PROG_CC |
|
10 | AC_PROG_CC | |
11 | AM_PROG_CC_STDC |
|
11 | AM_PROG_CC_STDC | |
|
12 | AC_PROG_INSTALL | |||
12 | AC_C_CONST |
|
13 | AC_C_CONST | |
13 | AC_LIBTOOL_WIN32_DLL |
|
14 | AC_LIBTOOL_WIN32_DLL | |
14 | AM_PROG_LIBTOOL |
|
15 | AM_PROG_LIBTOOL | |
|
16 | AC_PROG_LN_S | |||
|
17 | AC_PROG_MAKE_SET | |||
|
18 | AC_PROG_RANLIB | |||
|
19 | ||||
15 | #LT_INIT |
|
20 | #LT_INIT | |
16 | #AC_PROG_MAKE_SET |
|
21 | #AC_PROG_MAKE_SET | |
17 |
|
22 | |||
18 | # Checks for libraries. |
|
23 | # Checks for libraries. | |
19 |
|
24 | |||
20 | # Checks for header files. |
|
25 | # Checks for header files. | |
21 | AC_CHECK_HEADERS([stdio.h string.h fcntl.h errno.h unistd.h termios.h termio.h windows.h]) |
|
26 | AC_CHECK_HEADERS([stdio.h string.h fcntl.h errno.h unistd.h termios.h termio.h dirent.h windows.h]) | |
22 |
|
27 | |||
23 | AC_SUBST([RS232_SO_VERSION], [2:1:0]) |
|
28 | AC_SUBST([RS232_SO_VERSION], [2:1:0]) | |
24 | AC_SUBST([RS232_API_VERSION], [2.1]) |
|
29 | AC_SUBST([RS232_API_VERSION], [2.1]) |
@@ -4,7 +4,7 libdir=@libdir@ | |||||
4 | includedir=@includedir@ |
|
4 | includedir=@includedir@ | |
5 |
|
5 | |||
6 | Name: @PACKAGE_NAME@ |
|
6 | Name: @PACKAGE_NAME@ | |
7 |
Description: |
|
7 | Description: Standard RS232 library. | |
8 | Version: @PACKAGE_VERSION@ |
|
8 | Version: @PACKAGE_VERSION@ | |
9 | URL: @PACKAGE_URL@ |
|
9 | URL: @PACKAGE_URL@ | |
10 | Libs: -L${libdir} -lrs232-@RS232_API_VERSION@ |
|
10 | Libs: -L${libdir} -lrs232-@RS232_API_VERSION@ |
@@ -4,7 +4,12 | |||||
4 | #include <string.h> |
|
4 | #include <string.h> | |
5 | #include <errno.h> |
|
5 | #include <errno.h> | |
6 | #include <malloc.h> |
|
6 | #include <malloc.h> | |
|
7 | #include <dirent.h> | |||
|
8 | #include <limits.h> | |||
|
9 | #include <stdlib.h> | |||
|
10 | #include <sys/stat.h> | |||
7 | #include "rs232config.h" |
|
11 | #include "rs232config.h" | |
|
12 | ||||
8 | #ifdef HAVE_TERMIOS_H |
|
13 | #ifdef HAVE_TERMIOS_H | |
9 | #include <termios.h> |
|
14 | #include <termios.h> | |
10 | #endif |
|
15 | #endif | |
@@ -45,13 +50,69 int rs232close(rs232port_t fd) | |||||
45 |
|
50 | |||
46 | rs232portslist_t* rs232getportlist() |
|
51 | rs232portslist_t* rs232getportlist() | |
47 | { |
|
52 | { | |
|
53 | struct dirent *dp; | |||
|
54 | char* path="/dev/serial/by-id"; | |||
|
55 | DIR *dir = opendir(path); | |||
|
56 | rs232portslist_t* firstitem=NULL; | |||
|
57 | rs232portslist_t* previtem=NULL; | |||
|
58 | char linkname[1024]; | |||
|
59 | int i=0; | |||
|
60 | if(dir!=NULL) | |||
|
61 | { | |||
|
62 | while ((dp=readdir(dir)) != NULL) | |||
|
63 | { | |||
|
64 | char* name = (char*)malloc(1024); | |||
|
65 | for(i=0;i<1024;i++) | |||
|
66 | { | |||
|
67 | name[i]='\0'; | |||
|
68 | linkname[i]='\0'; | |||
|
69 | } | |||
|
70 | struct stat statbuf; | |||
|
71 | strcpy(linkname,path); | |||
|
72 | strcat(linkname,"/"); | |||
|
73 | strcat(linkname,dp->d_name); | |||
|
74 | lstat(linkname, &statbuf); | |||
|
75 | if(S_ISLNK(statbuf.st_mode)) | |||
|
76 | { | |||
|
77 | if(-1!=readlink(linkname,name,1024)) | |||
|
78 | { | |||
|
79 | for(i=0;i<1024;i++) | |||
|
80 | { | |||
|
81 | linkname[i]='\0'; | |||
|
82 | } | |||
|
83 | strcpy(linkname,path); | |||
|
84 | strcat(linkname,"/"); | |||
|
85 | strcat(linkname,name); | |||
|
86 | for(i=0;i<1024;i++) | |||
|
87 | { | |||
|
88 | name[i]='\0'; | |||
|
89 | } | |||
|
90 | if(NULL!=realpath(linkname, name)) | |||
|
91 | { | |||
|
92 | rs232portslist_t* item = (rs232portslist_t*)malloc(sizeof(rs232portslist_t)); | |||
|
93 | item->name = name; | |||
|
94 | item->next = NULL; | |||
|
95 | if(NULL!=previtem)previtem->next = item; | |||
|
96 | previtem = item; | |||
|
97 | if(NULL==firstitem)firstitem = item; | |||
|
98 | } | |||
48 |
|
99 | |||
|
100 | } | |||
|
101 | } | |||
49 |
|
102 | |||
50 | } |
|
103 | } | |
|
104 | } | |||
|
105 | return firstitem; | |||
|
106 | } | |||
51 |
|
107 | |||
52 | void rs232deleteportlist(rs232portslist_t* list) |
|
108 | void rs232deleteportlist(rs232portslist_t* list) | |
53 | { |
|
109 | { | |
54 |
|
110 | if(list!=NULL) | ||
|
111 | { | |||
|
112 | if(list->next != NULL) | |||
|
113 | rs232deleteportlist(list->next); | |||
|
114 | free(list); | |||
|
115 | } | |||
55 | } |
|
116 | } | |
56 |
|
117 | |||
57 | int rs232setup(rs232port_t fd, int ChSize, int BaudeRate, rs232parity Parity, rs232stop NbStop) |
|
118 | int rs232setup(rs232port_t fd, int ChSize, int BaudeRate, rs232parity Parity, rs232stop NbStop) |
@@ -124,14 +124,44 int rs232close(rs232port_t fd) | |||||
124 | } |
|
124 | } | |
125 | } |
|
125 | } | |
126 |
|
126 | |||
127 | rs232portslist_t* rs232getportlist() |
|
127 | rs232portslist_t* rs232getportlist() //here is the very dirty way! | |
|
128 | { | |||
|
129 | int i=0; | |||
|
130 | char* devName="COM111"; | |||
|
131 | rs232port_t testport; | |||
|
132 | rs232portslist_t* firstitem=NULL; | |||
|
133 | rs232portslist_t* previtem=NULL; | |||
|
134 | for(i=0;i<256;i++) | |||
128 | { |
|
135 | { | |
129 |
|
136 | devName[3] = '\0'; | ||
|
137 | devName[4] = '\0'; | |||
|
138 | devName[5] = '\0'; | |||
|
139 | devName[6] = '\0'; | |||
|
140 | sprintf(devName+3,"%d",i); | |||
|
141 | testport= rs232open(devName); | |||
|
142 | if(testport != (rs232port_t)badPortValue) | |||
|
143 | { | |||
|
144 | rs232portslist_t* item = (rs232portslist_t*)malloc(sizeof(rs232portslist_t)); | |||
|
145 | char* name = (char*)malloc(7); | |||
|
146 | strcpy(name,devName); | |||
|
147 | item->name = name; | |||
|
148 | item->next = NULL; | |||
|
149 | if(NULL!=previtem)previtem->next = item; | |||
|
150 | previtem = item; | |||
|
151 | if(NULL==firstitem)firstitem = item; | |||
|
152 | } | |||
|
153 | } | |||
|
154 | return firstitem; | |||
130 | } |
|
155 | } | |
131 |
|
156 | |||
132 | void rs232deleteportlist(rs232portslist_t* list) |
|
157 | void rs232deleteportlist(rs232portslist_t* list) | |
133 | { |
|
158 | { | |
134 |
|
159 | if(list!=NULL) | ||
|
160 | { | |||
|
161 | if(list->next != NULL) | |||
|
162 | rs232deleteportlist(list->next); | |||
|
163 | free(list); | |||
|
164 | } | |||
135 | } |
|
165 | } | |
136 |
|
166 | |||
137 |
|
167 |
@@ -1,5 +1,8 | |||||
1 | /* src/rs232config.h.in. Generated from configure.ac by autoheader. */ |
|
1 | /* src/rs232config.h.in. Generated from configure.ac by autoheader. */ | |
2 |
|
2 | |||
|
3 | /* Define to 1 if you have the <dirent.h> header file. */ | |||
|
4 | #undef HAVE_DIRENT_H | |||
|
5 | ||||
3 | /* Define to 1 if you have the <dlfcn.h> header file. */ |
|
6 | /* Define to 1 if you have the <dlfcn.h> header file. */ | |
4 | #undef HAVE_DLFCN_H |
|
7 | #undef HAVE_DLFCN_H | |
5 |
|
8 |
General Comments 0
You need to be logged in to leave comments.
Login now