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: |
@@ -1,30 +1,35 | |||
|
1 | 1 | # -*- Autoconf -*- |
|
2 | 2 | # Process this file with autoconf to produce a configure script. |
|
3 | 3 | AC_PREREQ([2.67]) |
|
4 | 4 | AC_INIT([librs232],[2.1.0],[alexis.jeandet@lpp.polytechnique.fr],[rs232],[http://www.lpp.fr]) |
|
5 | 5 | AM_INIT_AUTOMAKE([1.10 -Wall foreign]) |
|
6 | 6 | AC_CONFIG_MACRO_DIR([m4]) |
|
7 | 7 | # Checks for programs. |
|
8 | 8 | AC_CONFIG_HEADERS([src/rs232config.h]) |
|
9 | 9 | |
|
10 | 10 | AC_PROG_CC |
|
11 | 11 | AM_PROG_CC_STDC |
|
12 | AC_PROG_INSTALL | |
|
12 | 13 | AC_C_CONST |
|
13 | 14 | AC_LIBTOOL_WIN32_DLL |
|
14 | 15 | AM_PROG_LIBTOOL |
|
16 | AC_PROG_LN_S | |
|
17 | AC_PROG_MAKE_SET | |
|
18 | AC_PROG_RANLIB | |
|
19 | ||
|
15 | 20 | #LT_INIT |
|
16 | 21 | #AC_PROG_MAKE_SET |
|
17 | 22 | |
|
18 | 23 | # Checks for libraries. |
|
19 | 24 | |
|
20 | 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 | 28 | AC_SUBST([RS232_SO_VERSION], [2:1:0]) |
|
24 | 29 | AC_SUBST([RS232_API_VERSION], [2.1]) |
|
25 | 30 | # Checks for typedefs, structures, and compiler characteristics. |
|
26 | 31 | |
|
27 | 32 | # Checks for library functions. |
|
28 | 33 | AC_CONFIG_FILES([Makefile src/Makefile rs232-${RS232_API_VERSION}.pc:rs232.pc.in]) |
|
29 | 34 | |
|
30 | 35 | AC_OUTPUT |
@@ -1,11 +1,11 | |||
|
1 | 1 | prefix=@prefix@ |
|
2 | 2 | exec_prefix=@exec_prefix@ |
|
3 | 3 | libdir=@libdir@ |
|
4 | 4 | includedir=@includedir@ |
|
5 | 5 | |
|
6 | 6 | Name: @PACKAGE_NAME@ |
|
7 |
Description: |
|
|
7 | Description: Standard RS232 library. | |
|
8 | 8 | Version: @PACKAGE_VERSION@ |
|
9 | 9 | URL: @PACKAGE_URL@ |
|
10 | 10 | Libs: -L${libdir} -lrs232-@RS232_API_VERSION@ |
|
11 | 11 | Cflags: -I${includedir}/rs232-@RS232_API_VERSION@ -I${libdir}/rs232-@RS232_API_VERSION@/include |
@@ -1,455 +1,516 | |||
|
1 | 1 | #include <stdio.h> |
|
2 | 2 | #include <unistd.h> |
|
3 | 3 | #include <fcntl.h> |
|
4 | 4 | #include <string.h> |
|
5 | 5 | #include <errno.h> |
|
6 | 6 | #include <malloc.h> |
|
7 | #include <dirent.h> | |
|
8 | #include <limits.h> | |
|
9 | #include <stdlib.h> | |
|
10 | #include <sys/stat.h> | |
|
7 | 11 | #include "rs232config.h" |
|
12 | ||
|
8 | 13 | #ifdef HAVE_TERMIOS_H |
|
9 | 14 | #include <termios.h> |
|
10 | 15 | #endif |
|
11 | 16 | #ifdef HAVE_TERMIO_H |
|
12 | 17 | #include <termio.h> |
|
13 | 18 | #endif |
|
14 | 19 | #include "RS232.h" |
|
15 | 20 | |
|
16 | 21 | #ifdef HAVE_WINDOWS_H |
|
17 | 22 | #else |
|
18 | 23 | #ifdef HAVE_TERMIOS_H |
|
19 | 24 | rs232speed_t rs232cfspeed(unsigned int BaudeRate); |
|
20 | 25 | |
|
21 | 26 | rs232port_t rs232open(char* psPortName) |
|
22 | 27 | { |
|
23 | 28 | rs232port_t fd; |
|
24 | 29 | fd = (rs232port_t)open(psPortName, O_RDWR | O_NOCTTY | O_NDELAY); |
|
25 | 30 | fcntl((int)fd, F_SETFL, 0); |
|
26 | 31 | //fd = open(psPortName, O_RDWR | O_NOCTTY); |
|
27 | 32 | #ifdef debug |
|
28 | 33 | if(fd==-1)printf("can't open Port\n"); |
|
29 | 34 | #endif |
|
30 | 35 | return fd; |
|
31 | 36 | } |
|
32 | 37 | |
|
33 | 38 | int rs232close(rs232port_t fd) |
|
34 | 39 | { |
|
35 | 40 | if ((int)fd == -1) |
|
36 | 41 | { |
|
37 | 42 | return -1; |
|
38 | 43 | } |
|
39 | 44 | else |
|
40 | 45 | { |
|
41 | 46 | close(fd); |
|
42 | 47 | return 0; |
|
43 | 48 | } |
|
44 | 49 | } |
|
45 | 50 | |
|
46 | 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 | 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 | 118 | int rs232setup(rs232port_t fd, int ChSize, int BaudeRate, rs232parity Parity, rs232stop NbStop) |
|
58 | 119 | { |
|
59 | 120 | if ((int)fd == -1) |
|
60 | 121 | { |
|
61 | 122 | return -1; |
|
62 | 123 | } |
|
63 | 124 | else |
|
64 | 125 | { |
|
65 | 126 | struct termios terminos; |
|
66 | 127 | tcgetattr(fd, &terminos); |
|
67 | 128 | cfsetispeed(&terminos, rs232cfspeed(BaudeRate)); |
|
68 | 129 | cfsetospeed(&terminos, rs232cfspeed(BaudeRate)); |
|
69 | 130 | terminos.c_cflag |= (CLOCAL | CREAD); |
|
70 | 131 | rs232cfparity((int)fd, &terminos, Parity); |
|
71 | 132 | rs232cfnbstop((int)fd, &terminos, NbStop); |
|
72 | 133 | rs232cfcsize((int)fd, &terminos, ChSize); |
|
73 | 134 | terminos.c_cc[VMIN]=0; |
|
74 | 135 | terminos.c_cc[VTIME]=1; |
|
75 | 136 | tcflush(fd, TCIFLUSH); |
|
76 | 137 | #ifdef debug |
|
77 | 138 | if(tcsetattr(fd, TCSANOW, &terminos)!=0)printf("bad setup\n"); |
|
78 | 139 | #else |
|
79 | 140 | tcsetattr(fd, TCSANOW, &terminos); |
|
80 | 141 | #endif |
|
81 | 142 | return 0; |
|
82 | 143 | } |
|
83 | 144 | } |
|
84 | 145 | |
|
85 | 146 | int rs232setbaudrate(rs232port_t fd, int baudrate) |
|
86 | 147 | { |
|
87 | 148 | if ((int)fd == -1) |
|
88 | 149 | { |
|
89 | 150 | return fd; |
|
90 | 151 | } |
|
91 | 152 | else |
|
92 | 153 | { |
|
93 | 154 | struct termios terminos; |
|
94 | 155 | tcgetattr((int)fd, &terminos); |
|
95 | 156 | cfsetispeed(&terminos, rs232cfspeed(baudrate)); |
|
96 | 157 | cfsetospeed(&terminos, rs232cfspeed(baudrate)); |
|
97 | 158 | tcsetattr((int)fd, TCSANOW, &terminos); |
|
98 | 159 | return 0; |
|
99 | 160 | } |
|
100 | 161 | } |
|
101 | 162 | |
|
102 | 163 | int rs232setparity(rs232port_t fd, rs232parity Parity) |
|
103 | 164 | { |
|
104 | 165 | if ((int)fd == -1) |
|
105 | 166 | { |
|
106 | 167 | return fd; |
|
107 | 168 | } |
|
108 | 169 | else |
|
109 | 170 | { |
|
110 | 171 | struct termios terminos; |
|
111 | 172 | tcgetattr((int)fd, &terminos); |
|
112 | 173 | terminos.c_cflag &= ~PARENB; |
|
113 | 174 | terminos.c_cflag &= ~PARODD; |
|
114 | 175 | switch(Parity) |
|
115 | 176 | { |
|
116 | 177 | case rs232parityNo: |
|
117 | 178 | terminos.c_cflag &= ~PARENB; |
|
118 | 179 | break; |
|
119 | 180 | case rs232parityOdd: |
|
120 | 181 | terminos.c_cflag |= PARENB; |
|
121 | 182 | terminos.c_cflag |= PARODD; |
|
122 | 183 | break; |
|
123 | 184 | case rs232parityEven: |
|
124 | 185 | terminos.c_cflag |= PARENB; |
|
125 | 186 | terminos.c_cflag &= ~PARODD; |
|
126 | 187 | break; |
|
127 | 188 | default: |
|
128 | 189 | terminos.c_cflag &= ~PARENB; |
|
129 | 190 | break; |
|
130 | 191 | } |
|
131 | 192 | tcsetattr((int)fd, TCSANOW, &terminos); |
|
132 | 193 | return 0; |
|
133 | 194 | } |
|
134 | 195 | } |
|
135 | 196 | |
|
136 | 197 | int rs232setnbstop(rs232port_t fd, rs232stop NbStop) |
|
137 | 198 | { |
|
138 | 199 | if ((int)fd == -1) |
|
139 | 200 | { |
|
140 | 201 | return fd; |
|
141 | 202 | } |
|
142 | 203 | else |
|
143 | 204 | { |
|
144 | 205 | struct termios terminos; |
|
145 | 206 | tcgetattr((int)fd, &terminos); |
|
146 | 207 | switch(NbStop) |
|
147 | 208 | { |
|
148 | 209 | case rs232OneStop: |
|
149 | 210 | terminos.c_cflag &= ~CSTOPB; |
|
150 | 211 | break; |
|
151 | 212 | case rs232One5Stop: |
|
152 | 213 | terminos.c_cflag |= CSTOPB; |
|
153 | 214 | break; |
|
154 | 215 | case rs232TwoStop: |
|
155 | 216 | terminos.c_cflag |= CSTOPB; |
|
156 | 217 | break; |
|
157 | 218 | default: |
|
158 | 219 | terminos.c_cflag &= ~CSTOPB; |
|
159 | 220 | break; |
|
160 | 221 | } |
|
161 | 222 | tcsetattr((int)fd, TCSANOW, &terminos); |
|
162 | 223 | return 0; |
|
163 | 224 | } |
|
164 | 225 | } |
|
165 | 226 | |
|
166 | 227 | |
|
167 | 228 | int rs232setcsize(rs232port_t fd, int ChSize) |
|
168 | 229 | { |
|
169 | 230 | if ((int)fd == -1) |
|
170 | 231 | { |
|
171 | 232 | return fd; |
|
172 | 233 | } |
|
173 | 234 | else |
|
174 | 235 | { |
|
175 | 236 | struct termios terminos; |
|
176 | 237 | tcgetattr((int)fd, &terminos); |
|
177 | 238 | terminos.c_cflag &= ~CSIZE; |
|
178 | 239 | switch(ChSize) |
|
179 | 240 | { |
|
180 | 241 | case 5: |
|
181 | 242 | terminos.c_cflag |= CS5; |
|
182 | 243 | break; |
|
183 | 244 | case 6: |
|
184 | 245 | terminos.c_cflag |= CS6; |
|
185 | 246 | break; |
|
186 | 247 | case 7: |
|
187 | 248 | terminos.c_cflag |= CS7; |
|
188 | 249 | break; |
|
189 | 250 | default: |
|
190 | 251 | terminos.c_cflag |= CS8; |
|
191 | 252 | break; |
|
192 | 253 | } |
|
193 | 254 | tcsetattr((int)fd, TCSANOW, &terminos); |
|
194 | 255 | return 0; |
|
195 | 256 | } |
|
196 | 257 | } |
|
197 | 258 | |
|
198 | 259 | rs232speed_t rs232cfspeed(unsigned int BaudeRate) |
|
199 | 260 | { |
|
200 | 261 | if(BaudeRate<25) |
|
201 | 262 | return B0; |
|
202 | 263 | |
|
203 | 264 | if(BaudeRate<67) |
|
204 | 265 | return B50; |
|
205 | 266 | |
|
206 | 267 | if(BaudeRate<93) |
|
207 | 268 | return B75; |
|
208 | 269 | |
|
209 | 270 | if(BaudeRate<123) |
|
210 | 271 | return B110; |
|
211 | 272 | |
|
212 | 273 | if(BaudeRate<142) |
|
213 | 274 | return B134; |
|
214 | 275 | |
|
215 | 276 | if(BaudeRate<175) |
|
216 | 277 | return B150; |
|
217 | 278 | |
|
218 | 279 | if(BaudeRate<250) |
|
219 | 280 | return B200; |
|
220 | 281 | |
|
221 | 282 | if(BaudeRate<450) |
|
222 | 283 | return B300; |
|
223 | 284 | |
|
224 | 285 | if(BaudeRate<900) |
|
225 | 286 | return B600; |
|
226 | 287 | |
|
227 | 288 | if(BaudeRate<1500) |
|
228 | 289 | return B1200; |
|
229 | 290 | |
|
230 | 291 | if(BaudeRate<2100) |
|
231 | 292 | return B1800; |
|
232 | 293 | |
|
233 | 294 | if(BaudeRate<3600) |
|
234 | 295 | return B2400; |
|
235 | 296 | |
|
236 | 297 | if(BaudeRate<7200) |
|
237 | 298 | return B4800; |
|
238 | 299 | |
|
239 | 300 | if(BaudeRate<1400) |
|
240 | 301 | return B9600; |
|
241 | 302 | |
|
242 | 303 | if(BaudeRate<28800) |
|
243 | 304 | return B19200; |
|
244 | 305 | |
|
245 | 306 | if(BaudeRate<48000) |
|
246 | 307 | return B38400; |
|
247 | 308 | |
|
248 | 309 | if(BaudeRate<86400) |
|
249 | 310 | return B57600; |
|
250 | 311 | |
|
251 | 312 | if(BaudeRate<172800) |
|
252 | 313 | return B115200; |
|
253 | 314 | else |
|
254 | 315 | return B230400; |
|
255 | 316 | } |
|
256 | 317 | |
|
257 | 318 | |
|
258 | 319 | int rs232cfparity(int fd, struct termios *terminos, rs232parity Parity) |
|
259 | 320 | { |
|
260 | 321 | if ((int)fd == -1) |
|
261 | 322 | { |
|
262 | 323 | return fd; |
|
263 | 324 | } |
|
264 | 325 | else |
|
265 | 326 | { |
|
266 | 327 | terminos->c_cflag &= ~PARENB; |
|
267 | 328 | terminos->c_cflag &= ~PARODD; |
|
268 | 329 | switch(Parity) |
|
269 | 330 | { |
|
270 | 331 | case rs232parityNo: |
|
271 | 332 | terminos->c_cflag &= ~PARENB; |
|
272 | 333 | terminos->c_cflag &= ~PARODD; |
|
273 | 334 | break; |
|
274 | 335 | case rs232parityOdd: |
|
275 | 336 | terminos->c_cflag |= PARENB; |
|
276 | 337 | terminos->c_cflag |= PARODD; |
|
277 | 338 | break; |
|
278 | 339 | case rs232parityEven: |
|
279 | 340 | terminos->c_cflag |= PARENB; |
|
280 | 341 | terminos->c_cflag &= ~PARODD; |
|
281 | 342 | break; |
|
282 | 343 | default: |
|
283 | 344 | terminos->c_cflag &= ~PARENB; |
|
284 | 345 | terminos->c_cflag &= ~PARODD; |
|
285 | 346 | break; |
|
286 | 347 | } |
|
287 | 348 | return 0; |
|
288 | 349 | } |
|
289 | 350 | } |
|
290 | 351 | |
|
291 | 352 | int rs232cfnbstop(int fd, struct termios *terminos, rs232stop NbStop) |
|
292 | 353 | { |
|
293 | 354 | if ((int)fd == -1) |
|
294 | 355 | { |
|
295 | 356 | return fd; |
|
296 | 357 | } |
|
297 | 358 | else |
|
298 | 359 | { |
|
299 | 360 | switch(NbStop) |
|
300 | 361 | { |
|
301 | 362 | case 2: |
|
302 | 363 | terminos->c_cflag |= CSTOPB; |
|
303 | 364 | break; |
|
304 | 365 | default: |
|
305 | 366 | terminos->c_cflag &= ~CSTOPB; |
|
306 | 367 | break; |
|
307 | 368 | } |
|
308 | 369 | return 0; |
|
309 | 370 | } |
|
310 | 371 | } |
|
311 | 372 | |
|
312 | 373 | |
|
313 | 374 | int rs232cfcsize(int fd, struct termios *terminos, int ChSize) |
|
314 | 375 | { |
|
315 | 376 | if ((int)fd == -1) |
|
316 | 377 | { |
|
317 | 378 | return fd; |
|
318 | 379 | } |
|
319 | 380 | else |
|
320 | 381 | { |
|
321 | 382 | terminos->c_cflag &= ~CSIZE; |
|
322 | 383 | switch(ChSize) |
|
323 | 384 | { |
|
324 | 385 | case 5: |
|
325 | 386 | terminos->c_cflag |= CS5; |
|
326 | 387 | break; |
|
327 | 388 | case 6: |
|
328 | 389 | terminos->c_cflag |= CS6; |
|
329 | 390 | break; |
|
330 | 391 | case 7: |
|
331 | 392 | terminos->c_cflag |= CS7; |
|
332 | 393 | break; |
|
333 | 394 | default: |
|
334 | 395 | terminos->c_cflag |= CS8; |
|
335 | 396 | break; |
|
336 | 397 | } |
|
337 | 398 | return 0; |
|
338 | 399 | } |
|
339 | 400 | } |
|
340 | 401 | |
|
341 | 402 | |
|
342 | 403 | int rs232write(rs232port_t fd,char *psWrite, int WriteBufferSize) |
|
343 | 404 | { |
|
344 | 405 | if ((int)fd == -1) |
|
345 | 406 | { |
|
346 | 407 | return -1; |
|
347 | 408 | } |
|
348 | 409 | else |
|
349 | 410 | { |
|
350 | 411 | return write((int)fd, psWrite, WriteBufferSize); |
|
351 | 412 | } |
|
352 | 413 | } |
|
353 | 414 | |
|
354 | 415 | |
|
355 | 416 | int rs232read(rs232port_t fd,char *psReadHex, int ReadBufferSize) |
|
356 | 417 | { |
|
357 | 418 | |
|
358 | 419 | if ((int)fd == -1) |
|
359 | 420 | { |
|
360 | 421 | return -1; |
|
361 | 422 | } |
|
362 | 423 | else |
|
363 | 424 | { |
|
364 | 425 | return read((int)fd, psReadHex, ReadBufferSize); |
|
365 | 426 | } |
|
366 | 427 | |
|
367 | 428 | } |
|
368 | 429 | |
|
369 | 430 | |
|
370 | 431 | int rs232setRTS(rs232port_t fd) |
|
371 | 432 | { |
|
372 | 433 | int status; |
|
373 | 434 | ioctl((int)fd, TIOCMGET, &status); |
|
374 | 435 | status &= ~TIOCM_RTS; |
|
375 | 436 | if (ioctl((int)fd, TIOCMSET, &status)) |
|
376 | 437 | { |
|
377 | 438 | return -1; |
|
378 | 439 | } |
|
379 | 440 | return 0; |
|
380 | 441 | } |
|
381 | 442 | |
|
382 | 443 | int rs232clearRTS(rs232port_t fd) |
|
383 | 444 | { |
|
384 | 445 | int status; |
|
385 | 446 | ioctl((int)fd, TIOCMGET, &status); |
|
386 | 447 | status |= TIOCM_RTS; |
|
387 | 448 | if (ioctl((int)fd, TIOCMSET, &status)) |
|
388 | 449 | { |
|
389 | 450 | return -1; |
|
390 | 451 | } |
|
391 | 452 | return 0; |
|
392 | 453 | } |
|
393 | 454 | |
|
394 | 455 | int rs232setDTR(rs232port_t fd) |
|
395 | 456 | { |
|
396 | 457 | int status; |
|
397 | 458 | ioctl((int)fd, TIOCMGET, &status); |
|
398 | 459 | status &= ~TIOCM_DTR; |
|
399 | 460 | if (ioctl((int)fd, TIOCMSET, &status)) |
|
400 | 461 | { |
|
401 | 462 | return -1; |
|
402 | 463 | } |
|
403 | 464 | return 0; |
|
404 | 465 | } |
|
405 | 466 | |
|
406 | 467 | |
|
407 | 468 | int rs232clearDTR(rs232port_t fd) |
|
408 | 469 | { |
|
409 | 470 | int status; |
|
410 | 471 | ioctl((int)fd, TIOCMGET, &status); |
|
411 | 472 | status |= TIOCM_DTR; |
|
412 | 473 | if (ioctl((int)fd, TIOCMSET, &status)) |
|
413 | 474 | { |
|
414 | 475 | return -1; |
|
415 | 476 | } |
|
416 | 477 | return 0; |
|
417 | 478 | } |
|
418 | 479 | |
|
419 | 480 | |
|
420 | 481 | |
|
421 | 482 | int rs232saferead(rs232port_t fd,char* data,int count ) |
|
422 | 483 | { |
|
423 | 484 | int read=0; |
|
424 | 485 | int i=0; |
|
425 | 486 | for(i=0;i<100;i++) |
|
426 | 487 | { |
|
427 | 488 | read = rs232read((int)fd,data,count); |
|
428 | 489 | count -=read; |
|
429 | 490 | data+=read; |
|
430 | 491 | if(count==0) |
|
431 | 492 | return 0; |
|
432 | 493 | } |
|
433 | 494 | return -1; |
|
434 | 495 | } |
|
435 | 496 | |
|
436 | 497 | |
|
437 | 498 | |
|
438 | 499 | int rs232safewrite(rs232port_t fd,char* data,int count) |
|
439 | 500 | { |
|
440 | 501 | int written=0; |
|
441 | 502 | int i=0; |
|
442 | 503 | for(i=0;i<1000;i++) |
|
443 | 504 | { |
|
444 | 505 | written = rs232write((int)fd,data+written,count); |
|
445 | 506 | count-=written; |
|
446 | 507 | data+=written; |
|
447 | 508 | if(count==0) |
|
448 | 509 | return 0; |
|
449 | 510 | } |
|
450 | 511 | return -1; |
|
451 | 512 | } |
|
452 | 513 | |
|
453 | 514 | #endif |
|
454 | 515 | #endif //#ifdef HAVE_TERMIOS_H |
|
455 | 516 |
@@ -1,334 +1,364 | |||
|
1 | 1 | #include "rs232config.h" |
|
2 | 2 | #include <stdio.h> |
|
3 | 3 | #include <unistd.h> |
|
4 | 4 | #include <fcntl.h> |
|
5 | 5 | #include <string.h> |
|
6 | 6 | #include <errno.h> |
|
7 | 7 | #include <malloc.h> |
|
8 | 8 | |
|
9 | 9 | #ifdef HAVE_WINDOWS_H |
|
10 | 10 | #include <windows.h> |
|
11 | 11 | #endif |
|
12 | 12 | #include "RS232.h" |
|
13 | 13 | |
|
14 | 14 | #ifdef HAVE_WINDOWS_H |
|
15 | 15 | |
|
16 | 16 | |
|
17 | 17 | int privatedecodeparity(rs232parity Parity ) |
|
18 | 18 | { |
|
19 | 19 | switch(Parity) |
|
20 | 20 | { |
|
21 | 21 | case rs232parityNo: |
|
22 | 22 | return NOPARITY; |
|
23 | 23 | break; |
|
24 | 24 | case rs232parityOdd: |
|
25 | 25 | return ODDPARITY; |
|
26 | 26 | break; |
|
27 | 27 | case rs232parityEven: |
|
28 | 28 | return EVENPARITY; |
|
29 | 29 | break; |
|
30 | 30 | default: |
|
31 | 31 | return NOPARITY; |
|
32 | 32 | break; |
|
33 | 33 | } |
|
34 | 34 | } |
|
35 | 35 | |
|
36 | 36 | int privatedecodestop(rs232stop NbStop) |
|
37 | 37 | { |
|
38 | 38 | switch(NbStop) |
|
39 | 39 | { |
|
40 | 40 | case rs232OneStop: |
|
41 | 41 | return ONESTOPBIT; |
|
42 | 42 | break; |
|
43 | 43 | case rs232One5Stop: |
|
44 | 44 | return ONE5STOPBITS; |
|
45 | 45 | break; |
|
46 | 46 | case rs232TwoStop: |
|
47 | 47 | return TWOSTOPBITS; |
|
48 | 48 | break; |
|
49 | 49 | default: |
|
50 | 50 | return ONESTOPBIT; |
|
51 | 51 | break; |
|
52 | 52 | } |
|
53 | 53 | } |
|
54 | 54 | |
|
55 | 55 | |
|
56 | 56 | |
|
57 | 57 | rs232speed_t rs232cfspeed(unsigned int BaudeRate) |
|
58 | 58 | { |
|
59 | 59 | |
|
60 | 60 | if(BaudeRate<123) |
|
61 | 61 | return (rs232speed_t)CBR_110; |
|
62 | 62 | |
|
63 | 63 | if(BaudeRate<450) |
|
64 | 64 | return (rs232speed_t)CBR_300; |
|
65 | 65 | |
|
66 | 66 | if(BaudeRate<900) |
|
67 | 67 | return (rs232speed_t)CBR_600; |
|
68 | 68 | |
|
69 | 69 | if(BaudeRate<1500) |
|
70 | 70 | return (rs232speed_t)CBR_1200; |
|
71 | 71 | |
|
72 | 72 | if(BaudeRate<3600) |
|
73 | 73 | return (rs232speed_t)CBR_2400; |
|
74 | 74 | |
|
75 | 75 | if(BaudeRate<7200) |
|
76 | 76 | return (rs232speed_t)CBR_4800; |
|
77 | 77 | |
|
78 | 78 | if(BaudeRate<14000) |
|
79 | 79 | return (rs232speed_t)CBR_9600; |
|
80 | 80 | |
|
81 | 81 | if(BaudeRate<16800) |
|
82 | 82 | return (rs232speed_t)CBR_14400; |
|
83 | 83 | |
|
84 | 84 | if(BaudeRate<28800) |
|
85 | 85 | return (rs232speed_t)CBR_19200; |
|
86 | 86 | |
|
87 | 87 | if(BaudeRate<48000) |
|
88 | 88 | return (rs232speed_t)CBR_38400; |
|
89 | 89 | |
|
90 | 90 | if(BaudeRate<86400) |
|
91 | 91 | return (rs232speed_t)CBR_57600; |
|
92 | 92 | |
|
93 | 93 | if(BaudeRate<172800) |
|
94 | 94 | return (rs232speed_t)CBR_115200; |
|
95 | 95 | else |
|
96 | 96 | return (rs232speed_t)CBR_256000; |
|
97 | 97 | } |
|
98 | 98 | |
|
99 | 99 | |
|
100 | 100 | rs232port_t rs232open(char* psPortName) |
|
101 | 101 | { |
|
102 | 102 | rs232port_t fd; |
|
103 | 103 | fd = (rs232port_t)CreateFile(psPortName,GENERIC_READ | GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); |
|
104 | 104 | #ifdef debug |
|
105 | 105 | if(fd==(rs232port_t)INVALID_HANDLE_VALUE) |
|
106 | 106 | { |
|
107 | 107 | printf("can't open Port\n"); |
|
108 | 108 | return (rs232port_t)badPortValue; |
|
109 | 109 | } |
|
110 | 110 | #endif |
|
111 | 111 | return fd; |
|
112 | 112 | } |
|
113 | 113 | |
|
114 | 114 | int rs232close(rs232port_t fd) |
|
115 | 115 | { |
|
116 | 116 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
117 | 117 | { |
|
118 | 118 | return (rs232port_t)badPortValue; |
|
119 | 119 | } |
|
120 | 120 | else |
|
121 | 121 | { |
|
122 | 122 | CloseHandle((HANDLE)fd); |
|
123 | 123 | return rs232noerr; |
|
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 | 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 | |
|
138 | 168 | int rs232setup(rs232port_t fd, int ChSize, int BaudeRate, rs232parity Parity, rs232stop NbStop) |
|
139 | 169 | { |
|
140 | 170 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
141 | 171 | { |
|
142 | 172 | return (rs232port_t)badPortValue; |
|
143 | 173 | } |
|
144 | 174 | else |
|
145 | 175 | { |
|
146 | 176 | DCB dcbSerialParams = {0}; |
|
147 | 177 | dcbSerialParams.DCBlength=sizeof(dcbSerialParams); |
|
148 | 178 | GetCommState((HANDLE)fd, &dcbSerialParams); |
|
149 | 179 | dcbSerialParams.BaudRate=rs232cfspeed(BaudeRate); |
|
150 | 180 | dcbSerialParams.ByteSize=ChSize; |
|
151 | 181 | dcbSerialParams.StopBits=privatedecodestop(NbStop); |
|
152 | 182 | dcbSerialParams.Parity=privatedecodeparity(Parity); |
|
153 | 183 | SetCommState((HANDLE)fd, &dcbSerialParams); |
|
154 | 184 | COMMTIMEOUTS timeouts={0}; |
|
155 | 185 | timeouts.ReadIntervalTimeout=100; |
|
156 | 186 | timeouts.ReadTotalTimeoutConstant=100; |
|
157 | 187 | timeouts.ReadTotalTimeoutMultiplier=1; |
|
158 | 188 | timeouts.WriteTotalTimeoutConstant=100; |
|
159 | 189 | timeouts.WriteTotalTimeoutMultiplier=10; |
|
160 | 190 | SetCommTimeouts((HANDLE)fd, &timeouts); |
|
161 | 191 | return rs232noerr; |
|
162 | 192 | } |
|
163 | 193 | } |
|
164 | 194 | |
|
165 | 195 | int rs232setbaudrate(rs232port_t fd, int baudrate) |
|
166 | 196 | { |
|
167 | 197 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
168 | 198 | { |
|
169 | 199 | return (rs232port_t)badPortValue; |
|
170 | 200 | } |
|
171 | 201 | else |
|
172 | 202 | { |
|
173 | 203 | DCB dcbSerialParams = {0}; |
|
174 | 204 | dcbSerialParams.DCBlength=sizeof(dcbSerialParams); |
|
175 | 205 | GetCommState((HANDLE)fd, &dcbSerialParams); |
|
176 | 206 | dcbSerialParams.BaudRate=rs232cfspeed(baudrate); |
|
177 | 207 | SetCommState((HANDLE)fd, &dcbSerialParams); |
|
178 | 208 | return rs232noerr; |
|
179 | 209 | } |
|
180 | 210 | } |
|
181 | 211 | |
|
182 | 212 | int rs232setparity(rs232port_t fd, rs232parity Parity) |
|
183 | 213 | { |
|
184 | 214 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
185 | 215 | { |
|
186 | 216 | return (rs232port_t)badPortValue; |
|
187 | 217 | } |
|
188 | 218 | else |
|
189 | 219 | { |
|
190 | 220 | DCB dcbSerialParams = {0}; |
|
191 | 221 | dcbSerialParams.DCBlength=sizeof(dcbSerialParams); |
|
192 | 222 | GetCommState((HANDLE)fd, &dcbSerialParams); |
|
193 | 223 | dcbSerialParams.Parity = privatedecodeparity(Parity); |
|
194 | 224 | SetCommState((HANDLE)fd, &dcbSerialParams); |
|
195 | 225 | return rs232noerr; |
|
196 | 226 | } |
|
197 | 227 | } |
|
198 | 228 | |
|
199 | 229 | int rs232setnbstop(rs232port_t fd, rs232stop NbStop) |
|
200 | 230 | { |
|
201 | 231 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
202 | 232 | { |
|
203 | 233 | return (rs232port_t)badPortValue; |
|
204 | 234 | } |
|
205 | 235 | else |
|
206 | 236 | { |
|
207 | 237 | DCB dcbSerialParams = {0}; |
|
208 | 238 | dcbSerialParams.DCBlength=sizeof(dcbSerialParams); |
|
209 | 239 | GetCommState((HANDLE)fd, &dcbSerialParams); |
|
210 | 240 | dcbSerialParams.StopBits = privatedecodestop(NbStop); |
|
211 | 241 | SetCommState((HANDLE)fd, &dcbSerialParams); |
|
212 | 242 | return rs232noerr; |
|
213 | 243 | } |
|
214 | 244 | } |
|
215 | 245 | |
|
216 | 246 | |
|
217 | 247 | int rs232setcsize(rs232port_t fd, int ChSize) |
|
218 | 248 | { |
|
219 | 249 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
220 | 250 | { |
|
221 | 251 | return (rs232port_t)badPortValue; |
|
222 | 252 | } |
|
223 | 253 | else |
|
224 | 254 | { |
|
225 | 255 | DCB dcbSerialParams = {0}; |
|
226 | 256 | dcbSerialParams.DCBlength=sizeof(dcbSerialParams); |
|
227 | 257 | GetCommState((HANDLE)fd, &dcbSerialParams); |
|
228 | 258 | dcbSerialParams.ByteSize = ChSize; |
|
229 | 259 | SetCommState((HANDLE)fd, &dcbSerialParams); |
|
230 | 260 | return rs232noerr; |
|
231 | 261 | } |
|
232 | 262 | } |
|
233 | 263 | |
|
234 | 264 | |
|
235 | 265 | |
|
236 | 266 | |
|
237 | 267 | |
|
238 | 268 | |
|
239 | 269 | int rs232write(rs232port_t fd,char *psWrite, int WriteBufferSize) |
|
240 | 270 | { |
|
241 | 271 | |
|
242 | 272 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
243 | 273 | { |
|
244 | 274 | return (rs232port_t)badPortValue; |
|
245 | 275 | } |
|
246 | 276 | else |
|
247 | 277 | { |
|
248 | 278 | DWORD dwBytesWriten = 0; |
|
249 | 279 | WriteFile((HANDLE)fd, psWrite, WriteBufferSize, &dwBytesWriten, NULL); |
|
250 | 280 | return dwBytesWriten; |
|
251 | 281 | } |
|
252 | 282 | } |
|
253 | 283 | |
|
254 | 284 | |
|
255 | 285 | int rs232read(rs232port_t fd,char *psRead, int ReadBufferSize) |
|
256 | 286 | { |
|
257 | 287 | |
|
258 | 288 | if (fd == (rs232port_t)INVALID_HANDLE_VALUE) |
|
259 | 289 | { |
|
260 | 290 | return (rs232port_t)badPortValue; |
|
261 | 291 | } |
|
262 | 292 | else |
|
263 | 293 | { |
|
264 | 294 | DWORD dwBytesRead = 0; |
|
265 | 295 | ReadFile((HANDLE)fd, psRead, ReadBufferSize, &dwBytesRead, NULL); |
|
266 | 296 | return dwBytesRead; |
|
267 | 297 | } |
|
268 | 298 | |
|
269 | 299 | } |
|
270 | 300 | |
|
271 | 301 | |
|
272 | 302 | int rs232saferead(rs232port_t fd,char* data,int count ) |
|
273 | 303 | { |
|
274 | 304 | int read=0; |
|
275 | 305 | int i=0; |
|
276 | 306 | for(i=0;i<100;i++) |
|
277 | 307 | { |
|
278 | 308 | read = rs232read(fd,data,count); |
|
279 | 309 | count -=read; |
|
280 | 310 | data+=read; |
|
281 | 311 | if(count==0) |
|
282 | 312 | return rs232noerr; |
|
283 | 313 | } |
|
284 | 314 | return -1; |
|
285 | 315 | } |
|
286 | 316 | |
|
287 | 317 | |
|
288 | 318 | |
|
289 | 319 | int rs232safewrite(rs232port_t fd,char* data,int count) |
|
290 | 320 | { |
|
291 | 321 | int written=0; |
|
292 | 322 | int i=0; |
|
293 | 323 | for(i=0;i<1000;i++) |
|
294 | 324 | { |
|
295 | 325 | written = rs232write(fd,data+written,count); |
|
296 | 326 | count-=written; |
|
297 | 327 | data+=written; |
|
298 | 328 | if(count==0) |
|
299 | 329 | return rs232noerr; |
|
300 | 330 | } |
|
301 | 331 | return -1; |
|
302 | 332 | } |
|
303 | 333 | |
|
304 | 334 | |
|
305 | 335 | int rs232setRTS(rs232port_t fd) |
|
306 | 336 | { |
|
307 | 337 | if(EscapeCommFunction((HANDLE)fd, CLRRTS)) |
|
308 | 338 | return rs232noerr; |
|
309 | 339 | return -1; |
|
310 | 340 | } |
|
311 | 341 | |
|
312 | 342 | int rs232clearRTS(rs232port_t fd) |
|
313 | 343 | { |
|
314 | 344 | if(EscapeCommFunction((HANDLE)fd, SETRTS)) |
|
315 | 345 | return rs232noerr; |
|
316 | 346 | return -1; |
|
317 | 347 | } |
|
318 | 348 | |
|
319 | 349 | int rs232setDTR(rs232port_t fd) |
|
320 | 350 | { |
|
321 | 351 | if(EscapeCommFunction((HANDLE)fd, CLRDTR)) |
|
322 | 352 | return rs232noerr; |
|
323 | 353 | return -1; |
|
324 | 354 | } |
|
325 | 355 | |
|
326 | 356 | |
|
327 | 357 | int rs232clearDTR(rs232port_t fd) |
|
328 | 358 | { |
|
329 | 359 | if(EscapeCommFunction((HANDLE)fd, SETDTR)) |
|
330 | 360 | return rs232noerr; |
|
331 | 361 | return -1; |
|
332 | 362 | } |
|
333 | 363 | |
|
334 | 364 | #endif //#ifdef HAVE_WINDOWS_H |
@@ -1,83 +1,86 | |||
|
1 | 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 | 6 | /* Define to 1 if you have the <dlfcn.h> header file. */ |
|
4 | 7 | #undef HAVE_DLFCN_H |
|
5 | 8 | |
|
6 | 9 | /* Define to 1 if you have the <errno.h> header file. */ |
|
7 | 10 | #undef HAVE_ERRNO_H |
|
8 | 11 | |
|
9 | 12 | /* Define to 1 if you have the <fcntl.h> header file. */ |
|
10 | 13 | #undef HAVE_FCNTL_H |
|
11 | 14 | |
|
12 | 15 | /* Define to 1 if you have the <inttypes.h> header file. */ |
|
13 | 16 | #undef HAVE_INTTYPES_H |
|
14 | 17 | |
|
15 | 18 | /* Define to 1 if you have the <memory.h> header file. */ |
|
16 | 19 | #undef HAVE_MEMORY_H |
|
17 | 20 | |
|
18 | 21 | /* Define to 1 if you have the <stdint.h> header file. */ |
|
19 | 22 | #undef HAVE_STDINT_H |
|
20 | 23 | |
|
21 | 24 | /* Define to 1 if you have the <stdio.h> header file. */ |
|
22 | 25 | #undef HAVE_STDIO_H |
|
23 | 26 | |
|
24 | 27 | /* Define to 1 if you have the <stdlib.h> header file. */ |
|
25 | 28 | #undef HAVE_STDLIB_H |
|
26 | 29 | |
|
27 | 30 | /* Define to 1 if you have the <strings.h> header file. */ |
|
28 | 31 | #undef HAVE_STRINGS_H |
|
29 | 32 | |
|
30 | 33 | /* Define to 1 if you have the <string.h> header file. */ |
|
31 | 34 | #undef HAVE_STRING_H |
|
32 | 35 | |
|
33 | 36 | /* Define to 1 if you have the <sys/stat.h> header file. */ |
|
34 | 37 | #undef HAVE_SYS_STAT_H |
|
35 | 38 | |
|
36 | 39 | /* Define to 1 if you have the <sys/types.h> header file. */ |
|
37 | 40 | #undef HAVE_SYS_TYPES_H |
|
38 | 41 | |
|
39 | 42 | /* Define to 1 if you have the <termios.h> header file. */ |
|
40 | 43 | #undef HAVE_TERMIOS_H |
|
41 | 44 | |
|
42 | 45 | /* Define to 1 if you have the <termio.h> header file. */ |
|
43 | 46 | #undef HAVE_TERMIO_H |
|
44 | 47 | |
|
45 | 48 | /* Define to 1 if you have the <unistd.h> header file. */ |
|
46 | 49 | #undef HAVE_UNISTD_H |
|
47 | 50 | |
|
48 | 51 | /* Define to 1 if you have the <windows.h> header file. */ |
|
49 | 52 | #undef HAVE_WINDOWS_H |
|
50 | 53 | |
|
51 | 54 | /* Define to the sub-directory in which libtool stores uninstalled libraries. |
|
52 | 55 | */ |
|
53 | 56 | #undef LT_OBJDIR |
|
54 | 57 | |
|
55 | 58 | /* Name of package */ |
|
56 | 59 | #undef PACKAGE |
|
57 | 60 | |
|
58 | 61 | /* Define to the address where bug reports for this package should be sent. */ |
|
59 | 62 | #undef PACKAGE_BUGREPORT |
|
60 | 63 | |
|
61 | 64 | /* Define to the full name of this package. */ |
|
62 | 65 | #undef PACKAGE_NAME |
|
63 | 66 | |
|
64 | 67 | /* Define to the full name and version of this package. */ |
|
65 | 68 | #undef PACKAGE_STRING |
|
66 | 69 | |
|
67 | 70 | /* Define to the one symbol short name of this package. */ |
|
68 | 71 | #undef PACKAGE_TARNAME |
|
69 | 72 | |
|
70 | 73 | /* Define to the home page for this package. */ |
|
71 | 74 | #undef PACKAGE_URL |
|
72 | 75 | |
|
73 | 76 | /* Define to the version of this package. */ |
|
74 | 77 | #undef PACKAGE_VERSION |
|
75 | 78 | |
|
76 | 79 | /* Define to 1 if you have the ANSI C header files. */ |
|
77 | 80 | #undef STDC_HEADERS |
|
78 | 81 | |
|
79 | 82 | /* Version number of package */ |
|
80 | 83 | #undef VERSION |
|
81 | 84 | |
|
82 | 85 | /* Define to empty if `const' does not conform to ANSI C. */ |
|
83 | 86 | #undef const |
General Comments 0
You need to be logged in to leave comments.
Login now