mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-05-24 23:05:52 -04:00
Compare commits
327 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a6fd4c1c7 | ||
|
|
8395d24616 | ||
|
|
7d085960eb | ||
|
|
3884317181 | ||
|
|
089a2435f8 | ||
|
|
8ed16deb24 | ||
|
|
a577af9067 | ||
|
|
59af13651b | ||
|
|
787568f371 | ||
|
|
f0019fc506 | ||
|
|
9f639210ca | ||
|
|
deec574421 | ||
|
|
04657e42d5 | ||
|
|
1b88775534 | ||
|
|
7f6537557d | ||
|
|
518233ca79 | ||
|
|
bc72130d71 | ||
|
|
855decd3a7 | ||
|
|
0090cbdba6 | ||
|
|
73ff720972 | ||
|
|
c561e1378d | ||
|
|
aa2c47d835 | ||
|
|
536b84680b | ||
|
|
7508b795bf | ||
|
|
76ee1d18bf | ||
|
|
379bc86547 | ||
|
|
066696644f | ||
|
|
755bcd3722 | ||
|
|
1985aa9666 | ||
|
|
f4663a36da | ||
|
|
521e6fdcfc | ||
|
|
61ab574e38 | ||
|
|
660cb6a085 | ||
|
|
4274208833 | ||
|
|
34db05b421 | ||
|
|
1657be22a3 | ||
|
|
3636b9ffaa | ||
|
|
e3cd264571 | ||
|
|
69555b0943 | ||
|
|
522c05cf9a | ||
|
|
f0b4fdaf5e | ||
|
|
ac6ce98375 | ||
|
|
1b3cadaa39 | ||
|
|
61ca7d596c | ||
|
|
688d573295 | ||
|
|
ec6e0bf0c0 | ||
|
|
184dede92f | ||
|
|
d2cc0323fb | ||
|
|
3a1eefd331 | ||
|
|
824f1c7944 | ||
|
|
7bc8218d81 | ||
|
|
a405cda63c | ||
|
|
7afa3a4a48 | ||
|
|
c80b3d8c3f | ||
|
|
ef6122c622 | ||
|
|
75fb17b891 | ||
|
|
2abbf2498f | ||
|
|
b91b50c01f | ||
|
|
06891710f2 | ||
|
|
b765ec32b9 | ||
|
|
a70d070cc5 | ||
|
|
1f1fbe187e | ||
|
|
fc63847406 | ||
|
|
f58677d123 | ||
|
|
7ab1538861 | ||
|
|
7ad0f94de9 | ||
|
|
8af534a52c | ||
|
|
7447419266 | ||
|
|
5216de37a4 | ||
|
|
ccc0d1eb1d | ||
|
|
7fc0890881 | ||
|
|
b17f1d76c0 | ||
|
|
451b5fc969 | ||
|
|
1e678fcab1 | ||
|
|
48bcc6ee2b | ||
|
|
32734c7c3c | ||
|
|
aaf375d0a5 | ||
|
|
9680f811f6 | ||
|
|
bda41fa509 | ||
|
|
7ea84b6890 | ||
|
|
cc234d944a | ||
|
|
ac84096d1f | ||
|
|
a1cc591b29 | ||
|
|
da0405080e | ||
|
|
0c0a3e2dd3 | ||
|
|
ad301e487c | ||
|
|
b5ae4aba38 | ||
|
|
8d2aad49e3 | ||
|
|
bc2b4963a0 | ||
|
|
ee7118a816 | ||
|
|
95dd949c09 | ||
|
|
9326552e66 | ||
|
|
1e34e4b7cd | ||
|
|
06464f55e2 | ||
|
|
1b85e3f1a0 | ||
|
|
eac9dc63e3 | ||
|
|
30e8c8e1e4 | ||
|
|
d53d7795ee | ||
|
|
59c95e4243 | ||
|
|
f8a94f0de8 | ||
|
|
3b5f6214a6 | ||
|
|
542ad675b9 | ||
|
|
1e736b8ff7 | ||
|
|
a6d8c3f336 | ||
|
|
bb4aa89c10 | ||
|
|
09021eabb5 | ||
|
|
8d69d57113 | ||
|
|
eaa4c150ab | ||
|
|
a125c82ad2 | ||
|
|
93eff16a6a | ||
|
|
d2d9fe184d | ||
|
|
2d4ca358db | ||
|
|
39993af514 | ||
|
|
bef4934045 | ||
|
|
1312d9fc47 | ||
|
|
75aeac44e8 | ||
|
|
68f40ebba9 | ||
|
|
973007daac | ||
|
|
8060514230 | ||
|
|
b1a2f37a6e | ||
|
|
7c66b86028 | ||
|
|
cc248aae9b | ||
|
|
ca23c51aeb | ||
|
|
fca9a9b0f0 | ||
|
|
1ea15dbe05 | ||
|
|
8e34cd41f0 | ||
|
|
9ef1cc7cdf | ||
|
|
411acbbc2a | ||
|
|
32e83406c4 | ||
|
|
7e28fca126 | ||
|
|
e4ffb53900 | ||
|
|
7c2d381c28 | ||
|
|
bde47ca7c5 | ||
|
|
ea7f8108b0 | ||
|
|
98393ae2e2 | ||
|
|
759ac87019 | ||
|
|
a1e0e45e01 | ||
|
|
54170a084d | ||
|
|
1bbf83c07d | ||
|
|
ccd2b499ed | ||
|
|
1de50993a7 | ||
|
|
786c36876b | ||
|
|
8bd1a73e14 | ||
|
|
c7d692c3c3 | ||
|
|
f9b9e2f067 | ||
|
|
dafe63ca98 | ||
|
|
f49a7b227f | ||
|
|
f5e4eadb74 | ||
|
|
717eb9b883 | ||
|
|
5ba268efa8 | ||
|
|
25ff30e804 | ||
|
|
bdae761ee1 | ||
|
|
5af50297be | ||
|
|
32f761755e | ||
|
|
c4fea82ff9 | ||
|
|
6ded1170ac | ||
|
|
991f90f296 | ||
|
|
c979dad54a | ||
|
|
136ac7ecec | ||
|
|
3e8369b6dc | ||
|
|
a7dc44d27d | ||
|
|
07a874fd9b | ||
|
|
e35080cede | ||
|
|
ce8149b6fe | ||
|
|
a86179f429 | ||
|
|
56cf38ac98 | ||
|
|
b0f451eb3b | ||
|
|
d0829892c6 | ||
|
|
fdf88d7574 | ||
|
|
595f2d4d97 | ||
|
|
cae95647a4 | ||
|
|
a254fd9798 | ||
|
|
805edf9d7d | ||
|
|
eca2adb4b3 | ||
|
|
4eea7793ea | ||
|
|
67684d038d | ||
|
|
98b332edea | ||
|
|
e681e82066 | ||
|
|
08571358b1 | ||
|
|
8901a07fdb | ||
|
|
880da0072e | ||
|
|
a83600cc82 | ||
|
|
dd0628f85f | ||
|
|
e66dfd1879 | ||
|
|
bf2daeaf2d | ||
|
|
bd0ad74f4b | ||
|
|
79f671cc7c | ||
|
|
0f9c48b1d2 | ||
|
|
538ba24fd7 | ||
|
|
d37d8d7b69 | ||
|
|
f4a0483ab8 | ||
|
|
f5f95a38c4 | ||
|
|
3e7053ac59 | ||
|
|
420ef2c419 | ||
|
|
9fb3f7a9ab | ||
|
|
734a94a20c | ||
|
|
b44be3e944 | ||
|
|
fc0302cf07 | ||
|
|
4fdc39dde8 | ||
|
|
9a933bc2ce | ||
|
|
524dc9afd6 | ||
|
|
e4d709cbf8 | ||
|
|
48c1586cd1 | ||
|
|
7bd0cf5b8f | ||
|
|
fcb69e5cdc | ||
|
|
96557d23a3 | ||
|
|
4e5db0ad4a | ||
|
|
c81a32f071 | ||
|
|
6f2623fd69 | ||
|
|
b4235b3165 | ||
|
|
d25c0e42c7 | ||
|
|
0ecfbf27c3 | ||
|
|
fb4c98c2c8 | ||
|
|
cd8e38b13f | ||
|
|
b35d0d8e9a | ||
|
|
c948e309f2 | ||
|
|
d1f83bcc81 | ||
|
|
e0fde757fd | ||
|
|
25d34a5c80 | ||
|
|
610364e3a6 | ||
|
|
036e70b024 | ||
|
|
ac13ad106a | ||
|
|
bd9e9eccbd | ||
|
|
8ff9d697c9 | ||
|
|
62b68c8046 | ||
|
|
e4724e5c1c | ||
|
|
559e727bf7 | ||
|
|
126642b633 | ||
|
|
cca4e06786 | ||
|
|
2f1faea89b | ||
|
|
3d90ec146f | ||
|
|
1bc209b441 | ||
|
|
1433e6da69 | ||
|
|
f8f4c862e8 | ||
|
|
226df8e717 | ||
|
|
6c92af2067 | ||
|
|
54c7298ce4 | ||
|
|
642a979a27 | ||
|
|
e733c93423 | ||
|
|
ffdb58a51a | ||
|
|
c053133207 | ||
|
|
9098bbf3b3 | ||
|
|
68618b8810 | ||
|
|
e553d27f41 | ||
|
|
d092924c63 | ||
|
|
34027489e0 | ||
|
|
d1239eae92 | ||
|
|
331050969b | ||
|
|
259c3e72b0 | ||
|
|
8f7a38336d | ||
|
|
999dfffc9b | ||
|
|
527a51cec5 | ||
|
|
20c15aead5 | ||
|
|
fb859e5674 | ||
|
|
4f2dcb1714 | ||
|
|
64e74631e0 | ||
|
|
fba31efb74 | ||
|
|
435f1ed70d | ||
|
|
94f34ca10a | ||
|
|
b0633744fa | ||
|
|
c127e8aaec | ||
|
|
bf4e725d5d | ||
|
|
663717f465 | ||
|
|
12b159ac41 | ||
|
|
9299c8f0b4 | ||
|
|
dfef3f1099 | ||
|
|
fa3690f488 | ||
|
|
4acbfa2ade | ||
|
|
ef86d74736 | ||
|
|
118f39d45b | ||
|
|
77867907ed | ||
|
|
98c1b32565 | ||
|
|
7a176e87d5 | ||
|
|
79c9d8a180 | ||
|
|
7d8219327b | ||
|
|
4ac4bdbb38 | ||
|
|
f494f2864c | ||
|
|
017f22b47f | ||
|
|
dec41b556b | ||
|
|
be2961da2c | ||
|
|
914cc65c9d | ||
|
|
6479c2ed3f | ||
|
|
c1a04ecbfd | ||
|
|
69b06c50c4 | ||
|
|
6aaf8d8c10 | ||
|
|
4cf64834ed | ||
|
|
b8709f5046 | ||
|
|
24448f741f | ||
|
|
76533c52dc | ||
|
|
3ff984d7a7 | ||
|
|
7a52790b50 | ||
|
|
7b329a2d79 | ||
|
|
599dc93c64 | ||
|
|
8b54f00466 | ||
|
|
8469faef03 | ||
|
|
bceec82f35 | ||
|
|
ed521de525 | ||
|
|
d157de203a | ||
|
|
1bfbf40bd5 | ||
|
|
6d19c6742c | ||
|
|
a628b06977 | ||
|
|
6b2d24de2c | ||
|
|
e23d790fa7 | ||
|
|
2a5904a580 | ||
|
|
4610ac79c2 | ||
|
|
142f5be922 | ||
|
|
b17dd0c435 | ||
|
|
3669201179 | ||
|
|
a5c48193c7 | ||
|
|
4366275bab | ||
|
|
c579310a00 | ||
|
|
96553aa7ef | ||
|
|
2094283b80 | ||
|
|
4c631ac621 | ||
|
|
d96d3893dd | ||
|
|
b73b51a9e4 | ||
|
|
3c1edccb7b | ||
|
|
b23c290630 | ||
|
|
c7b562becf | ||
|
|
5648a81936 | ||
|
|
daa3d0e2da | ||
|
|
c9a66d41fe | ||
|
|
0ee1bd82c5 | ||
|
|
53e1f937bc | ||
|
|
604f343c49 | ||
|
|
e9c4c3018b | ||
|
|
db1babe6a9 |
11
.cvsignore
11
.cvsignore
@@ -1,9 +1,15 @@
|
||||
ID
|
||||
Makefile
|
||||
autom4te.cache
|
||||
confdefs.h
|
||||
config.cache
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
conftest.c
|
||||
conftest.log
|
||||
dox
|
||||
getgroups
|
||||
gmon.out
|
||||
rsync
|
||||
shconfig
|
||||
@@ -12,7 +18,6 @@ tests-dont-exist
|
||||
testtmp
|
||||
testtmp.*
|
||||
tls
|
||||
trimslash
|
||||
t_unsafe
|
||||
zlib/dummy
|
||||
confdefs.h
|
||||
conftest.c
|
||||
conftest.log
|
||||
|
||||
187
Doxyfile
Normal file
187
Doxyfile
Normal file
@@ -0,0 +1,187 @@
|
||||
# Doxyfile 1.2.15
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
PROJECT_NAME = rsync
|
||||
PROJECT_NUMBER = HEAD
|
||||
OUTPUT_DIRECTORY = dox
|
||||
OUTPUT_LANGUAGE = English
|
||||
EXTRACT_ALL = YES
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH = *source
|
||||
INTERNAL_DOCS = YES
|
||||
STRIP_CODE_COMMENTS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
SHORT_NAMES = NO
|
||||
HIDE_SCOPE_NAMES = YES
|
||||
VERBATIM_HEADERS = YES
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
INHERIT_DOCS = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 8
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
ALIASES =
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SHOW_USED_FILES = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = NO
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = .
|
||||
FILE_PATTERNS = *.c \
|
||||
*.h
|
||||
RECURSIVE = YES
|
||||
EXCLUDE = proto.h \
|
||||
zlib \
|
||||
popt
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 3
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 3
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = NO
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = NO
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
TEMPLATE_RELATIONS = YES
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
CGI_NAME = search.cgi
|
||||
CGI_URL =
|
||||
DOC_URL =
|
||||
DOC_ABSPATH =
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
EXT_DOC_PATHS =
|
||||
3
INSTALL
3
INSTALL
@@ -14,6 +14,9 @@ cut-down copy of release 1.5 is included in the rsync distribution,
|
||||
and will be used it there is no popt library on your build host, or if
|
||||
the --with-included-popt option is passed to ./configure.
|
||||
|
||||
If you configure using --enable-maintainer-mode, then rsync will try
|
||||
to pop up an xterm on DISPLAY=:0 if it crashes. You might find this
|
||||
useful, but it should be turned off for production builds.
|
||||
|
||||
|
||||
HP-UX NOTES
|
||||
|
||||
124
Makefile.in
124
Makefile.in
@@ -9,9 +9,12 @@ mandir=@mandir@
|
||||
LIBS=@LIBS@
|
||||
CC=@CC@
|
||||
CFLAGS=@CFLAGS@
|
||||
CPPFLAGS=@CPPFLAGS@
|
||||
EXEEXT=@EXEEXT@
|
||||
LDFLAGS=@LDFLAGS@
|
||||
|
||||
INSTALLCMD=@INSTALL@
|
||||
INSTALLMAN=@INSTALL@
|
||||
|
||||
srcdir=@srcdir@
|
||||
VPATH=$(srcdir)
|
||||
@@ -23,77 +26,107 @@ VERSION=@VERSION@
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
|
||||
lib/permstring.o \
|
||||
@LIBOBJS@
|
||||
lib/permstring.o @LIBOBJS@
|
||||
ZLIBOBJ=zlib/deflate.o zlib/infblock.o zlib/infcodes.o zlib/inffast.o \
|
||||
zlib/inflate.o zlib/inftrees.o zlib/infutil.o zlib/trees.o \
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o main.o checksum.o match.o syscall.o log.o backup.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o fileio.o batch.o \
|
||||
clientname.o
|
||||
zlib/zutil.o zlib/adler32.o
|
||||
OBJS1=rsync.o generator.o receiver.o cleanup.o sender.o exclude.o util.o \
|
||||
main.o checksum.o match.o syscall.o log.o backup.o
|
||||
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
|
||||
fileio.o batch.o clientname.o
|
||||
OBJS3=progress.o pipe.o
|
||||
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
|
||||
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
|
||||
popt/popthelp.o popt/poptparse.o
|
||||
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
|
||||
|
||||
TLS_OBJ = tls.o syscall.o lib/permstring.o
|
||||
TLS_OBJ = tls.o syscall.o lib/permstring.o
|
||||
|
||||
# Programs we must have to run the test cases
|
||||
CHECK_PROGS = rsync tls
|
||||
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) \
|
||||
trimslash$(EXEEXT) t_unsafe$(EXEEXT)
|
||||
|
||||
# Objects for CHECK_PROGS to clean
|
||||
CHECK_OBJS=getgroups.o t_stub.o t_unsafe.o trimslash.o
|
||||
|
||||
# note that the -I. is needed to handle config.h when using VPATH
|
||||
.c.o:
|
||||
@OBJ_SAVE@
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
|
||||
@OBJ_RESTORE@
|
||||
|
||||
all: rsync
|
||||
all: rsync$(EXEEXT)
|
||||
|
||||
man: rsync.1 rsyncd.conf.5
|
||||
|
||||
install: all
|
||||
-mkdir -p ${bindir}
|
||||
${INSTALLCMD} -m 755 rsync ${bindir}
|
||||
-mkdir -p ${mandir}/man1
|
||||
-mkdir -p ${mandir}/man5
|
||||
${INSTALLCMD} -m 644 $(srcdir)/rsync.1 ${mandir}/man1
|
||||
${INSTALLCMD} -m 644 $(srcdir)/rsyncd.conf.5 ${mandir}/man5
|
||||
-mkdir -p ${DESTDIR}${bindir}
|
||||
${INSTALLCMD} ${STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
|
||||
-mkdir -p ${DESTDIR}${mandir}/man1
|
||||
-mkdir -p ${DESTDIR}${mandir}/man5
|
||||
${INSTALLMAN} -m 644 $(srcdir)/rsync.1 ${DESTDIR}${mandir}/man1
|
||||
${INSTALLMAN} -m 644 $(srcdir)/rsyncd.conf.5 ${DESTDIR}${mandir}/man5
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALLCMD='$(INSTALLCMD) -s' install
|
||||
$(MAKE) STRIP='-s' install
|
||||
|
||||
rsync: $(OBJS)
|
||||
@echo "Please ignore warnings below about mktemp -- it is used in a safe way"
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o rsync $(OBJS) $(LIBS)
|
||||
rsync$(EXEEXT): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
$(OBJS): config.h
|
||||
|
||||
tls: $(TLS_OBJ)
|
||||
tls$(EXEEXT): $(TLS_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
|
||||
|
||||
Makefile: Makefile.in configure config.status
|
||||
echo "WARNING: You need to run ./config.status --recheck"
|
||||
getgroups$(EXEEXT): getgroups.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
|
||||
|
||||
TRIMSLASH_OBJ = trimslash.o syscall.o
|
||||
trimslash$(EXEEXT): $(TRIMSLASH_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TRIMSLASH_OBJ) $(LIBS)
|
||||
|
||||
T_UNSAFE_OBJ = t_unsafe.o syscall.o util.o t_stub.o lib/compat.o lib/snprintf.o
|
||||
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
|
||||
|
||||
# I don't like these rules because CVS can skew the timestamps and
|
||||
# produce spurious warnings, and also make "make install" fail if the
|
||||
# source directory can no longer be found. Since we don't rebuild
|
||||
# automatically they're kind of lame anyhow.
|
||||
|
||||
#Makefile: Makefile.in configure config.status
|
||||
# echo "WARNING: You need to run ./config.status --recheck"
|
||||
|
||||
# don't actually run autoconf, just issue a warning
|
||||
configure: configure.in
|
||||
echo "WARNING: you need to rerun autoconf"
|
||||
#configure: configure.in
|
||||
# echo "WARNING: you need to rerun autoconf"
|
||||
|
||||
rsync.1: rsync.yo
|
||||
yodl2man -o rsync.1 rsync.yo
|
||||
$(srcdir)/rsync.1: $(srcdir)/rsync.yo
|
||||
yodl2man -o $(srcdir)/rsync.1 $(srcdir)/rsync.yo
|
||||
|
||||
rsyncd.conf.5: rsyncd.conf.yo
|
||||
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
|
||||
$(srcdir)/rsyncd.conf.5: $(srcdir)/rsyncd.conf.yo
|
||||
yodl2man -o $(srcdir)/rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
|
||||
|
||||
proto:
|
||||
cat $(srcdir)/*.c $(srcdir)/lib/compat.c | awk -f $(srcdir)/mkproto.awk > $(srcdir)/proto.h
|
||||
|
||||
clean:
|
||||
rm -f *~ $(OBJS) rsync $(TLS_OBJ) tls
|
||||
rm -rf ./testtmp
|
||||
rm -f config.cache
|
||||
clean: cleantests
|
||||
rm -f *~ $(OBJS) $(TLS_OBJ) $(CHECK_PROGS) $(CHECK_OBJS)
|
||||
|
||||
cleantests:
|
||||
rm -rf ./testtmp*
|
||||
|
||||
# We try to delete built files from both the source and build
|
||||
# directories, just in case somebody previously configured things in
|
||||
# the source directory.
|
||||
distclean: clean
|
||||
rm -f Makefile config.h config.status
|
||||
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
|
||||
|
||||
rm -f config.cache config.log
|
||||
rm -f $(srcdir)/config.cache $(srcdir)/config.log
|
||||
|
||||
rm -f shconfig $(srcdir)/shconfig
|
||||
|
||||
# this target is really just for my use. It only works on a limited
|
||||
# range of machines and is used to produce a list of potentially
|
||||
@@ -101,7 +134,7 @@ distclean: clean
|
||||
finddead:
|
||||
nm *.o */*.o |grep 'U ' | awk '{print $$2}' | sort -u > nmused.txt
|
||||
nm *.o */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
|
||||
comm -13 nmused.txt nmfns.txt
|
||||
comm -13 nmused.txt nmfns.txt
|
||||
|
||||
# 'check' is the GNU name, 'test' is the name for everybody else :-)
|
||||
.PHONY: check test
|
||||
@@ -123,22 +156,37 @@ test: check
|
||||
# might lose in the future where POSIX diverges from old sh.
|
||||
|
||||
check: all $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin=`pwd`/rsync srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin=`pwd`/rsync$(EXEEXT) srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# This does *not* depend on building or installing: you can use it to
|
||||
# check a version installed from a binary or some other source tree,
|
||||
# if you want.
|
||||
|
||||
installcheck: $(CHECK_PROGS)
|
||||
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin="$(bindir)/rsync" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin="$(bindir)/rsync$(EXEEXT)" srcdir="$(srcdir)" $(srcdir)/runtests.sh
|
||||
|
||||
# TODO: Add 'dist' target; need to know which files will be included
|
||||
|
||||
# Run the SPLINT (Secure Programming Lint) tool. <www.splint.org>
|
||||
.PHONY: splint
|
||||
splint:
|
||||
splint +unixlib +gnuextensions -weak rsync.c
|
||||
|
||||
|
||||
rsync.dvi: doc/rsync.texinfo
|
||||
texi2dvi -o $@ $<
|
||||
|
||||
rsync.ps: rsync.dvi
|
||||
rsync.ps: rsync.dvi
|
||||
dvips -ta4 -o $@ $<
|
||||
|
||||
rsync.pdf: doc/rsync.texinfo
|
||||
texi2dvi -o $@ --pdf $<
|
||||
|
||||
|
||||
doxygen:
|
||||
cd $(srcdir) && rm dox/html/* && doxygen
|
||||
|
||||
# for maintainers only
|
||||
doxygen-upload:
|
||||
rsync -avzv $(srcdir)/dox/html/ --delete \
|
||||
samba.org:/home/httpd/html/rsync/doxygen/head/
|
||||
|
||||
99
NEWS
99
NEWS
@@ -1,16 +1,91 @@
|
||||
rsync 2.5.4 (13 March 2002)
|
||||
NEWS for rsync version 2.5.6, aka the dwd-between-jobs release
|
||||
Changes since version 2.5.5:
|
||||
|
||||
"Imitation lizard skin"
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Additional fix for zlib double-free bug. (Martin Pool, Andrew
|
||||
Tridgell) (CVE CAN-2002-0059)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* Merge in changes from zlib 1.1.3 to zlib 1.1.4. (Jos Backus)
|
||||
(Note that rsync still uses a custom version of zlib; you can
|
||||
not just link against a system library. See zlib/README.rsync)
|
||||
* The --delete-after option now implies --delete. (Wayne Davison)
|
||||
|
||||
* Additional test cases for --compress. (Martin Pool)
|
||||
* The --suffix option can now be used with --backup-dir. (Michael
|
||||
Zimmerman)
|
||||
|
||||
* Combining "::" syntax with the -rsh/-e option now uses the
|
||||
specified remote-shell as a transport to talk to a (newly-spawned)
|
||||
server-daemon. This allows someone to use daemon features, such
|
||||
as modules, over a secure protocol, such as ssh. (JD Paul)
|
||||
|
||||
* The rsync:// syntax for daemon connections is now accepted in the
|
||||
destination field.
|
||||
|
||||
* If the file name given to --include-from or --exclude-from is "-",
|
||||
rsync will read from standard input. (J.W. Schultz)
|
||||
|
||||
* New option --link-dest which is like --compare-dest except that
|
||||
unchanged files are hard-linked in to the destination directory.
|
||||
(J.W. Schultz)
|
||||
|
||||
* Don't report an error if an excluded file disappears during an
|
||||
rsync run. (Eugene Chupriyanov and Bo Kersey)
|
||||
|
||||
* Added .svn to --cvs-exclude list to support subversion. (Jon
|
||||
Middleton)
|
||||
|
||||
* Properly support IPv6 addresses in the rsyncd.conf "hosts allow"
|
||||
and "hosts deny" fields. (Hideaki Yoshifuji)
|
||||
|
||||
* Changed exclude file handling to permit DOS or MAC style line
|
||||
terminations. (J.W. Schultz)
|
||||
|
||||
* Ignore errors from chmod when -p/-a/--preserve-perms is not set.
|
||||
(Dave Dykstra)
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix "forward name lookup failed" errors on AIX 4.3.3. (John
|
||||
L. Allen, Martin Pool)
|
||||
|
||||
* Generate each file's rolling-checksum data as we send it, not
|
||||
in a separate (memory-eating) pass before hand. This prevents
|
||||
timeout errors on really large files. (Stefan Nehlsen)
|
||||
|
||||
* Fix compilation on Tru64. (Albert Chin, Zoong Pham)
|
||||
|
||||
* Better handling of some client-server errors. (Martin Pool)
|
||||
|
||||
* Fixed a crash that would occur when sending a list of files that
|
||||
contains a duplicate name (if it sorts to the end of the file
|
||||
list) and using --delete. (Wayne Davison)
|
||||
|
||||
* Fixed the file-name duplicate-removal code when dealing with multiple
|
||||
dups in a row. (Wayne Davison)
|
||||
|
||||
* Fixed a bug that caused rsync to lose the exit status of its child
|
||||
processes and sometimes return an exit code of 0 instead of showing
|
||||
an error. (David R. Staples, Dave Dykstra)
|
||||
|
||||
* Fixed bug in --copy-unsafe-links that caused it to be completely
|
||||
broken. (Dave Dykstra)
|
||||
|
||||
* Prevent infinite recursion in cleanup code under certain circumstances.
|
||||
(Sviatoslav Sviridov and Marc Espie)
|
||||
|
||||
* Fixed a bug that prevented rsync from creating intervening directories
|
||||
when --relative-paths/-R is set. (Craig Barratt)
|
||||
|
||||
* Prevent "Connection reset by peer" messages from Cygwin. (Randy O'Meara)
|
||||
|
||||
INTERNAL:
|
||||
|
||||
* Many code cleanups and improved internal documentation. (Martin
|
||||
Pool, Nelson Beebe)
|
||||
|
||||
* Portability fixes. (Dave Dykstra and Wayne Davison)
|
||||
|
||||
* More test cases. (Martin Pool)
|
||||
|
||||
* Some test-case fixes. (Brian Poole, Wayne Davison)
|
||||
|
||||
* Updated included popt to the latest vendor drop, version 1.6.4.
|
||||
(Jos Backus)
|
||||
|
||||
* Updated config.guess and config.sub to latest versions; this
|
||||
means rsync should build on more platforms. (Paul Green)
|
||||
|
||||
58
OLDNEWS
58
OLDNEWS
@@ -1,3 +1,60 @@
|
||||
rsync 2.5.5 "Snowy River" (2 April 2002)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* With --progress, when a transfer is complete show the time taken;
|
||||
otherwise show expected time to complete. (Cameron Simpson)
|
||||
|
||||
* Make "make install-strip" works properly, and "make install"
|
||||
accepts a DESTDIR variable for help in building binary packages.
|
||||
(Peter Breitenlohner, Greg Louis)
|
||||
|
||||
* If configured with --enable-maintainer-mode, then on receipt of
|
||||
a fatal signal rsync will try to open an xterm running gdb,
|
||||
similarly to Samba's "panic action" or GNOME's bug-buddy.
|
||||
(Martin Pool)
|
||||
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Fix situation where failure to fork (e.g. because out of process
|
||||
slots) would cause rsync to kill all processes owned by the
|
||||
current user. Yes, really! (Paul Haas, Martin Pool)
|
||||
|
||||
* Fix test suite on Solaris. (Jos Backus, Martin Pool)
|
||||
|
||||
* Fix minor memory leak in socket code. (Dave Dykstra, Martin
|
||||
Pool.)
|
||||
|
||||
* Fix --whole-file problem that caused it to be the default even
|
||||
for remote connections. (Martin Pool, Frank Schulz)
|
||||
|
||||
* Work around bug in Mac OS X mkdir(2), which cannot handle
|
||||
trailing slashes.
|
||||
<http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html>
|
||||
(Martin Pool)
|
||||
|
||||
* Improved network error handling. (Greg A. Woods)
|
||||
|
||||
|
||||
rsync 2.5.4 (13 March 2002)
|
||||
|
||||
"Imitation lizard skin"
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
* Additional fix for zlib double-free bug. (Martin Pool, Andrew
|
||||
Tridgell) (CVE CAN-2002-0059)
|
||||
|
||||
ENHANCEMENTS:
|
||||
|
||||
* Merge in changes from zlib 1.1.3 to zlib 1.1.4. (Jos Backus)
|
||||
(Note that rsync still uses a custom version of zlib; you can
|
||||
not just link against a system library. See zlib/README.rsync)
|
||||
|
||||
* Additional test cases for --compress. (Martin Pool)
|
||||
|
||||
|
||||
rsync 2.5.3 (11 March 2002)
|
||||
|
||||
"Happy 26"
|
||||
@@ -122,6 +179,7 @@ rsync 2.5.1 (2002-01-03)
|
||||
|
||||
* Clearer error messages for some conditions.
|
||||
|
||||
|
||||
rsync 2.5.0 (2001-11-30)
|
||||
|
||||
ANNOUNCEMENTS
|
||||
|
||||
85
README
85
README
@@ -18,73 +18,12 @@ this package.
|
||||
USAGE
|
||||
-----
|
||||
|
||||
Basically you use rsync just like rcp, but rsync has many additional options.
|
||||
Basically you use rsync just like rcp, but rsync has many additional
|
||||
options. To get a complete list of supported options type
|
||||
|
||||
Here is a brief description of rsync usage:
|
||||
|
||||
Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST
|
||||
or rsync [OPTION]... [USER@]HOST:SRC DEST
|
||||
or rsync [OPTION]... SRC [SRC]... DEST
|
||||
or rsync [OPTION]... [USER@]HOST::SRC [DEST]
|
||||
or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
|
||||
or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
|
||||
SRC on single-colon remote HOST will be expanded by remote shell
|
||||
SRC on server remote HOST may contain shell wildcards or multiple
|
||||
sources separated by space as long as they have same top-level
|
||||
|
||||
Options
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ suffix)
|
||||
--suffix=SUFFIX override backup suffix
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links preserve soft links
|
||||
-L, --copy-links treat soft links like regular files
|
||||
--copy-unsafe-links copy links outside the source tree
|
||||
--safe-links ignore links outside the destination tree
|
||||
-H, --hard-links preserve hard links
|
||||
-p, --perms preserve permissions
|
||||
-o, --owner preserve owner (root only)
|
||||
-g, --group preserve group
|
||||
-D, --devices preserve devices (root only)
|
||||
-t, --times preserve times
|
||||
-S, --sparse handle sparse files efficiently
|
||||
-n, --dry-run show what would have been transferred
|
||||
-W, --whole-file copy whole files, no incremental checks
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size=SIZE checksum blocking size (default 700)
|
||||
-e, --rsh=COMMAND specify rsh replacement
|
||||
--rsync-path=PATH specify path to rsync on the remote machine
|
||||
-C, --cvs-exclude auto ignore files in the same way CVS does
|
||||
--delete delete files that don't exist on the sending side
|
||||
--delete-excluded also delete excluded files on the receiving side
|
||||
--partial keep partially transferred files
|
||||
--force force deletion of directories even if not empty
|
||||
--numeric-ids don't map uid/gid values by user/group name
|
||||
--timeout=TIME set IO timeout in seconds
|
||||
-I, --ignore-times don't exclude files that match length and time
|
||||
--size-only only use file size when determining if a file should be transferred
|
||||
-T --temp-dir=DIR create temporary files in directory DIR
|
||||
--compare-dest=DIR also compare destination files relative to DIR
|
||||
-z, --compress compress file data
|
||||
--exclude=PATTERN exclude files matching PATTERN
|
||||
--exclude-from=FILE exclude patterns listed in FILE
|
||||
--include=PATTERN don't exclude files matching PATTERN
|
||||
--include-from=FILE don't exclude patterns listed in FILE
|
||||
--version print version number
|
||||
--daemon run as a rsync daemon
|
||||
--config=FILE specify alternate rsyncd.conf file
|
||||
--port=PORT specify alternate rsyncd port number
|
||||
--stats give some file transfer stats
|
||||
--progress show progress during transfer
|
||||
--log-format=FORMAT log file transfers using specified format
|
||||
--password-file=FILE get password from FILE
|
||||
-h, --help show this help screen
|
||||
rsync --help
|
||||
|
||||
and see the manual for more information.
|
||||
|
||||
|
||||
SETUP
|
||||
@@ -137,13 +76,19 @@ BUG REPORTS
|
||||
-----------
|
||||
|
||||
If you have web access then please look at
|
||||
http://rsync.samba.org/rsync/
|
||||
|
||||
This will give you access to the bug tracking system used by the
|
||||
developers of rsync and will allow you to look at other bug reports or
|
||||
submit a new bug report.
|
||||
http://rsync.samba.org
|
||||
|
||||
If you don't have web access then mail bug reports to rsync@samba.org.
|
||||
That page contains links to the current bug list, and information on
|
||||
how to report a bug well. You might also like to try searching the
|
||||
internet for the error message you've received, or looking in the
|
||||
mailing list archives at
|
||||
|
||||
http://mail-archive.com/rsync@lists.samba.org/
|
||||
|
||||
Please send bug reports to
|
||||
|
||||
rsync@lists.samba.org
|
||||
|
||||
|
||||
CVS TREE
|
||||
|
||||
502
TODO
502
TODO
@@ -1,12 +1,111 @@
|
||||
-*- indented-text -*-
|
||||
|
||||
URGENT ---------------------------------------------------------------
|
||||
BUGS ---------------------------------------------------------------
|
||||
|
||||
rsync-url barfs on upload
|
||||
|
||||
rsync foo rsync://localhost/transfer/
|
||||
|
||||
Fix the parser.
|
||||
|
||||
|
||||
IMPORTANT ------------------------------------------------------------
|
||||
There seems to be a bug with hardlinks
|
||||
|
||||
mbp/2 build$ ls -l /tmp/a /tmp/b -i
|
||||
/tmp/a:
|
||||
total 32
|
||||
2568307 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
2568307 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
2568307 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
2568310 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
|
||||
/tmp/b:
|
||||
total 32
|
||||
2568309 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
2568309 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
2568309 -rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
2568311 -rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
mbp/2 build$ rm -r /tmp/b && ./rsync -avH /tmp/a/ /tmp/b
|
||||
building file list ... done
|
||||
created directory /tmp/b
|
||||
./
|
||||
a1
|
||||
a4
|
||||
a2 => a1
|
||||
a3 => a2
|
||||
wrote 350 bytes read 52 bytes 804.00 bytes/sec
|
||||
total size is 232 speedup is 0.58
|
||||
mbp/2 build$ rm -r /tmp/b
|
||||
mbp/2 build$ ls -l /tmp/b
|
||||
ls: /tmp/b: No such file or directory
|
||||
mbp/2 build$ rm -r /tmp/b && ./rsync -avH /tmp/a/ /tmp/b
|
||||
rm: cannot remove `/tmp/b': No such file or directory
|
||||
mbp/2 build$ rm -f -r /tmp/b && ./rsync -avH /tmp/a/ /tmp/b
|
||||
building file list ... done
|
||||
created directory /tmp/b
|
||||
./
|
||||
a1
|
||||
a4
|
||||
a2 => a1
|
||||
a3 => a2
|
||||
wrote 350 bytes read 52 bytes 804.00 bytes/sec
|
||||
total size is 232 speedup is 0.58
|
||||
mbp/2 build$ ls -l /tmp/b
|
||||
total 32
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
mbp/2 build$ ls -l /tmp/a
|
||||
total 32
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a1
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a2
|
||||
-rw-rw-r-- 3 mbp mbp 29 Mar 25 17:30 a3
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a4
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 a5
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b1
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b2
|
||||
-rw-rw-r-- 5 mbp mbp 29 Mar 25 17:30 b3
|
||||
|
||||
|
||||
Progress indicator can produce corrupt output when transferring directories:
|
||||
|
||||
main/binary-arm/
|
||||
main/binary-arm/admin/
|
||||
main/binary-arm/base/
|
||||
main/binary-arm/comm/8.56kB/s 0:00:52
|
||||
main/binary-arm/devel/
|
||||
main/binary-arm/doc/
|
||||
main/binary-arm/editors/
|
||||
main/binary-arm/electronics/s 0:00:53
|
||||
main/binary-arm/games/
|
||||
main/binary-arm/graphics/
|
||||
main/binary-arm/hamradio/
|
||||
main/binary-arm/interpreters/
|
||||
main/binary-arm/libs/6.61kB/s 0:00:54
|
||||
main/binary-arm/mail/
|
||||
main/binary-arm/math/
|
||||
main/binary-arm/misc/
|
||||
|
||||
|
||||
lchmod
|
||||
I don't think we handle this properly on systems that don't have the
|
||||
call. Are there any such?
|
||||
|
||||
|
||||
Cross-test versions
|
||||
|
||||
Part of the regression suite should be making sure that we don't
|
||||
break backwards compatibility: old clients vs new servers and so
|
||||
on. Ideally we would test the cross product of versions.
|
||||
@@ -16,6 +115,49 @@ Cross-test versions
|
||||
some testing and also be the most common case for having different
|
||||
versions and not being able to upgrade.
|
||||
|
||||
--no-blocking-io might be broken
|
||||
|
||||
in the same way as --no-whole-file; somebody needs to check.
|
||||
|
||||
Do not rely on having a group called "nobody"
|
||||
|
||||
http://www.linuxbase.org/spec/refspecs/LSB_1.1.0/gLSB/usernames.html
|
||||
|
||||
On Debian it's "nogroup"
|
||||
|
||||
Temporary file names can exceed max name length
|
||||
|
||||
Rsync creates temporary file names that are 10 characters longer
|
||||
than the length of the file being transferred. This creates
|
||||
problems for operating systems have fairly short maximum lengths
|
||||
(e.g., 32 characters for Stratus VOS). Even on operating systems
|
||||
with long max lengths it can still be a problem as it is perfectly
|
||||
reasonable to be using files with long names.
|
||||
|
||||
|
||||
DAEMON --------------------------------------------------------------
|
||||
|
||||
server-imposed bandwidth limits
|
||||
|
||||
rsyncd over ssh
|
||||
|
||||
There are already some patches to do this.
|
||||
|
||||
BitKeeper uses a server whose login shell is set to bkd. That's
|
||||
probably a reasonable approach.
|
||||
|
||||
|
||||
FEATURES ------------------------------------------------------------
|
||||
|
||||
|
||||
--dry-run is too dry
|
||||
|
||||
Mark Santcroos points out that -n fails to list files which have
|
||||
only metadata changes, though it probably should.
|
||||
|
||||
There may be a Debian bug about this as well.
|
||||
|
||||
|
||||
use chroot
|
||||
|
||||
If the platform doesn't support it, then don't even try.
|
||||
@@ -26,22 +168,31 @@ use chroot
|
||||
http://lists.samba.org/pipermail/rsync/2001-August/thread.html
|
||||
http://lists.samba.org/pipermail/rsync/2001-September/thread.html
|
||||
|
||||
|
||||
--files-from
|
||||
|
||||
Avoids traversal. Better option than a pile of --include statements
|
||||
for people who want to generate the file list using a find(1)
|
||||
command or a script.
|
||||
|
||||
|
||||
supplementary groups
|
||||
|
||||
Perhaps allow supplementary groups to be specified in rsyncd.conf;
|
||||
then make the first one the primary gid and all the rest be
|
||||
supplementary gids.
|
||||
|
||||
|
||||
File list structure in memory
|
||||
|
||||
Rather than one big array, perhaps have a tree in memory mirroring
|
||||
the directory tree.
|
||||
the directory tree.
|
||||
|
||||
This might make sorting much faster! (I'm not sure it's a big CPU
|
||||
problem, mind you.)
|
||||
problem, mind you.)
|
||||
|
||||
It might also reduce memory use in storing repeated directory names
|
||||
-- again I'm not sure this is a problem.
|
||||
-- again I'm not sure this is a problem.
|
||||
|
||||
Performance
|
||||
|
||||
@@ -62,7 +213,7 @@ Handling duplicate names
|
||||
through the pipeline at the same time. For example we might have
|
||||
updated the first occurrence after reading the checksums for the
|
||||
second. So possibly we just need to make sure that we don't have
|
||||
both in the pipeline at the same time.
|
||||
both in the pipeline at the same time.
|
||||
|
||||
Possibly if we did one directory at a time that would be sufficient.
|
||||
|
||||
@@ -108,7 +259,7 @@ Memory accounting
|
||||
Hard-link handling
|
||||
|
||||
At the moment hardlink handling is very expensive, so it's off by
|
||||
default. It does not need to be so.
|
||||
default. It does not need to be so.
|
||||
|
||||
Since most of the solutions are rather intertwined with the file
|
||||
list it is probably better to fix that first, although fixing
|
||||
@@ -122,7 +273,7 @@ Hard-link handling
|
||||
but I have not seen them.
|
||||
|
||||
When trying to reproduce hard links, we only need to worry about
|
||||
files that have more than one name (nlinks>1 && !S_ISDIR).
|
||||
files that have more than one name (nlinks>1 && !S_ISDIR).
|
||||
|
||||
The basic point of this is to discover alternate names that refer to
|
||||
the same file. All operations, including creating the file and
|
||||
@@ -172,8 +323,39 @@ Hard-link handling
|
||||
might need a little program to check whether several names refer to
|
||||
the same file.
|
||||
|
||||
IPv6
|
||||
|
||||
|
||||
Handling IPv6 on old machines
|
||||
|
||||
The KAME IPv6 patch is nice in theory but has proved a bit of a
|
||||
nightmare in practice. The basic idea of their patch is that rsync
|
||||
is rewritten to use the new getaddrinfo()/getnameinfo() interface,
|
||||
rather than gethostbyname()/gethostbyaddr() as in rsync 2.4.6.
|
||||
Systems that don't have the new interface are handled by providing
|
||||
our own implementation in lib/, which is selectively linked in.
|
||||
|
||||
The problem with this is that it is really hard to get right on
|
||||
platforms that have a half-working implementation, so redefining
|
||||
these functions clashes with system headers, and leaving them out
|
||||
breaks. This affects at least OSF/1, RedHat 5, and Cobalt, which
|
||||
are moderately improtant.
|
||||
|
||||
Perhaps the simplest solution would be to have two different files
|
||||
implementing the same interface, and choose either the new or the
|
||||
old API. This is probably necessary for systems that e.g. have
|
||||
IPv6, but gethostbyaddr() can't handle it. The Linux manpage claims
|
||||
this is currently the case.
|
||||
|
||||
In fact, our internal sockets interface (things like
|
||||
open_socket_out(), etc) is much narrower than the getaddrinfo()
|
||||
interface, and so probably simpler to get right. In addition, the
|
||||
old code is known to work well on old machines.
|
||||
|
||||
We could drop the rather large lib/getaddrinfo files.
|
||||
|
||||
|
||||
Other IPv6 stuff:
|
||||
|
||||
Implement suggestions from http://www.kame.net/newsletter/19980604/
|
||||
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
|
||||
|
||||
@@ -189,11 +371,11 @@ IPv6
|
||||
colons, they tend to break most naming systems, including ours.
|
||||
Based on the HTTP IPv6 syntax, I think we should use
|
||||
|
||||
rsync://[::1]/foo/bar
|
||||
[::1]::bar
|
||||
rsync://[::1]/foo/bar [::1]::bar
|
||||
|
||||
which should just take a small change to the parser code.
|
||||
|
||||
|
||||
Errors
|
||||
|
||||
If we hang or get SIGINT, then explain where we were up to. Perhaps
|
||||
@@ -203,13 +385,18 @@ Errors
|
||||
|
||||
"The dungeon collapses! You are killed." Rather than "unexpected
|
||||
eof" give a message that is more detailed if possible and also more
|
||||
helpful.
|
||||
helpful.
|
||||
|
||||
If we get an error writing to a socket, then we should perhaps
|
||||
continue trying to read to see if an error message comes across
|
||||
explaining why the socket is closed. I'm not sure if this would
|
||||
work, but it would certainly make our messages more helpful.
|
||||
|
||||
What happens if a directory is missing -x attributes. Do we lose
|
||||
our load? (Debian #28416) Probably fixed now, but a test case would
|
||||
be good.
|
||||
|
||||
|
||||
File attributes
|
||||
|
||||
Device major/minor numbers should be at least 32 bits each. See
|
||||
@@ -228,7 +415,7 @@ Empty directories
|
||||
|
||||
zlib
|
||||
|
||||
Perhaps don't use our own zlib.
|
||||
Perhaps don't use our own zlib.
|
||||
|
||||
Advantages:
|
||||
|
||||
@@ -259,14 +446,26 @@ logging
|
||||
At the connections that just get a list of modules are not logged,
|
||||
but they should be.
|
||||
|
||||
rsyncd over ssh
|
||||
If a child of the rsync daemon dies with a signal, we should notice
|
||||
that when we reap it and log a message.
|
||||
|
||||
Keep stderr and stdout properly separated (Debian #23626)
|
||||
|
||||
After we get the @RSYNCD greeting from the server, we know it's
|
||||
version but we have not yet sent the command line, so we could just
|
||||
remove the -z option if the server is too old.
|
||||
|
||||
For ssh invocation it's not so simple, because we actually use the
|
||||
command line to start the remote process. However, we only actually
|
||||
do compression in token.c, and we could therefore once we discover
|
||||
the remote version emit an error if it's too old. I'm not sure if
|
||||
that's a good tradeoff or not.
|
||||
|
||||
There are already some patches to do this.
|
||||
|
||||
proxy authentication
|
||||
|
||||
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
|
||||
HTTP Basic Proxy-Authentication.
|
||||
HTTP Basic Proxy-Authentication.
|
||||
|
||||
Multiple schemes are possible, up to and including the insanity that
|
||||
is NTLM, but Basic probably covers most cases.
|
||||
@@ -276,18 +475,25 @@ SOCKS
|
||||
Add --with-socks, and then perhaps a command-line option to put them
|
||||
on or off. This might be more reliable than LD_PRELOAD hacks.
|
||||
|
||||
FAT support
|
||||
|
||||
rsync to a FAT partition on a Unix machine doesn't work very well at
|
||||
the moment. I think we get errors about invalid filenames and
|
||||
perhaps also trying to do atomic renames.
|
||||
|
||||
I guess the code to do this is currently #ifdef'd on Windows;
|
||||
perhaps we ought to intelligently fall back to it on Unix too.
|
||||
|
||||
|
||||
Better statistics:
|
||||
|
||||
<Rasmus> mbp: hey, how about an rsync option that just gives you the
|
||||
summary without the list of files? And perhaps gives more
|
||||
information like the number of new files, number of changed,
|
||||
deleted, etc. ?
|
||||
<mbp> Rasmus: nice idea
|
||||
<mbp> there is --stats
|
||||
<mbp> but at the moment it's very tridge-oriented
|
||||
<mbp> rather than user-friendly
|
||||
<mbp> it would be nice to improve it
|
||||
<mbp> that would also work well with --dryrun
|
||||
deleted, etc. ? <mbp> Rasmus: nice idea <mbp> there is --stats
|
||||
<mbp> but at the moment it's very tridge-oriented <mbp> rather than
|
||||
user-friendly <mbp> it would be nice to improve it <mbp> that would
|
||||
also work well with --dryrun
|
||||
|
||||
TDB:
|
||||
|
||||
@@ -304,23 +510,84 @@ TDB:
|
||||
|
||||
chmod:
|
||||
|
||||
On 12 Mar 2002, Dave Dykstra <dwd@bell-labs.com> wrote:
|
||||
> If we would add an option to do that functionality, I would vote for one
|
||||
> that was more general which could mask off any set of permission bits and
|
||||
> possibly add any set of bits. Perhaps a chmod-like syntax if it could be
|
||||
> implemented simply.
|
||||
On 12 Mar 2002, Dave Dykstra <dwd@bell-labs.com> wrote: > If we
|
||||
would add an option to do that functionality, I would vote for one >
|
||||
that was more general which could mask off any set of permission bits
|
||||
and > possibly add any set of bits. Perhaps a chmod-like syntax if it
|
||||
could be > implemented simply.
|
||||
|
||||
I think that would be good too. For example, people uploading files
|
||||
I think that would be good too. For example, people uploading files
|
||||
to a web server might like to say
|
||||
|
||||
rsync -avzP --chmod a+rX ./ sourcefrog.net:/home/www/sourcefrog/
|
||||
|
||||
Ideally the patch would implement as many of the gnu chmod semantics
|
||||
as possible. I think the mode parser should be a separate function
|
||||
that passes back something like (mask,set) description to the rest of
|
||||
the program. For bonus points there would be a test case for the
|
||||
that passes back something like (mask,set) description to the rest
|
||||
of the program. For bonus points there would be a test case for the
|
||||
parser.
|
||||
|
||||
Possibly also --chown
|
||||
|
||||
(Debian #23628)
|
||||
|
||||
|
||||
--diff
|
||||
|
||||
Allow people to specify the diff command. (Might want to use wdiff,
|
||||
gnudiff, etc.)
|
||||
|
||||
Just diff the temporary file with the destination file, and delete
|
||||
the tmp file rather than moving it into place.
|
||||
|
||||
Interaction with --partial.
|
||||
|
||||
Security interactions with daemon mode?
|
||||
|
||||
(Suggestion from david.e.sewell)
|
||||
|
||||
|
||||
Incorrect timestamps (Debian #100295)
|
||||
|
||||
A bit hard to believe, but apparently it happens.
|
||||
|
||||
|
||||
Check "refuse options works"
|
||||
|
||||
We need a test case for this...
|
||||
|
||||
Was this broken when we changed to popt?
|
||||
|
||||
|
||||
PERFORMANCE ----------------------------------------------------------
|
||||
|
||||
MD4 file_sum
|
||||
|
||||
If we're doing a local transfer, or using -W, then perhaps don't
|
||||
send the file checksum. If we're doing a local transfer, then
|
||||
calculating MD4 checksums uses 90% of CPU and is unlikely to be
|
||||
useful.
|
||||
|
||||
Indeed for transfers over zlib or ssh we can also rely on the
|
||||
transport to have quite strong protection against corruption.
|
||||
|
||||
Perhaps we should have an option to disable this, analogous to
|
||||
--whole-file, although it would default to disabled. The file
|
||||
checksum takes up a definite space in the protocol -- we can either
|
||||
set it to 0, or perhaps just leave it out.
|
||||
|
||||
MD4
|
||||
|
||||
Perhaps borrow an assembler MD4 from someone?
|
||||
|
||||
Make sure we call MD4 with properly-sized blocks whenever possible
|
||||
to avoid copying into the residue region?
|
||||
|
||||
String area code
|
||||
|
||||
Test whether this is actually faster than just using malloc(). If
|
||||
it's not (anymore), throw it out.
|
||||
|
||||
|
||||
PLATFORMS ------------------------------------------------------------
|
||||
|
||||
@@ -330,12 +597,6 @@ Win32
|
||||
|
||||
http://sources.redhat.com/ml/cygwin/2001-08/msg00234.html
|
||||
|
||||
According to "Effective TCP/IP Programming" (??) close() on a socket
|
||||
has incorrect behaviour on Windows -- it sends a RST packet to the
|
||||
other side, which gives a "connection reset by peer" error. On that
|
||||
platform we should probably do shutdown() instead. However, on Unix
|
||||
we are correct to call close(), because shutdown() discards
|
||||
untransmitted data.
|
||||
|
||||
DEVELOPMENT ----------------------------------------------------------
|
||||
|
||||
@@ -362,22 +623,148 @@ Memory debugger
|
||||
|
||||
http://devel-home.kde.org/~sewardj/
|
||||
|
||||
Release script
|
||||
|
||||
Update spec files
|
||||
|
||||
Build tar file; upload
|
||||
|
||||
Send announcement to mailing list and c.o.l.a.
|
||||
|
||||
Make freshmeat announcement
|
||||
|
||||
Update web site
|
||||
|
||||
|
||||
|
||||
TESTING --------------------------------------------------------------
|
||||
|
||||
Cross-test versions
|
||||
|
||||
Part of the regression suite should be making sure that we don't
|
||||
break backwards compatibility: old clients vs new servers and so on.
|
||||
Ideally we would test both up and down from the current release to
|
||||
all old versions.
|
||||
|
||||
We might need to omit broken old versions, or versions in which
|
||||
particular functionality is broken
|
||||
|
||||
It might be sufficient to test downloads from well-known public
|
||||
rsync servers running different versions of rsync. This will give
|
||||
some testing and also be the most common case for having different
|
||||
versions and not being able to upgrade.
|
||||
|
||||
|
||||
Test on kernel source
|
||||
|
||||
Download all versions of kernel; unpack, sync between them. Also
|
||||
sync between uncompressed tarballs. Compare directories after
|
||||
transfer.
|
||||
|
||||
Use local mode; ssh; daemon; --whole-file and --no-whole-file.
|
||||
|
||||
Use awk to pull out the 'speedup' number for each transfer. Make
|
||||
sure it is >= x.
|
||||
|
||||
|
||||
Test large files
|
||||
|
||||
Sparse and non-sparse
|
||||
|
||||
Mutator program
|
||||
|
||||
Insert bytes, delete bytes, swap blocks, ...
|
||||
|
||||
configure option to enable dangerous tests
|
||||
|
||||
If tests are skipped, say why.
|
||||
|
||||
Test daemon feature to disallow particular options.
|
||||
|
||||
Pipe program that makes slow/jerky connections.
|
||||
|
||||
Versions of read() and write() that corrupt the stream, or abruptly
|
||||
fail
|
||||
|
||||
Separate makefile target to run rough tests -- or perhaps just run
|
||||
them every time?
|
||||
|
||||
Test "refuse options" works
|
||||
|
||||
What about for --recursive?
|
||||
|
||||
If you specify an unrecognized option here, you should get an error.
|
||||
|
||||
|
||||
DOCUMENTATION --------------------------------------------------------
|
||||
|
||||
Update README
|
||||
|
||||
Keep list of open issues and todos on the web site
|
||||
|
||||
Update web site from CVS
|
||||
|
||||
|
||||
Perhaps redo manual as SGML
|
||||
|
||||
The man page is getting rather large, and there is more information
|
||||
that ought to be added.
|
||||
|
||||
TexInfo source is probably a dying format.
|
||||
|
||||
Linuxdoc looks like the most likely contender. I know DocBook is
|
||||
favoured by some people, but it's so bloody verbose, even with emacs
|
||||
support.
|
||||
|
||||
|
||||
BUILD FARM -----------------------------------------------------------
|
||||
|
||||
Add machines
|
||||
|
||||
AMDAHL UTS (Dave Dykstra)
|
||||
|
||||
Cygwin (on different versions of Win32?)
|
||||
|
||||
HP-UX variants (via HP?)
|
||||
|
||||
SCO
|
||||
|
||||
|
||||
LOGGING --------------------------------------------------------------
|
||||
|
||||
Perhaps flush stdout after each filename, so that people trying to
|
||||
monitor progress in a log file can do so more easily. See
|
||||
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=48108
|
||||
|
||||
At the connections that just get a list of modules are not logged,
|
||||
but they should be.
|
||||
|
||||
If a child of the rsync daemon dies with a signal, we should notice
|
||||
that when we reap it and log a message.
|
||||
|
||||
Keep stderr and stdout properly separated (Debian #23626)
|
||||
|
||||
Use a separate function for reporting errors; prefix it with
|
||||
"rsync:" or "rsync(remote)", or perhaps even "rsync(local
|
||||
generator): ".
|
||||
|
||||
verbose output
|
||||
|
||||
Indicate whether files are new, updated, or deleted
|
||||
|
||||
At end of transfer, show how many files were or were not transferred
|
||||
correctly.
|
||||
|
||||
-vv
|
||||
|
||||
Explain *why* every file is transferred or not (e.g. "local mtime
|
||||
123123 newer than 1283198")
|
||||
|
||||
|
||||
debugging of daemon
|
||||
|
||||
Add an rsyncd.conf parameter to turn on debugging on the server.
|
||||
|
||||
|
||||
|
||||
NICE -----------------------------------------------------------------
|
||||
|
||||
--no-detach and --no-fork options
|
||||
@@ -388,26 +775,41 @@ NICE -----------------------------------------------------------------
|
||||
|
||||
hang/timeout friendliness
|
||||
|
||||
verbose output
|
||||
|
||||
Indicate whether files are new, updated, or deleted
|
||||
|
||||
At end of transfer, show how many files were or were not transferred
|
||||
correctly.
|
||||
|
||||
internationalization
|
||||
|
||||
Change to using gettext(). Probably need to ship this for platforms
|
||||
that don't have it.
|
||||
that don't have it.
|
||||
|
||||
Solicit translations.
|
||||
|
||||
Does anyone care?
|
||||
Does anyone care? Before we bother modifying the code, we ought to
|
||||
get the manual translated first, because that's possibly more useful
|
||||
and at any rate demonstrates desire.
|
||||
|
||||
rsyncsh
|
||||
rsyncsh
|
||||
|
||||
Write a small emulation of interactive ftp as a Pythonn program
|
||||
that calls rsync. Commands such as "cd", "ls", "ls *.c" etc map
|
||||
fairly directly into rsync commands: it just needs to remember the
|
||||
current host, directory and so on. We can probably even do
|
||||
completion of remote filenames.
|
||||
|
||||
|
||||
RELATED PROJECTS -----------------------------------------------------
|
||||
|
||||
http://rsync.samba.org/rsync-and-debian/
|
||||
|
||||
rsyncable gzip patch
|
||||
|
||||
Exhaustive, tortuous testing
|
||||
|
||||
Cleanups?
|
||||
|
||||
rsyncsplit as alternative to real integration with gzip?
|
||||
|
||||
reverse rsync over HTTP Range
|
||||
|
||||
Goswin Brederlow suggested this on Debian; I think tridge and I
|
||||
talked about it previous in relation to rproxy.
|
||||
|
||||
|
||||
|
||||
172
access.c
172
access.c
@@ -30,54 +30,166 @@ static int match_hostname(char *host, char *tok)
|
||||
return (fnmatch(tok, host, 0) == 0);
|
||||
}
|
||||
|
||||
static int match_binary(char *b1, char *b2, char *mask, int addrlen)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<addrlen; i++) {
|
||||
if ((b1[i]^b2[i])&mask[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void make_mask(char *mask, int plen, int addrlen) {
|
||||
int w, b;
|
||||
|
||||
w = plen >> 3;
|
||||
b = plen & 0x7;
|
||||
|
||||
if (w)
|
||||
memset(mask, 0xff, w);
|
||||
if (w < addrlen)
|
||||
mask[w] = 0xff & (0xff<<(8-b));
|
||||
if (w+1 < addrlen)
|
||||
memset(mask+w+1, 0, addrlen-w-1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int match_address(char *addr, char *tok)
|
||||
{
|
||||
char *p;
|
||||
unsigned long a, t, mask = (unsigned long)~0;
|
||||
struct addrinfo hints, *resa, *rest;
|
||||
int gai;
|
||||
int ret = 0;
|
||||
int addrlen = 0;
|
||||
#ifdef HAVE_STRTOL
|
||||
long int bits;
|
||||
#else
|
||||
int bits;
|
||||
#endif
|
||||
char mask[16];
|
||||
char *a = NULL, *t = NULL;
|
||||
|
||||
if (!addr || !*addr) return 0;
|
||||
|
||||
if (!isdigit(tok[0])) return 0;
|
||||
|
||||
p = strchr(tok,'/');
|
||||
if (p) *p = 0;
|
||||
|
||||
a = inet_addr(addr);
|
||||
t = inet_addr(tok);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
#ifdef AI_NUMERICHOST
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
#endif
|
||||
|
||||
if (p) {
|
||||
*p = '/';
|
||||
}
|
||||
gai = getaddrinfo(addr, NULL, &hints, &resa);
|
||||
if (gai) return 0;
|
||||
|
||||
if (t == INADDR_NONE) {
|
||||
gai = getaddrinfo(tok, NULL, &hints, &rest);
|
||||
if (p)
|
||||
*p++ = '/';
|
||||
if (gai) {
|
||||
rprintf(FERROR,"malformed address %s\n", tok);
|
||||
freeaddrinfo(resa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
a = ntohl(a);
|
||||
t = ntohl(t);
|
||||
|
||||
if (p) {
|
||||
if (strchr(p+1,'.')) {
|
||||
mask = inet_addr(p+1);
|
||||
if (mask == INADDR_NONE) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
return 0;
|
||||
}
|
||||
mask = ntohl(mask);
|
||||
} else {
|
||||
int bits = atoi(p+1);
|
||||
if (bits == 0) return 1;
|
||||
if (bits <= 0 || bits > 32) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
return 0;
|
||||
}
|
||||
mask &= (mask << (32-bits));
|
||||
}
|
||||
if (rest->ai_family != resa->ai_family) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return ((a&mask) == (t&mask));
|
||||
switch(resa->ai_family) {
|
||||
case PF_INET:
|
||||
a = (char *)&((struct sockaddr_in *)resa->ai_addr)->sin_addr;
|
||||
t = (char *)&((struct sockaddr_in *)rest->ai_addr)->sin_addr;
|
||||
addrlen = 4;
|
||||
|
||||
break;
|
||||
|
||||
#ifdef INET6
|
||||
case PF_INET6:
|
||||
{
|
||||
struct sockaddr_in6 *sin6a, *sin6t;
|
||||
|
||||
sin6a = (struct sockaddr_in6 *)resa->ai_addr;
|
||||
sin6t = (struct sockaddr_in6 *)rest->ai_addr;
|
||||
|
||||
a = (char *)&sin6a->sin6_addr;
|
||||
t = (char *)&sin6t->sin6_addr;
|
||||
|
||||
addrlen = 16;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
if (sin6t->sin6_scope_id &&
|
||||
sin6a->sin6_scope_id != sin6t->sin6_scope_id) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
rprintf(FERROR,"unknown family %u\n", rest->ai_family);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bits = -1;
|
||||
if (p) {
|
||||
if (inet_pton(resa->ai_addr->sa_family, p, mask) <= 0) {
|
||||
#ifdef HAVE_STRTOL
|
||||
char *ep = NULL;
|
||||
#else
|
||||
unsigned char *pp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRTOL
|
||||
bits = strtol(p, &ep, 10);
|
||||
if (!*p || *ep) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
for (pp = (unsigned char *)p; *pp; pp++) {
|
||||
if (!isascii(*pp) || !isdigit(*pp)) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
bits = atoi(p);
|
||||
#endif
|
||||
if (bits == 0) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
if (bits < 0 || bits > (addrlen << 3)) {
|
||||
rprintf(FERROR,"malformed mask in %s\n", tok);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bits = 128;
|
||||
}
|
||||
|
||||
if (bits >= 0)
|
||||
make_mask(mask, bits, addrlen);
|
||||
|
||||
ret = match_binary(a, t, mask, addrlen);
|
||||
|
||||
out:
|
||||
freeaddrinfo(resa);
|
||||
freeaddrinfo(rest);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int access_match(char *list, char *addr, char *host)
|
||||
|
||||
@@ -7,4 +7,5 @@
|
||||
#undef HAVE_GETTIMEOFDAY_TZ
|
||||
#undef ENABLE_IPV6
|
||||
#undef HAVE_SOCKADDR_LEN
|
||||
#undef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
#undef HAVE_SOCKETPAIR
|
||||
|
||||
@@ -203,7 +203,7 @@ static void generate_hash(char *in, char *challenge, char *out)
|
||||
|
||||
otherwise return username
|
||||
*/
|
||||
char *auth_server(int fd, int module, char *addr, char *leader)
|
||||
char *auth_server(int f_in, int f_out, int module, char *addr, char *leader)
|
||||
{
|
||||
char *users = lp_auth_users(module);
|
||||
char challenge[16];
|
||||
@@ -222,9 +222,9 @@ char *auth_server(int fd, int module, char *addr, char *leader)
|
||||
|
||||
base64_encode(challenge, 16, b64_challenge);
|
||||
|
||||
io_printf(fd,"%s%s\n", leader, b64_challenge);
|
||||
io_printf(f_out, "%s%s\n", leader, b64_challenge);
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
10
backup.c
10
backup.c
@@ -21,6 +21,7 @@
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
extern int suffix_specified;
|
||||
extern char *backup_suffix;
|
||||
extern char *backup_dir;
|
||||
|
||||
@@ -203,12 +204,17 @@ static int keep_backup(char *fname)
|
||||
if (!file) return 1;
|
||||
|
||||
/* make a complete pathname for backup file */
|
||||
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {
|
||||
if (strlen(backup_dir) + strlen(fname) +
|
||||
(suffix_specified ? strlen(backup_suffix) : 0) > (MAXPATHLEN - 1)) {
|
||||
rprintf (FERROR, "keep_backup filename too long\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
|
||||
if (suffix_specified) {
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s%s", backup_dir, fname, backup_suffix);
|
||||
} else {
|
||||
snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_MKNOD
|
||||
|
||||
19
batch.c
19
batch.c
@@ -264,7 +264,7 @@ int read_batch_flist_file(char *buff, int len)
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
unsigned char read_batch_flags()
|
||||
unsigned char read_batch_flags(void)
|
||||
{
|
||||
int flags;
|
||||
|
||||
@@ -392,20 +392,27 @@ void close_batch_csums_file(void)
|
||||
close(fdb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write csum info to batch file
|
||||
*
|
||||
* @todo This will break if s->count is ever larger than maxint. The
|
||||
* batch code should probably be changed to consistently use the
|
||||
* variable-length integer routines, which is probably a compatible
|
||||
* change.
|
||||
**/
|
||||
void write_batch_csum_info(int *flist_entry, int flist_count,
|
||||
struct sum_struct *s)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int int_zero = 0;
|
||||
int int_count;
|
||||
extern int csum_length;
|
||||
|
||||
fdb_open = 1;
|
||||
|
||||
/* Write csum info to batch file */
|
||||
|
||||
/* FIXME: This will break if s->count is ever not exactly an int. */
|
||||
write_batch_csums_file(flist_entry, sizeof(int));
|
||||
write_batch_csums_file(s ? &s->count : &int_zero, sizeof(int));
|
||||
int_count = s ? (int) s->count : 0;
|
||||
write_batch_csums_file(&int_count, sizeof int_count);
|
||||
|
||||
if (s) {
|
||||
for (i = 0; i < s->count; i++) {
|
||||
|
||||
10
checksum.c
10
checksum.c
@@ -140,7 +140,15 @@ void sum_init(void)
|
||||
sum_update(s,4);
|
||||
}
|
||||
|
||||
void sum_update(char *p,int len)
|
||||
/**
|
||||
* Feed data into an MD4 accumulator, md. The results may be
|
||||
* retrieved using sum_end(). md is used for different purposes at
|
||||
* different points during execution.
|
||||
*
|
||||
* @todo Perhaps get rid of md and just pass in the address each time.
|
||||
* Very slightly clearer and slower.
|
||||
**/
|
||||
void sum_update(char *p, int len)
|
||||
{
|
||||
int i;
|
||||
if (len + sumresidue < CSUM_CHUNK) {
|
||||
|
||||
73
cleanup.c
73
cleanup.c
@@ -2,6 +2,7 @@
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -20,9 +21,50 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* handling the cleanup when a transfer is interrupted is tricky when
|
||||
--partial is selected. We need to ensure that the partial file is
|
||||
kept if any real data has been transferred */
|
||||
/**
|
||||
* Close all open sockets and files, allowing a (somewhat) graceful
|
||||
* shutdown() of socket connections. This eliminates the abortive
|
||||
* TCP RST sent by a Winsock-based system when the close() occurs.
|
||||
**/
|
||||
void close_all()
|
||||
{
|
||||
#ifdef SHUTDOWN_ALL_SOCKETS
|
||||
int max_fd;
|
||||
int fd;
|
||||
int ret;
|
||||
struct stat st;
|
||||
|
||||
max_fd = sysconf(_SC_OPEN_MAX) - 1;
|
||||
for (fd = max_fd; fd >= 0; fd--) {
|
||||
ret = fstat(fd,&st);
|
||||
if (fstat(fd,&st) == 0) {
|
||||
if (is_a_socket(fd)) {
|
||||
ret = shutdown(fd, 2);
|
||||
}
|
||||
ret = close(fd);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @file cleanup.c
|
||||
*
|
||||
* Code for handling interrupted transfers. Depending on the @c
|
||||
* --partial option, we may either delete the temporary file, or go
|
||||
* ahead and overwrite the destination. This second behaviour only
|
||||
* occurs if we've sent literal data and therefore hopefully made
|
||||
* progress on the transfer.
|
||||
**/
|
||||
|
||||
/**
|
||||
* Set to True once literal data has been sent across the link for the
|
||||
* current file. (????)
|
||||
*
|
||||
* Handling the cleanup when a transfer is interrupted is tricky when
|
||||
* --partial is selected. We need to ensure that the partial file is
|
||||
* kept if any real data has been transferred.
|
||||
**/
|
||||
int cleanup_got_literal=0;
|
||||
|
||||
static char *cleanup_fname;
|
||||
@@ -35,17 +77,31 @@ extern int io_error;
|
||||
|
||||
pid_t cleanup_child_pid = -1;
|
||||
|
||||
/*
|
||||
* Code is one of the RERR_* codes from errcode.h.
|
||||
*/
|
||||
/**
|
||||
* Eventually calls exit(), passing @p code, therefore does not return.
|
||||
*
|
||||
* @param code one of the RERR_* codes from errcode.h.
|
||||
**/
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
int ocode = code;
|
||||
extern int keep_partial;
|
||||
extern int log_got_error;
|
||||
static int inside_cleanup = 0;
|
||||
|
||||
if (inside_cleanup > 10) {
|
||||
/* prevent the occasional infinite recursion */
|
||||
return;
|
||||
}
|
||||
inside_cleanup++;
|
||||
|
||||
signal(SIGUSR1, SIG_IGN);
|
||||
signal(SIGUSR2, SIG_IGN);
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): entered\n",
|
||||
code, file, line);
|
||||
|
||||
if (cleanup_child_pid != -1) {
|
||||
int status;
|
||||
if (waitpid(cleanup_child_pid, &status, WNOHANG) == cleanup_child_pid) {
|
||||
@@ -81,6 +137,11 @@ void _exit_cleanup(int code, const char *file, int line)
|
||||
|
||||
if (code) log_exit(code, file, line);
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"_exit_cleanup(code=%d, file=%s, line=%d): about to call exit(%d)\n",
|
||||
ocode, file, line, code);
|
||||
|
||||
close_all();
|
||||
exit(code);
|
||||
}
|
||||
|
||||
|
||||
112
clientname.c
112
clientname.c
@@ -34,6 +34,8 @@
|
||||
#include "rsync.h"
|
||||
|
||||
static const char default_name[] = "UNKNOWN";
|
||||
extern int am_daemon;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
/**
|
||||
@@ -43,6 +45,8 @@ char *client_addr(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t length = sizeof ss;
|
||||
char *ssh_client, *p;
|
||||
int len;
|
||||
static char addr_buf[100];
|
||||
static int initialised;
|
||||
|
||||
@@ -50,11 +54,25 @@ char *client_addr(int fd)
|
||||
|
||||
initialised = 1;
|
||||
|
||||
client_sockaddr(fd, &ss, &length);
|
||||
if (am_server) {
|
||||
/* daemon over --rsh mode */
|
||||
strcpy(addr_buf, "0.0.0.0");
|
||||
if ((ssh_client = getenv("SSH_CLIENT")) != NULL) {
|
||||
/* truncate SSH_CLIENT to just IP address */
|
||||
p = strchr(ssh_client, ' ');
|
||||
if (p) {
|
||||
len = MIN((unsigned int) (p - ssh_client),
|
||||
sizeof(addr_buf) - 1);
|
||||
strncpy(addr_buf, ssh_client, len);
|
||||
*(addr_buf + len) = '\0';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
client_sockaddr(fd, &ss, &length);
|
||||
getnameinfo((struct sockaddr *)&ss, length,
|
||||
addr_buf, sizeof addr_buf, NULL, 0, NI_NUMERICHOST);
|
||||
}
|
||||
|
||||
getnameinfo((struct sockaddr *)&ss, length,
|
||||
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
|
||||
|
||||
return addr_buf;
|
||||
}
|
||||
|
||||
@@ -74,24 +92,67 @@ static int get_sockaddr_family(const struct sockaddr_storage *ss)
|
||||
* If anything goes wrong, including the name->addr->name check, then
|
||||
* we just use "UNKNOWN", so you can use that value in hosts allow
|
||||
* lines.
|
||||
*
|
||||
* After translation from sockaddr to name we do a forward lookup to
|
||||
* make sure nobody is spoofing PTR records.
|
||||
**/
|
||||
char *client_name(int fd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len = sizeof ss;
|
||||
static char name_buf[100];
|
||||
static char port_buf[100];
|
||||
static int initialised;
|
||||
struct sockaddr_storage ss, *ssp;
|
||||
struct sockaddr_in sin;
|
||||
#ifdef INET6
|
||||
struct sockaddr_in6 sin6;
|
||||
#endif
|
||||
socklen_t ss_len;
|
||||
|
||||
if (initialised) return name_buf;
|
||||
|
||||
strcpy(name_buf, default_name);
|
||||
initialised = 1;
|
||||
|
||||
client_sockaddr(fd, &ss, &ss_len);
|
||||
if (am_server) {
|
||||
/* daemon over --rsh mode */
|
||||
|
||||
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
|
||||
check_name(fd, &ss, name_buf, port_buf);
|
||||
char *addr = client_addr(fd);
|
||||
#ifdef INET6
|
||||
int dots = 0;
|
||||
char *p;
|
||||
|
||||
for (p = addr; *p && (dots <= 3); p++) {
|
||||
if (*p == '.')
|
||||
dots++;
|
||||
}
|
||||
if (dots > 3) {
|
||||
/* more than 4 parts to IP address, must be ipv6 */
|
||||
ssp = (struct sockaddr_storage *) &sin6;
|
||||
ss_len = sizeof sin6;
|
||||
memset(ssp, 0, ss_len);
|
||||
inet_pton(AF_INET6, addr, &sin6.sin6_addr);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ssp = (struct sockaddr_storage *) &sin;
|
||||
ss_len = sizeof sin;
|
||||
memset(ssp, 0, ss_len);
|
||||
inet_pton(AF_INET, addr, &sin.sin_addr);
|
||||
sin.sin_family = AF_INET;
|
||||
}
|
||||
|
||||
} else {
|
||||
ss_len = sizeof ss;
|
||||
ssp = &ss;
|
||||
|
||||
client_sockaddr(fd, &ss, &ss_len);
|
||||
|
||||
}
|
||||
|
||||
if (!lookup_name(fd, ssp, ss_len, name_buf, sizeof name_buf,
|
||||
port_buf, sizeof port_buf))
|
||||
check_name(fd, ssp, name_buf);
|
||||
|
||||
return name_buf;
|
||||
}
|
||||
@@ -108,6 +169,8 @@ void client_sockaddr(int fd,
|
||||
struct sockaddr_storage *ss,
|
||||
socklen_t *ss_len)
|
||||
{
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
|
||||
if (getpeername(fd, (struct sockaddr *) ss, ss_len)) {
|
||||
/* FIXME: Can we really not continue? */
|
||||
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
|
||||
@@ -149,6 +212,8 @@ void client_sockaddr(int fd,
|
||||
|
||||
/**
|
||||
* Look up a name from @p ss into @p name_buf.
|
||||
*
|
||||
* @param fd file descriptor for client socket.
|
||||
**/
|
||||
int lookup_name(int fd, const struct sockaddr_storage *ss,
|
||||
socklen_t ss_len,
|
||||
@@ -209,9 +274,23 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
|
||||
sin1 = (const struct sockaddr_in6 *) ss;
|
||||
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
|
||||
|
||||
return memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
|
||||
sizeof sin1->sin6_addr);
|
||||
|
||||
if (ai->ai_addrlen < sizeof(struct sockaddr_in6)) {
|
||||
rprintf(FERROR,
|
||||
"%s: too short sockaddr_in6; length=%d\n",
|
||||
fn, ai->ai_addrlen);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
|
||||
sizeof sin1->sin6_addr))
|
||||
return 1;
|
||||
|
||||
#ifdef HAVE_SOCKADDR_IN6_SCOPE_ID
|
||||
if (sin1->sin6_scope_id != sin2->sin6_scope_id)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* INET6 */
|
||||
else {
|
||||
@@ -226,11 +305,14 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
|
||||
* @p ss -- otherwise we may be being spoofed. If we suspect we are,
|
||||
* then we don't abort the connection but just emit a warning, and
|
||||
* change @p name_buf to be "UNKNOWN".
|
||||
*
|
||||
* We don't do anything with the service when checking the name,
|
||||
* because it doesn't seem that it could be spoofed in any way, and
|
||||
* getaddrinfo on random service names seems to cause problems on AIX.
|
||||
**/
|
||||
int check_name(int fd,
|
||||
const struct sockaddr_storage *ss,
|
||||
char *name_buf,
|
||||
const char *port_buf)
|
||||
char *name_buf)
|
||||
{
|
||||
struct addrinfo hints, *res, *res0;
|
||||
int error;
|
||||
@@ -240,7 +322,7 @@ int check_name(int fd,
|
||||
hints.ai_family = ss_family;
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
error = getaddrinfo(name_buf, port_buf, &hints, &res0);
|
||||
error = getaddrinfo(name_buf, NULL, &hints, &res0);
|
||||
if (error) {
|
||||
rprintf(FERROR,
|
||||
RSYNC_NAME ": forward name lookup for %s failed: %s\n",
|
||||
|
||||
266
clientserver.c
266
clientserver.c
@@ -1,24 +1,29 @@
|
||||
/* -*- c-file-style: "linux"; -*-
|
||||
|
||||
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2001-2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* the socket based protocol for setting up a connection with rsyncd */
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The socket based protocol for setting up a connection with
|
||||
* rsyncd.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
@@ -27,43 +32,32 @@ extern int read_only;
|
||||
extern int verbose;
|
||||
extern int rsync_port;
|
||||
char *auth_user;
|
||||
int sanitize_paths = 0;
|
||||
extern int sanitize_paths;
|
||||
|
||||
/*
|
||||
/**
|
||||
* Run a client connected to an rsyncd. The alternative to this
|
||||
* function for remote-shell connections is do_cmd.
|
||||
*/
|
||||
* function for remote-shell connections is do_cmd().
|
||||
*
|
||||
* After negotiating which module to use and reading the server's
|
||||
* motd, this hands over to client_run(). Telling the server the
|
||||
* module will cause it to chroot/setuid/etc.
|
||||
*
|
||||
* Instead of doing a transfer, the client may at this stage instead
|
||||
* get a listing of remote modules and exit.
|
||||
*
|
||||
* @return -1 for error in startup, or the result of client_run().
|
||||
* Either way, it eventually gets passed to exit_cleanup().
|
||||
**/
|
||||
int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
{
|
||||
int fd, i;
|
||||
char *sargs[MAX_ARGS];
|
||||
int sargc=0;
|
||||
char line[MAXPATHLEN];
|
||||
int fd, ret;
|
||||
char *p, *user=NULL;
|
||||
extern int remote_version;
|
||||
extern int am_sender;
|
||||
extern char *shell_cmd;
|
||||
extern int kludge_around_eof;
|
||||
extern char *bind_address;
|
||||
extern int default_af_hint;
|
||||
|
||||
if (argc == 0 && !am_sender) {
|
||||
extern int list_only;
|
||||
list_only = 1;
|
||||
}
|
||||
|
||||
/* This is just a friendliness enhancement: if the connection
|
||||
* is to an rsyncd then there is no point specifying the -e option.
|
||||
* Note that this is only set if the -e was explicitly specified,
|
||||
* not if the environment variable just happens to be set.
|
||||
* See http://lists.samba.org/pipermail/rsync/2000-September/002744.html
|
||||
*/
|
||||
if (shell_cmd) {
|
||||
rprintf(FERROR, "WARNING: --rsh or -e option ignored when "
|
||||
"connecting to rsync daemon\n");
|
||||
/* continue */
|
||||
}
|
||||
|
||||
/* this is redundant with code in start_inband_exchange(), but
|
||||
this short-circuits a problem before we open a socket, and
|
||||
the extra check won't hurt */
|
||||
if (*path == '/') {
|
||||
rprintf(FERROR,"ERROR: The remote path must start with a module name not a /\n");
|
||||
return -1;
|
||||
@@ -76,10 +70,10 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
*p = 0;
|
||||
}
|
||||
|
||||
if (!user) user = getenv("USER");
|
||||
if (!user) user = getenv("LOGNAME");
|
||||
|
||||
if (verbose >= 2) {
|
||||
/* FIXME: If we're going to use a socket program for
|
||||
* testing, then this message is wrong. We need to
|
||||
* say something like "(except really using %s)" */
|
||||
rprintf(FINFO, "opening tcp connection to %s port %d\n",
|
||||
host, rsync_port);
|
||||
}
|
||||
@@ -88,8 +82,41 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
if (fd == -1) {
|
||||
exit_cleanup(RERR_SOCKETIO);
|
||||
}
|
||||
|
||||
server_options(sargs,&sargc);
|
||||
|
||||
ret = start_inband_exchange(user, path, fd, fd, argc);
|
||||
|
||||
return ret < 0? ret : client_run(fd, fd, -1, argc, argv);
|
||||
}
|
||||
|
||||
int start_inband_exchange(char *user, char *path, int f_in, int f_out, int argc)
|
||||
{
|
||||
int i;
|
||||
char *sargs[MAX_ARGS];
|
||||
int sargc = 0;
|
||||
char line[MAXPATHLEN];
|
||||
char *p;
|
||||
extern int remote_version;
|
||||
extern int kludge_around_eof;
|
||||
extern int am_sender;
|
||||
extern int daemon_over_rsh;
|
||||
extern int list_only;
|
||||
|
||||
if (argc == 0 && !am_sender)
|
||||
list_only = 1;
|
||||
|
||||
if (*path == '/') {
|
||||
rprintf(FERROR, "ERROR: The remote path must start with a module name\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!user) user = getenv("USER");
|
||||
if (!user) user = getenv("LOGNAME");
|
||||
|
||||
/* set daemon_over_rsh to false since we need to build the
|
||||
true set of args passed through the rsh/ssh connection;
|
||||
this is a no-op for direct-socket-connection mode */
|
||||
daemon_over_rsh = 0;
|
||||
server_options(sargs, &sargc);
|
||||
|
||||
sargs[sargc++] = ".";
|
||||
|
||||
@@ -98,62 +125,77 @@ int start_socket_client(char *host, char *path, int argc, char *argv[])
|
||||
|
||||
sargs[sargc] = NULL;
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
io_printf(f_out, "@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
rprintf(FERROR, "rsync: did not see server greeting\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) {
|
||||
/* note that read_line strips of \n or \r */
|
||||
rprintf(FERROR, "rsync: server sent \"%s\" rather than greeting\n",
|
||||
line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
p = strchr(path,'/');
|
||||
if (p) *p = 0;
|
||||
io_printf(fd,"%s\n",path);
|
||||
io_printf(f_out, "%s\n", path);
|
||||
if (p) *p = '/';
|
||||
|
||||
/* Old servers may just drop the connection here,
|
||||
rather than sending a proper EXIT command. Yuck. */
|
||||
kludge_around_eof = remote_version < 25;
|
||||
kludge_around_eof = list_only && (remote_version < 25);
|
||||
|
||||
while (1) {
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
rprintf(FERROR, "rsync: didn't get server startup line\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strncmp(line,"@RSYNCD: AUTHREQD ",18) == 0) {
|
||||
auth_client(fd, user, line+18);
|
||||
auth_client(f_out, user, line+18);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(line,"@RSYNCD: OK") == 0) break;
|
||||
|
||||
if (strcmp(line,"@RSYNCD: EXIT") == 0) exit(0);
|
||||
if (strcmp(line,"@RSYNCD: EXIT") == 0) {
|
||||
/* This is sent by recent versions of the
|
||||
* server to terminate the listing of modules.
|
||||
* We don't want to go on and transfer
|
||||
* anything; just exit. */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (strncmp(line, "@ERROR", 6) == 0)
|
||||
if (strncmp(line, "@ERROR", 6) == 0) {
|
||||
rprintf(FERROR,"%s\n", line);
|
||||
else
|
||||
/* This is always fatal; the server will now
|
||||
* close the socket. */
|
||||
return RERR_STARTCLIENT;
|
||||
} else {
|
||||
rprintf(FINFO,"%s\n", line);
|
||||
}
|
||||
}
|
||||
kludge_around_eof = False;
|
||||
|
||||
for (i=0;i<sargc;i++) {
|
||||
io_printf(fd,"%s\n", sargs[i]);
|
||||
for (i = 0; i < sargc; i++) {
|
||||
io_printf(f_out, "%s\n", sargs[i]);
|
||||
}
|
||||
io_printf(fd,"\n");
|
||||
io_printf(f_out, "\n");
|
||||
|
||||
if (remote_version < 23) {
|
||||
if (remote_version == 22 || (remote_version > 17 && !am_sender))
|
||||
io_start_multiplex_in(fd);
|
||||
io_start_multiplex_in(f_in);
|
||||
}
|
||||
|
||||
return client_run(fd, fd, -1, argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int rsync_module(int fd, int i)
|
||||
static int rsync_module(int f_in, int f_out, int i)
|
||||
{
|
||||
int argc=0;
|
||||
char *argv[MAX_ARGS];
|
||||
@@ -162,46 +204,53 @@ static int rsync_module(int fd, int i)
|
||||
uid_t uid = (uid_t)-2; /* canonically "nobody" */
|
||||
gid_t gid = (gid_t)-2;
|
||||
char *p;
|
||||
char *addr = client_addr(fd);
|
||||
char *host = client_name(fd);
|
||||
char *addr = client_addr(f_in);
|
||||
char *host = client_name(f_in);
|
||||
char *name = lp_name(i);
|
||||
int use_chroot = lp_use_chroot(i);
|
||||
int start_glob=0;
|
||||
int ret;
|
||||
char *request=NULL;
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int remote_version;
|
||||
extern int am_root;
|
||||
|
||||
if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
|
||||
rprintf(FERROR,"rsync denied on module %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
io_printf(fd,"@ERROR: access denied to %s from %s (%s)\n",
|
||||
io_printf(f_out, "@ERROR: access denied to %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (am_daemon && am_server) {
|
||||
rprintf(FINFO, "rsync allowed access on module %s from %s (%s)\n",
|
||||
name, host, addr);
|
||||
}
|
||||
|
||||
if (!claim_connection(lp_lock_file(i), lp_max_connections(i))) {
|
||||
if (errno) {
|
||||
rprintf(FERROR,"failed to open lock file %s : %s\n",
|
||||
lp_lock_file(i), strerror(errno));
|
||||
io_printf(fd,"@ERROR: failed to open lock file %s : %s\n",
|
||||
io_printf(f_out, "@ERROR: failed to open lock file %s : %s\n",
|
||||
lp_lock_file(i), strerror(errno));
|
||||
} else {
|
||||
rprintf(FERROR,"max connections (%d) reached\n",
|
||||
lp_max_connections(i));
|
||||
io_printf(fd,"@ERROR: max connections (%d) reached - try again later\n", lp_max_connections(i));
|
||||
io_printf(f_out, "@ERROR: max connections (%d) reached - try again later\n", lp_max_connections(i));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
auth_user = auth_server(fd, i, addr, "@RSYNCD: AUTHREQD ");
|
||||
auth_user = auth_server(f_in, f_out, i, addr, "@RSYNCD: AUTHREQD ");
|
||||
|
||||
if (!auth_user) {
|
||||
rprintf(FERROR,"auth failed on module %s from %s (%s)\n",
|
||||
name, client_name(fd), client_addr(fd));
|
||||
io_printf(fd,"@ERROR: auth failed on module %s\n",name);
|
||||
name, host, addr);
|
||||
io_printf(f_out, "@ERROR: auth failed on module %s\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -212,9 +261,9 @@ static int rsync_module(int fd, int i)
|
||||
if (am_root) {
|
||||
p = lp_uid(i);
|
||||
if (!name_to_uid(p, &uid)) {
|
||||
if (!isdigit(*p)) {
|
||||
if (!isdigit(* (unsigned char *) p)) {
|
||||
rprintf(FERROR,"Invalid uid %s\n", p);
|
||||
io_printf(fd,"@ERROR: invalid uid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid uid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
uid = atoi(p);
|
||||
@@ -222,9 +271,9 @@ static int rsync_module(int fd, int i)
|
||||
|
||||
p = lp_gid(i);
|
||||
if (!name_to_gid(p, &gid)) {
|
||||
if (!isdigit(*p)) {
|
||||
if (!isdigit(* (unsigned char *) p)) {
|
||||
rprintf(FERROR,"Invalid gid %s\n", p);
|
||||
io_printf(fd,"@ERROR: invalid gid %s\n", p);
|
||||
io_printf(f_out, "@ERROR: invalid gid %s\n", p);
|
||||
return -1;
|
||||
}
|
||||
gid = atoi(p);
|
||||
@@ -267,20 +316,20 @@ static int rsync_module(int fd, int i)
|
||||
*/
|
||||
if (chroot(lp_path(i))) {
|
||||
rsyserr(FERROR, errno, "chroot %s failed", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chroot failed\n");
|
||||
io_printf(f_out, "@ERROR: chroot failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!push_dir("/", 0)) {
|
||||
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chdir failed\n");
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!push_dir(lp_path(i), 0)) {
|
||||
rsyserr(FERROR, errno, "chdir %s failed\n", lp_path(i));
|
||||
io_printf(fd,"@ERROR: chdir failed\n");
|
||||
io_printf(f_out, "@ERROR: chdir failed\n");
|
||||
return -1;
|
||||
}
|
||||
sanitize_paths = 1;
|
||||
@@ -292,7 +341,7 @@ static int rsync_module(int fd, int i)
|
||||
* might have inheristed. */
|
||||
if (setgroups(0, NULL)) {
|
||||
rsyserr(FERROR, errno, "setgroups failed");
|
||||
io_printf(fd, "@ERROR: setgroups failed\n");
|
||||
io_printf(f_out, "@ERROR: setgroups failed\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
@@ -309,25 +358,25 @@ static int rsync_module(int fd, int i)
|
||||
|
||||
if (setgid(gid)) {
|
||||
rsyserr(FERROR, errno, "setgid %d failed", (int) gid);
|
||||
io_printf(fd,"@ERROR: setgid failed\n");
|
||||
io_printf(f_out, "@ERROR: setgid failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setuid(uid)) {
|
||||
rsyserr(FERROR, errno, "setuid %d failed", (int) uid);
|
||||
io_printf(fd,"@ERROR: setuid failed\n");
|
||||
io_printf(f_out, "@ERROR: setuid failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
am_root = (getuid() == 0);
|
||||
}
|
||||
|
||||
io_printf(fd,"@RSYNCD: OK\n");
|
||||
io_printf(f_out, "@RSYNCD: OK\n");
|
||||
|
||||
argv[argc++] = "rsyncd";
|
||||
|
||||
while (1) {
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -395,7 +444,7 @@ static int rsync_module(int fd, int i)
|
||||
|
||||
if (remote_version < 23) {
|
||||
if (remote_version == 22 || (remote_version > 17 && am_sender))
|
||||
io_start_multiplex_out(fd);
|
||||
io_start_multiplex_out(f_out);
|
||||
}
|
||||
|
||||
/* For later protocol versions, we don't start multiplexing
|
||||
@@ -416,7 +465,7 @@ static int rsync_module(int fd, int i)
|
||||
io_timeout = lp_timeout(i);
|
||||
}
|
||||
|
||||
start_server(fd, fd, argc, argp);
|
||||
start_server(f_in, f_out, argc, argp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -437,26 +486,31 @@ static void send_listing(int fd)
|
||||
io_printf(fd,"@RSYNCD: EXIT\n");
|
||||
}
|
||||
|
||||
/* this is called when a socket connection is established to a client
|
||||
/* this is called when a connection is established to a client
|
||||
and we want to start talking. The setup of the system is done from
|
||||
here */
|
||||
static int start_daemon(int fd)
|
||||
int start_daemon(int f_in, int f_out)
|
||||
{
|
||||
char line[200];
|
||||
char *motd;
|
||||
int i = -1;
|
||||
extern char *config_file;
|
||||
extern int remote_version;
|
||||
extern int am_server;
|
||||
|
||||
if (!lp_load(config_file, 0)) {
|
||||
exit_cleanup(RERR_SYNTAX);
|
||||
}
|
||||
|
||||
set_socket_options(fd,"SO_KEEPALIVE");
|
||||
set_socket_options(fd,lp_socket_options());
|
||||
set_nonblocking(fd);
|
||||
log_init();
|
||||
|
||||
io_printf(fd,"@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
if (!am_server) {
|
||||
set_socket_options(f_in, "SO_KEEPALIVE");
|
||||
set_socket_options(f_in, lp_socket_options());
|
||||
set_nonblocking(f_in);
|
||||
}
|
||||
|
||||
io_printf(f_out, "@RSYNCD: %d\n", PROTOCOL_VERSION);
|
||||
|
||||
motd = lp_motd_file();
|
||||
if (motd && *motd) {
|
||||
@@ -465,47 +519,47 @@ static int start_daemon(int fd)
|
||||
int len = fread(line, 1, sizeof(line)-1, f);
|
||||
if (len > 0) {
|
||||
line[len] = 0;
|
||||
io_printf(fd,"%s", line);
|
||||
io_printf(f_out, "%s", line);
|
||||
}
|
||||
}
|
||||
if (f) fclose(f);
|
||||
io_printf(fd,"\n");
|
||||
io_printf(f_out, "\n");
|
||||
}
|
||||
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sscanf(line,"@RSYNCD: %d", &remote_version) != 1) {
|
||||
io_printf(fd,"@ERROR: protocol startup error\n");
|
||||
io_printf(f_out, "@ERROR: protocol startup error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (i == -1) {
|
||||
line[0] = 0;
|
||||
if (!read_line(fd, line, sizeof(line)-1)) {
|
||||
if (!read_line(f_in, line, sizeof(line)-1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!*line || strcmp(line,"#list")==0) {
|
||||
send_listing(fd);
|
||||
send_listing(f_out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*line == '#') {
|
||||
/* it's some sort of command that I don't understand */
|
||||
io_printf(fd,"@ERROR: Unknown command '%s'\n", line);
|
||||
io_printf(f_out, "@ERROR: Unknown command '%s'\n", line);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = lp_number(line);
|
||||
if (i == -1) {
|
||||
io_printf(fd,"@ERROR: Unknown module '%s'\n", line);
|
||||
io_printf(f_out, "@ERROR: Unknown module '%s'\n", line);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return rsync_module(fd, i);
|
||||
return rsync_module(f_in, f_out, i);
|
||||
}
|
||||
|
||||
|
||||
@@ -527,7 +581,7 @@ int daemon_main(void)
|
||||
open("/dev/null", O_RDWR);
|
||||
}
|
||||
|
||||
return start_daemon(STDIN_FILENO);
|
||||
return start_daemon(STDIN_FILENO, STDIN_FILENO);
|
||||
}
|
||||
|
||||
if (!no_detach)
|
||||
|
||||
6
compat.c
6
compat.c
@@ -17,7 +17,11 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* compatability routines for older rsync protocol versions */
|
||||
/**
|
||||
* @file compat.c
|
||||
*
|
||||
* Compatibility routines for older rsync protocol versions.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
458
config.guess
vendored
458
config.guess
vendored
@@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2001-07-19'
|
||||
timestamp='2003-01-10'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -24,8 +24,9 @@ timestamp='2001-07-19'
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Written by Per Bothner <bothner@cygnus.com>.
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
# Originally written by Per Bothner <per@bothner.com>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
@@ -87,30 +88,41 @@ if test $# != 0; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap 'exit 1' 1 2 15
|
||||
|
||||
dummy=dummy-$$
|
||||
trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
|
||||
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
|
||||
# compiler to aid in system detection is discouraged as it requires
|
||||
# temporary files to be created and, as you can see below, it is a
|
||||
# headache to deal with in a portable fashion.
|
||||
|
||||
# CC_FOR_BUILD -- compiler used by this script.
|
||||
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
|
||||
# use `HOST_CC' if defined, but it is deprecated.
|
||||
|
||||
set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
|
||||
,,) echo "int dummy(){}" > $dummy.c ;
|
||||
for c in cc gcc c89 ; do
|
||||
($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
|
||||
if test $? = 0 ; then
|
||||
# Portable tmp directory creation inspired by the Autoconf team.
|
||||
|
||||
set_cc_for_build='
|
||||
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
|
||||
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
|
||||
: ${TMPDIR=/tmp} ;
|
||||
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
|
||||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
|
||||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
|
||||
dummy=$tmp/dummy ;
|
||||
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
|
||||
case $CC_FOR_BUILD,$HOST_CC,$CC in
|
||||
,,) echo "int x;" > $dummy.c ;
|
||||
for c in cc gcc c89 c99 ; do
|
||||
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
|
||||
CC_FOR_BUILD="$c"; break ;
|
||||
fi ;
|
||||
done ;
|
||||
rm -f $dummy.c $dummy.o $dummy.rel ;
|
||||
if test x"$CC_FOR_BUILD" = x ; then
|
||||
CC_FOR_BUILD=no_compiler_found ;
|
||||
fi
|
||||
;;
|
||||
,,*) CC_FOR_BUILD=$CC ;;
|
||||
,*,*) CC_FOR_BUILD=$HOST_CC ;;
|
||||
esac'
|
||||
esac ;'
|
||||
|
||||
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
|
||||
# (ghazi@noc.rutgers.edu 1994-08-24)
|
||||
@@ -127,29 +139,30 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# Netbsd (nbsd) targets should (where applicable) match one or
|
||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
# compatibility and a consistent mechanism for selecting the
|
||||
# object file format.
|
||||
# Determine the machine/vendor (is the vendor relevant).
|
||||
case "${UNAME_MACHINE}" in
|
||||
amiga) machine=m68k-unknown ;;
|
||||
arm32) machine=arm-unknown ;;
|
||||
atari*) machine=m68k-atari ;;
|
||||
sun3*) machine=m68k-sun ;;
|
||||
mac68k) machine=m68k-apple ;;
|
||||
macppc) machine=powerpc-apple ;;
|
||||
hp3[0-9][05]) machine=m68k-hp ;;
|
||||
ibmrt|romp-ibm) machine=romp-ibm ;;
|
||||
*) machine=${UNAME_MACHINE}-unknown ;;
|
||||
#
|
||||
# Note: NetBSD doesn't particularly care about the vendor
|
||||
# portion of the name. We always set it to "unknown".
|
||||
sysctl="sysctl -n hw.machine_arch"
|
||||
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
|
||||
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
armeb) machine=armeb-unknown ;;
|
||||
arm*) machine=arm-unknown ;;
|
||||
sh3el) machine=shl-unknown ;;
|
||||
sh3eb) machine=sh-unknown ;;
|
||||
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format, if it has switched
|
||||
# to ELF recently, or will in the future.
|
||||
case "${UNAME_MACHINE}" in
|
||||
i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
|
||||
case "${UNAME_MACHINE_ARCH}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep __ELF__ >/dev/null
|
||||
@@ -166,12 +179,65 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
# Debian GNU/NetBSD machines have a different userland, and
|
||||
# thus, need a distinct triplet. However, they do not need
|
||||
# kernel version information, so it can be replaced with a
|
||||
# suitable tag, in the style of linux-gnu.
|
||||
case "${UNAME_VERSION}" in
|
||||
Debian*)
|
||||
release='-gnu'
|
||||
;;
|
||||
*)
|
||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
;;
|
||||
esac
|
||||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||
# contains redundant information, the shorter form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
macppc:OpenBSD:*:*)
|
||||
echo powerpc-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvmeppc:OpenBSD:*:*)
|
||||
echo powerpc-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mipseb-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:MicroBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-microbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
@@ -180,6 +246,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
eval $set_cc_for_build
|
||||
cat <<EOF >$dummy.s
|
||||
.data
|
||||
\$Lformat:
|
||||
@@ -205,10 +272,9 @@ main:
|
||||
jsr \$26,exit
|
||||
.end main
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
|
||||
$CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
case `./$dummy` in
|
||||
case `$dummy` in
|
||||
0-0)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
@@ -227,9 +293,14 @@ EOF
|
||||
2-307)
|
||||
UNAME_MACHINE="alphaev67"
|
||||
;;
|
||||
2-1307)
|
||||
UNAME_MACHINE="alphaev68"
|
||||
;;
|
||||
3-1307)
|
||||
UNAME_MACHINE="alphaev7"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -f $dummy.s $dummy
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
exit 0 ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
@@ -244,29 +315,11 @@ EOF
|
||||
Amiga*:UNIX_System_V:4.0:*)
|
||||
echo m68k-unknown-sysv4
|
||||
exit 0;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:[Aa]miga[Oo][Ss]:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-amigaos
|
||||
exit 0 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
arc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hkmips:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
pmax:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sgi:OpenBSD:*:*)
|
||||
echo mips-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
*:[Mm]orph[Oo][Ss]:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-morphos
|
||||
exit 0 ;;
|
||||
*:OS/390:*:*)
|
||||
echo i370-ibm-openedition
|
||||
@@ -288,6 +341,10 @@ EOF
|
||||
NILE*:*:*:dcosx)
|
||||
echo pyramid-pyramid-svr4
|
||||
exit 0 ;;
|
||||
DRS?6000:UNIX_SV:4.2*:7*)
|
||||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7 && exit 0 ;;
|
||||
esac ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
@@ -316,7 +373,7 @@ EOF
|
||||
echo m68k-sun-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun*:*:4.2BSD:*)
|
||||
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
|
||||
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
|
||||
case "`/bin/arch`" in
|
||||
sun3)
|
||||
@@ -330,9 +387,6 @@ EOF
|
||||
aushp:SunOS:*:*)
|
||||
echo sparc-auspex-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
# The situation for MiNT is a little confusing. The machine name
|
||||
# can be virtually everything (everything which is not
|
||||
# "atarist" or "atariste" at least should have a processor
|
||||
@@ -359,18 +413,6 @@ EOF
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mvme88k:OpenBSD:*:*)
|
||||
echo m88k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
powerpc:machten:*:*)
|
||||
echo powerpc-apple-machten${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -387,6 +429,7 @@ EOF
|
||||
echo clipper-intergraph-clix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
@@ -408,16 +451,20 @@ EOF
|
||||
exit (-1);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy \
|
||||
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c \
|
||||
&& $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& exit 0
|
||||
echo mips-mips-riscos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Motorola:PowerMAX_OS:*:*)
|
||||
echo powerpc-motorola-powermax
|
||||
exit 0 ;;
|
||||
Motorola:*:4.3:PL8-*)
|
||||
echo powerpc-harris-powermax
|
||||
exit 0 ;;
|
||||
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
|
||||
echo powerpc-harris-powermax
|
||||
exit 0 ;;
|
||||
Night_Hawk:Power_UNIX:*:*)
|
||||
echo powerpc-harris-powerunix
|
||||
exit 0 ;;
|
||||
@@ -478,6 +525,7 @@ EOF
|
||||
exit 0 ;;
|
||||
*:AIX:2:3)
|
||||
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
@@ -489,9 +537,7 @@ EOF
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
|
||||
echo rs6000-ibm-aix3.2.5
|
||||
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
echo rs6000-ibm-aix3.2.4
|
||||
@@ -500,7 +546,7 @@ EOF
|
||||
fi
|
||||
exit 0 ;;
|
||||
*:AIX:*:[45])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
else
|
||||
@@ -540,10 +586,8 @@ EOF
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/[678][0-9][0-9])
|
||||
case "${HPUX_REV}" in
|
||||
11.[0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
@@ -552,12 +596,13 @@ EOF
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
fi ;;
|
||||
esac
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
fi
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
@@ -590,12 +635,21 @@ EOF
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
|
||||
if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
|
||||
rm -f $dummy.c $dummy
|
||||
fi ;;
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
fi ;;
|
||||
esac
|
||||
if [ ${HP_ARCH} = "hppa2.0w" ]
|
||||
then
|
||||
# avoid double evaluation of $set_cc_for_build
|
||||
test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
else
|
||||
HP_ARCH="hppa64"
|
||||
fi
|
||||
fi
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
ia64:HP-UX:*:*)
|
||||
@@ -603,6 +657,7 @@ EOF
|
||||
echo ia64-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
3050*:HI-UX:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <unistd.h>
|
||||
int
|
||||
@@ -628,9 +683,7 @@ EOF
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
|
||||
echo unknown-hitachi-hiuxwe2
|
||||
exit 0 ;;
|
||||
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
|
||||
@@ -658,9 +711,6 @@ EOF
|
||||
parisc*:Lites*:*:*)
|
||||
echo hppa1.1-hp-lites
|
||||
exit 0 ;;
|
||||
hppa*:OpenBSD:*:*)
|
||||
echo hppa-unknown-openbsd
|
||||
exit 0 ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
@@ -679,9 +729,6 @@ EOF
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit 0 ;;
|
||||
CRAY*X-MP:*:*:*)
|
||||
echo xmp-cray-unicos
|
||||
exit 0 ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
@@ -694,27 +741,21 @@ EOF
|
||||
CRAY*TS:*:*:*)
|
||||
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*T3D:*:*:*)
|
||||
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*T3E:*:*:*)
|
||||
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*SV1:*:*:*)
|
||||
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
*:UNICOS/mp:*:*)
|
||||
echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -725,10 +766,18 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:FreeBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
# Determine whether the default compiler uses glibc.
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
|
||||
exit 0 ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
@@ -739,11 +788,17 @@ EOF
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit 0 ;;
|
||||
x86:Interix*:3*)
|
||||
echo i586-pc-interix3
|
||||
exit 0 ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit 0 ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
# UNAME_MACHINE based on the output of uname instead of i386?
|
||||
echo i386-pc-interix
|
||||
echo i586-pc-interix
|
||||
exit 0 ;;
|
||||
i*:UWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-uwin
|
||||
@@ -764,16 +819,48 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit 0 ;;
|
||||
mips:Linux:*:*)
|
||||
case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
|
||||
big) echo mips-unknown-linux-gnu && exit 0 ;;
|
||||
little) echo mipsel-unknown-linux-gnu && exit 0 ;;
|
||||
esac
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips
|
||||
#undef mipsel
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mipsel
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
|
||||
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips64
|
||||
#undef mips64el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mips64el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips64
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
|
||||
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
|
||||
;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
@@ -789,7 +876,7 @@ EOF
|
||||
PCA57) UNAME_MACHINE=alphapca56 ;;
|
||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
@@ -822,7 +909,8 @@ EOF
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
ld_supported_targets=`cd /; ld --help 2>&1 \
|
||||
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||
| sed -ne '/supported targets:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported targets: *//
|
||||
@@ -834,7 +922,7 @@ EOF
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit 0 ;;
|
||||
exit 0 ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit 0 ;;
|
||||
@@ -845,33 +933,29 @@ EOF
|
||||
exit 0 ;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
cat >$dummy.c <<EOF
|
||||
#include <features.h>
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
int main (int argc, char *argv[]) {
|
||||
#else
|
||||
int main (argc, argv) int argc; char *argv[]; {
|
||||
#endif
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
printf ("%s-pc-linux-gnu\n", argv[1]);
|
||||
# else
|
||||
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
# else
|
||||
printf ("%s-pc-linux-gnulibc1\n", argv[1]);
|
||||
# endif
|
||||
#else
|
||||
printf ("%s-pc-linux-gnuaout\n", argv[1]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
#else
|
||||
#ifdef __INTEL_COMPILER
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=gnuaout
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
|
||||
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
|
||||
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
|
||||
;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
@@ -888,6 +972,23 @@ EOF
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit 0 ;;
|
||||
i*86:OS/2:*:*)
|
||||
# If we were able to find `uname', then EMX Unix compatibility
|
||||
# is probably installed.
|
||||
echo ${UNAME_MACHINE}-pc-os2-emx
|
||||
exit 0 ;;
|
||||
i*86:XTS-300:*:STOP)
|
||||
echo ${UNAME_MACHINE}-unknown-stop
|
||||
exit 0 ;;
|
||||
i*86:atheos:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-atheos
|
||||
exit 0 ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i*86:*DOS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
|
||||
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
|
||||
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
|
||||
@@ -909,22 +1010,19 @@ EOF
|
||||
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
|
||||
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
|
||||
elif /bin/uname -X 2>/dev/null >/dev/null ; then
|
||||
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
|
||||
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
|
||||
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
|
||||
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
|
||||
&& UNAME_MACHINE=i586
|
||||
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
|
||||
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
|
||||
&& UNAME_MACHINE=i686
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
|
||||
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
|
||||
&& UNAME_MACHINE=i686
|
||||
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv32
|
||||
fi
|
||||
exit 0 ;;
|
||||
i*86:*DOS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
@@ -948,9 +1046,15 @@ EOF
|
||||
# "miniframe"
|
||||
echo m68010-convergent-sysv
|
||||
exit 0 ;;
|
||||
mc68k:UNIX:SYSTEM5:3.51m)
|
||||
echo m68k-convergent-sysv
|
||||
exit 0 ;;
|
||||
M680?0:D-NIX:5.3:*)
|
||||
echo m68k-diab-dnix
|
||||
exit 0 ;;
|
||||
M68*:*:R3V[567]*:*)
|
||||
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
|
||||
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
|
||||
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0)
|
||||
OS_REL=''
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
@@ -967,9 +1071,6 @@ EOF
|
||||
mc68030:UNIX_System_V:4.*:*)
|
||||
echo m68k-atari-sysv4
|
||||
exit 0 ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
TSUNAMI:LynxOS:2.*:*)
|
||||
echo sparc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -996,8 +1097,8 @@ EOF
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit 0 ;;
|
||||
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit 0 ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
@@ -1009,6 +1110,10 @@ EOF
|
||||
# From seanf@swdc.stratus.com.
|
||||
echo i860-stratus-sysv4
|
||||
exit 0 ;;
|
||||
*:VOS:*:*)
|
||||
# From Paul.Green@stratus.com.
|
||||
echo hppa1.1-stratus-vos
|
||||
exit 0 ;;
|
||||
mc68*:A/UX:*:*)
|
||||
echo m68k-apple-aux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -1037,6 +1142,9 @@ EOF
|
||||
SX-5:SUPER-UX:*:*)
|
||||
echo sx5-nec-superux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
SX-6:SUPER-UX:*:*)
|
||||
echo sx6-nec-superux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -1044,18 +1152,24 @@ EOF
|
||||
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:Darwin:*:*)
|
||||
echo `uname -p`-apple-darwin${UNAME_RELEASE}
|
||||
case `uname -p` in
|
||||
*86) UNAME_PROCESSOR=i686 ;;
|
||||
powerpc) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
if test "${UNAME_MACHINE}" = "x86pc"; then
|
||||
UNAME_PROCESSOR=`uname -p`
|
||||
if test "$UNAME_PROCESSOR" = "x86"; then
|
||||
UNAME_PROCESSOR=i386
|
||||
UNAME_MACHINE=pc
|
||||
fi
|
||||
echo `uname -p`-${UNAME_MACHINE}-nto-qnx
|
||||
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit 0 ;;
|
||||
NSR-[KW]:NONSTOP_KERNEL:*:*)
|
||||
NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
|
||||
echo nsr-tandem-nsk${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:NonStop-UX:*:*)
|
||||
@@ -1078,11 +1192,6 @@ EOF
|
||||
fi
|
||||
echo ${UNAME_MACHINE}-unknown-plan9
|
||||
exit 0 ;;
|
||||
i*86:OS/2:*:*)
|
||||
# If we were able to find `uname', then EMX Unix compatibility
|
||||
# is probably installed.
|
||||
echo ${UNAME_MACHINE}-pc-os2-emx
|
||||
exit 0 ;;
|
||||
*:TOPS-10:*:*)
|
||||
echo pdp10-unknown-tops10
|
||||
exit 0 ;;
|
||||
@@ -1106,6 +1215,7 @@ esac
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/types.h>
|
||||
@@ -1220,9 +1330,7 @@ main ()
|
||||
}
|
||||
EOF
|
||||
|
||||
eval $set_cc_for_build
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
|
||||
|
||||
# Apollos put the system type in the environment.
|
||||
|
||||
|
||||
325
config.sub
vendored
325
config.sub
vendored
@@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2001-06-08'
|
||||
timestamp='2003-01-22'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@@ -29,7 +29,8 @@ timestamp='2001-06-08'
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Please send patches to <config-patches@gnu.org>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
@@ -117,7 +118,7 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
@@ -223,26 +224,48 @@ esac
|
||||
case $basic_machine in
|
||||
# Recognize the basic CPU types without company name.
|
||||
# Some are omitted here because they have special meanings below.
|
||||
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \
|
||||
| arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \
|
||||
| pyramid | mn10200 | mn10300 | tron | a29k \
|
||||
| 580 | i960 | h8300 \
|
||||
| x86 | ppcbe | mipsbe | mipsle | shbe | shle \
|
||||
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
|
||||
| hppa64 \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
|
||||
| alphaev6[78] \
|
||||
| we32k | ns16k | clipper | i370 | sh | sh[34] \
|
||||
| powerpc | powerpcle \
|
||||
| 1750a | dsp16xx | pdp10 | pdp11 \
|
||||
| mips16 | mips64 | mipsel | mips64el \
|
||||
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
|
||||
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr5000 | mips64vr5000el | mcore | s390 | s390x \
|
||||
| sparc | sparclet | sparclite | sparc64 | sparcv9 | sparcv9b \
|
||||
| v850 | c4x \
|
||||
| thumb | d10v | d30v | fr30 | avr | openrisc | tic80 \
|
||||
| pj | pjl | h8500 | z8k)
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| msp430 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xscale | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
@@ -265,31 +288,58 @@ case $basic_machine in
|
||||
exit 1
|
||||
;;
|
||||
# Recognize the basic CPU types with company name.
|
||||
# FIXME: clean up the formatting here.
|
||||
vax-* | tahoe-* | i*86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
|
||||
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \
|
||||
| arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \
|
||||
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
|
||||
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
|
||||
| xmp-* | ymp-* \
|
||||
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \
|
||||
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
|
||||
| hppa2.0n-* | hppa64-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
|
||||
| alphaev6[78]-* \
|
||||
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
|
||||
| clipper-* | orion-* \
|
||||
| sparclite-* | pdp10-* | pdp11-* | sh-* | sh[34]-* | sh[34]eb-* \
|
||||
| powerpc-* | powerpcle-* | sparc64-* | sparcv9-* | sparcv9b-* | sparc86x-* \
|
||||
| mips16-* | mips64-* | mipsel-* \
|
||||
| mips64el-* | mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
|
||||
| mipstx39-* | mipstx39el-* | mcore-* \
|
||||
| f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \
|
||||
| [cjt]90-* \
|
||||
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
|
||||
| thumb-* | v850-* | d30v-* | tic30-* | tic80-* | c30-* | fr30-* \
|
||||
| bs2000-* | tic54x-* | c54x-* | x86_64-* | pj-* | pjl-*)
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* \
|
||||
| m32r-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| msp430-* \
|
||||
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
| xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
@@ -352,6 +402,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -372,16 +426,8 @@ case $basic_machine in
|
||||
basic_machine=c38-convex
|
||||
os=-bsd
|
||||
;;
|
||||
cray | ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cray2)
|
||||
basic_machine=cray2-cray
|
||||
os=-unicos
|
||||
;;
|
||||
[cjt]90)
|
||||
basic_machine=${basic_machine}-cray
|
||||
cray | j90)
|
||||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -396,6 +442,14 @@ case $basic_machine in
|
||||
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
|
||||
basic_machine=mips-dec
|
||||
;;
|
||||
decsystem10* | dec10*)
|
||||
basic_machine=pdp10-dec
|
||||
os=-tops10
|
||||
;;
|
||||
decsystem20* | dec20*)
|
||||
basic_machine=pdp10-dec
|
||||
os=-tops20
|
||||
;;
|
||||
delta | 3300 | motorola-3300 | motorola-delta \
|
||||
| 3300-motorola | delta-motorola)
|
||||
basic_machine=m68k-motorola
|
||||
@@ -576,14 +630,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-atari
|
||||
os=-mint
|
||||
;;
|
||||
mipsel*-linux*)
|
||||
basic_machine=mipsel-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips*-linux*)
|
||||
basic_machine=mips-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips3*-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
||||
;;
|
||||
@@ -598,6 +644,10 @@ case $basic_machine in
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
;;
|
||||
morphos)
|
||||
basic_machine=powerpc-unknown
|
||||
os=-morphos
|
||||
;;
|
||||
msdos)
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
@@ -670,6 +720,10 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
nv1)
|
||||
basic_machine=nv1-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -677,6 +731,10 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
or32 | or32-*)
|
||||
basic_machine=or32-unknown
|
||||
os=-coff
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
os=-ose
|
||||
@@ -699,19 +757,19 @@ case $basic_machine in
|
||||
pbb)
|
||||
basic_machine=m68k-tti
|
||||
;;
|
||||
pc532 | pc532-*)
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexgen)
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6 | 6x86 | athlon)
|
||||
pentiumpro | p6 | 6x86 | athlon | athlon_*)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentiumii | pentium2)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
|
||||
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumpro-* | p6-* | 6x86-* | athlon-*)
|
||||
@@ -726,15 +784,25 @@ case $basic_machine in
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64) basic_machine=powerpc64-unknown
|
||||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ps2)
|
||||
basic_machine=i386-ibm
|
||||
;;
|
||||
@@ -752,10 +820,22 @@ case $basic_machine in
|
||||
rtpc | rtpc-*)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
s390 | s390-*)
|
||||
basic_machine=s390-ibm
|
||||
;;
|
||||
s390x | s390x-*)
|
||||
basic_machine=s390x-ibm
|
||||
;;
|
||||
sa29200)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
sb1)
|
||||
basic_machine=mipsisa64sb1-unknown
|
||||
;;
|
||||
sb1el)
|
||||
basic_machine=mipsisa64sb1el-unknown
|
||||
;;
|
||||
sequent)
|
||||
basic_machine=i386-sequent
|
||||
;;
|
||||
@@ -763,7 +843,7 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sparclite-wrs)
|
||||
sparclite-wrs | simso-wrs)
|
||||
basic_machine=sparclite-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
@@ -830,9 +910,17 @@ case $basic_machine in
|
||||
os=-dynix
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=t3e-cray
|
||||
basic_machine=alphaev5-cray
|
||||
os=-unicos
|
||||
;;
|
||||
t90)
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic4x | c4x*)
|
||||
basic_machine=tic4x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
@@ -843,6 +931,10 @@ case $basic_machine in
|
||||
tx39el)
|
||||
basic_machine=mipstx39el-unknown
|
||||
;;
|
||||
toad1)
|
||||
basic_machine=pdp10-xkl
|
||||
os=-tops20
|
||||
;;
|
||||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
@@ -867,8 +959,8 @@ case $basic_machine in
|
||||
os=-vms
|
||||
;;
|
||||
vpp*|vx|vx-*)
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
vxworks960)
|
||||
basic_machine=i960-wrs
|
||||
os=-vxworks
|
||||
@@ -889,17 +981,13 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
windows32)
|
||||
basic_machine=i386-pc
|
||||
os=-windows32-msvcrt
|
||||
;;
|
||||
xmp)
|
||||
basic_machine=xmp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
xps | xps100)
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
z8k-*-coff)
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
@@ -920,13 +1008,6 @@ case $basic_machine in
|
||||
op60c)
|
||||
basic_machine=hppa1.1-oki
|
||||
;;
|
||||
mips)
|
||||
if [ x$os = x-linux-gnu ]; then
|
||||
basic_machine=mips-unknown
|
||||
else
|
||||
basic_machine=mips-mips
|
||||
fi
|
||||
;;
|
||||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
@@ -946,13 +1027,16 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh3 | sh4)
|
||||
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
cydra)
|
||||
basic_machine=cydra-cydrome
|
||||
;;
|
||||
orion)
|
||||
@@ -967,10 +1051,6 @@ case $basic_machine in
|
||||
pmac | pmac-mpw)
|
||||
basic_machine=powerpc-apple
|
||||
;;
|
||||
c4x*)
|
||||
basic_machine=c4x-none
|
||||
os=-coff
|
||||
;;
|
||||
*-unknown)
|
||||
# Make sure to match an already-canonicalized machine name.
|
||||
;;
|
||||
@@ -1033,9 +1113,12 @@ case $os in
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -microbsd*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1047,8 +1130,10 @@ case $os in
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-nto-qnx*)
|
||||
;;
|
||||
-nto*)
|
||||
os=-nto-qnx
|
||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
@@ -1087,14 +1172,20 @@ case $os in
|
||||
-acis*)
|
||||
os=-aos
|
||||
;;
|
||||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
-ctix* | -uts*)
|
||||
os=-sysv
|
||||
;;
|
||||
-nova*)
|
||||
os=-rtmk-nova
|
||||
;;
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk*)
|
||||
os=-nsk
|
||||
@@ -1133,8 +1224,11 @@ case $os in
|
||||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
;;
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
@@ -1167,10 +1261,11 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
;;
|
||||
pdp11-*)
|
||||
pdp11-*)
|
||||
os=-none
|
||||
;;
|
||||
*-dec | vax-*)
|
||||
@@ -1197,6 +1292,9 @@ case $basic_machine in
|
||||
mips*-*)
|
||||
os=-elf
|
||||
;;
|
||||
or32-*)
|
||||
os=-coff
|
||||
;;
|
||||
*-tti) # must be before sparc entry or we get the wrong os.
|
||||
os=-sysv3
|
||||
;;
|
||||
@@ -1260,19 +1358,19 @@ case $basic_machine in
|
||||
*-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
*-gould)
|
||||
*-gould)
|
||||
os=-sysv
|
||||
;;
|
||||
*-highlevel)
|
||||
*-highlevel)
|
||||
os=-bsd
|
||||
;;
|
||||
*-encore)
|
||||
os=-bsd
|
||||
;;
|
||||
*-sgi)
|
||||
*-sgi)
|
||||
os=-irix
|
||||
;;
|
||||
*-siemens)
|
||||
*-siemens)
|
||||
os=-sysv4
|
||||
;;
|
||||
*-masscomp)
|
||||
@@ -1344,7 +1442,7 @@ case $basic_machine in
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-vxsim* | -vxworks*)
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
-aux*)
|
||||
@@ -1359,6 +1457,9 @@ case $basic_machine in
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
vendor=atari
|
||||
;;
|
||||
-vos*)
|
||||
vendor=stratus
|
||||
;;
|
||||
esac
|
||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||
;;
|
||||
|
||||
84
configure.in
84
configure.in
@@ -5,7 +5,7 @@ AC_CONFIG_SRCDIR([byteorder.h])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PREREQ(2.52)
|
||||
|
||||
RSYNC_VERSION=2.5.4
|
||||
RSYNC_VERSION=2.5.6
|
||||
AC_SUBST(RSYNC_VERSION)
|
||||
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
|
||||
|
||||
@@ -25,7 +25,7 @@ AC_SUBST(SHELL)
|
||||
AC_DEFINE([_GNU_SOURCE], 1,
|
||||
[Define _GNU_SOURCE so that we get all necessary prototypes])
|
||||
|
||||
if test "$xac_cv_prog_cc_stdc" = xno
|
||||
if test "x$ac_cv_prog_cc_stdc" = xno
|
||||
then
|
||||
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
|
||||
fi
|
||||
@@ -65,6 +65,17 @@ then
|
||||
fi
|
||||
|
||||
|
||||
# Specifically, this turns on panic_action handling.
|
||||
AC_ARG_ENABLE(maintainer-mode,
|
||||
AC_HELP_STRING([--enable-maintainer-mode],
|
||||
[turn on extra debug features],
|
||||
[], []))
|
||||
if test x"$enable_maintainer_mode" = xyes
|
||||
then
|
||||
CFLAGS="$CFLAGS -DMAINTAINER_MODE"
|
||||
fi
|
||||
|
||||
|
||||
# This is needed for our included version of popt. Kind of silly, but
|
||||
# I don't want our version too far out of sync.
|
||||
CFLAGS="$CFLAGS -DHAVE_CONFIG_H"
|
||||
@@ -236,16 +247,26 @@ yes
|
||||
AC_SEARCH_LIBS(getaddrinfo, inet6)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([whether to call shutdown on all sockets])
|
||||
case $host_os in
|
||||
*cygwin* ) AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(SHUTDOWN_ALL_SOCKETS, 1,
|
||||
[Define if sockets need to be shutdown])
|
||||
;;
|
||||
* ) AC_MSG_RESULT(no);;
|
||||
esac
|
||||
|
||||
AC_C_BIGENDIAN
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_TIME
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h unistd.h utime.h grp.h)
|
||||
AC_CHECK_HEADERS(compat.h sys/param.h ctype.h sys/wait.h sys/ioctl.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h)
|
||||
AC_CHECK_HEADERS(glob.h alloca.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h sys/un.h)
|
||||
AC_CHECK_HEADERS(glob.h mcheck.h sys/sysctl.h arpa/inet.h arpa/nameser.h)
|
||||
AC_CHECK_HEADERS(netdb.h)
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
AC_CHECK_HEADERS(float.h)
|
||||
|
||||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
@@ -315,8 +336,39 @@ dnl AC_MSG_NOTICE([Looking in libraries: $LIBS])
|
||||
AC_CHECK_FUNCS(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
|
||||
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
|
||||
|
||||
AC_CHECK_FUNCS(getaddrinfo, , AC_LIBOBJ(lib/getaddrinfo))
|
||||
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
# Irix 6.5 has getaddrinfo but not the corresponding defines, so use
|
||||
# builtin getaddrinfo if one of the defines don't exist
|
||||
AC_CACHE_CHECK([whether defines needed by getaddrinfo exist],
|
||||
rsync_cv_HAVE_GETADDR_DEFINES,[
|
||||
AC_EGREP_CPP(yes, [
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#ifdef AI_PASSIVE
|
||||
yes
|
||||
#endif],
|
||||
rsync_cv_HAVE_GETADDR_DEFINES=yes,
|
||||
rsync_cv_HAVE_GETADDR_DEFINES=no)])
|
||||
if test x"$rsync_cv_HAVE_GETADDR_DEFINES" = x"yes"; then
|
||||
# Tru64 UNIX has getaddrinfo() but has it renamed in libc as
|
||||
# something else so we must include <netdb.h> to get the
|
||||
# redefinition.
|
||||
AC_CHECK_FUNCS(getaddrinfo, ,
|
||||
[AC_MSG_CHECKING([for getaddrinfo by including <netdb.h>])
|
||||
AC_TRY_LINK([#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>],[getaddrinfo(NULL, NULL, NULL, NULL);],
|
||||
[AC_MSG_RESULT([yes])
|
||||
AC_DEFINE(HAVE_GETADDRINFO, 1,
|
||||
[Define if you have the `getaddrinfo' function.])],
|
||||
[AC_MSG_RESULT([no])
|
||||
AC_LIBOBJ(lib/getaddrinfo)])])
|
||||
AC_CHECK_FUNCS(getnameinfo, , AC_LIBOBJ(lib/getnameinfo))
|
||||
else
|
||||
AC_LIBOBJ(lib/getaddrinfo)
|
||||
AC_LIBOBJ(lib/getnameinfo)
|
||||
fi
|
||||
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr.sa_len],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
|
||||
@@ -335,6 +387,15 @@ AC_TRY_COMPILE([#include <sys/types.h>
|
||||
[Define if you have strct sockaddr_storage.] ),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_scope_id],
|
||||
[ AC_DEFINE(HAVE_SOCKADDR_IN6_SCOPE_ID) ],
|
||||
[],
|
||||
[
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
])
|
||||
|
||||
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
|
||||
#
|
||||
AC_CHECK_FUNCS(strcasecmp)
|
||||
@@ -348,10 +409,11 @@ dnl every platform has a memcmp that can do at least that.
|
||||
dnl AC_FUNC_MEMCMP
|
||||
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
|
||||
AC_FUNC_ALLOCA
|
||||
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod mkfifo)
|
||||
AC_CHECK_FUNCS(fchmod fstat strchr readlink link utime utimes strftime)
|
||||
AC_CHECK_FUNCS(memmove lchown vsnprintf snprintf asprintf setsid glob strpbrk)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy mtrace mallinfo setgroups)
|
||||
AC_CHECK_FUNCS(strlcat strlcpy strtol mtrace mallinfo setgroups)
|
||||
|
||||
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
|
||||
AC_TRY_RUN([
|
||||
@@ -387,6 +449,12 @@ then
|
||||
AC_MSG_RESULT($srcdir/popt)
|
||||
BUILD_POPT='$(popt_OBJS)'
|
||||
CFLAGS="$CFLAGS -I$srcdir/popt"
|
||||
if test x"$ALLOCA" != x
|
||||
then
|
||||
# this can be removed when/if we add an included alloca.c;
|
||||
# see autoconf documentation on AC_FUNC_ALLOCA
|
||||
AC_MSG_WARN([included libpopt will use malloc, not alloca (which wastes a small amount of memory)])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
|
||||
2
doc/.cvsignore
Normal file
2
doc/.cvsignore
Normal file
@@ -0,0 +1,2 @@
|
||||
rsync.pdf
|
||||
rsync.ps
|
||||
@@ -253,10 +253,27 @@ running rsync giving the network directory.
|
||||
</qandaentry>
|
||||
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>
|
||||
Why is rsync so much bigger when I build it with
|
||||
<command>gcc</command>?
|
||||
</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
On gcc, rsync builds by default with debug symbols
|
||||
included. If you strip both executables, they should end
|
||||
up about the same size. (Use <command>make
|
||||
install-strip</command>.)
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
|
||||
|
||||
<qandaentry>
|
||||
<question>
|
||||
Is rsync useful for a single large file like an ISO image?
|
||||
<para>Is rsync useful for a single large file like an ISO image?</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>
|
||||
@@ -319,12 +336,16 @@ running rsync giving the network directory.
|
||||
This answer, formatted with "real" bullets, can be found at:
|
||||
-[4]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFileFAQ*
|
||||
|
||||
Note: I modified this on Oct. 9. 2001 -- I marked the changes with asterisks. The only deletion
|
||||
without a corresponding correction was the deletion of an "(IIRC)".
|
||||
2001-Oct-09 7:47am rhkramerATfastDOTnet
|
||||
</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandaset>
|
||||
</chapter>
|
||||
|
||||
|
||||
<appendix>
|
||||
<title>Other Resources</title>
|
||||
|
||||
<para><ulink url="http://www.ccp14.ac.uk/ccp14admin/rsync/"></ulink></para>
|
||||
</appendix>
|
||||
</book>
|
||||
@@ -22,6 +22,7 @@
|
||||
* string mappings in log.c
|
||||
*/
|
||||
|
||||
#define RERR_OK 0
|
||||
#define RERR_SYNTAX 1 /* syntax or usage error */
|
||||
#define RERR_PROTOCOL 2 /* protocol incompatibility */
|
||||
#define RERR_FILESELECT 3 /* errors selecting input/output files, dirs */
|
||||
|
||||
62
exclude.c
62
exclude.c
@@ -1,22 +1,23 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 1996 by Paul Mackerras
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1996-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 1996 by Paul Mackerras
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/* a lot of this stuff was originally derived from GNU tar, although
|
||||
it has now changed so much that it is hard to tell :) */
|
||||
@@ -30,7 +31,7 @@ extern int delete_mode;
|
||||
|
||||
static struct exclude_struct **exclude_list;
|
||||
|
||||
/* build an exclude structure given a exclude pattern */
|
||||
/** Build an exclude structure given a exclude pattern */
|
||||
static struct exclude_struct *make_exclude(const char *pattern, int include)
|
||||
{
|
||||
struct exclude_struct *ret;
|
||||
@@ -219,8 +220,14 @@ struct exclude_struct **make_exclude_list(const char *fname,
|
||||
int fatal, int include)
|
||||
{
|
||||
struct exclude_struct **list=list1;
|
||||
FILE *f = fopen(fname,"r");
|
||||
FILE *f;
|
||||
char line[MAXPATHLEN];
|
||||
|
||||
if (strcmp(fname, "-")) {
|
||||
f = fopen(fname,"r");
|
||||
} else {
|
||||
f = fdopen(0, "r");
|
||||
}
|
||||
if (!f) {
|
||||
if (fatal) {
|
||||
rsyserr(FERROR, errno,
|
||||
@@ -234,7 +241,7 @@ struct exclude_struct **make_exclude_list(const char *fname,
|
||||
|
||||
while (fgets(line,MAXPATHLEN,f)) {
|
||||
int l = strlen(line);
|
||||
if (l && line[l-1] == '\n') l--;
|
||||
while (l && (line[l-1] == '\n' || line[l-1] == '\r')) l--;
|
||||
line[l] = 0;
|
||||
if (line[0] && (line[0] != ';') && (line[0] != '#')) {
|
||||
/* Skip lines starting with semicolon or pound.
|
||||
@@ -334,7 +341,7 @@ char *get_exclude_tok(char *p)
|
||||
return(NULL);
|
||||
|
||||
/* Skip over any initial spaces */
|
||||
while(isspace(*s))
|
||||
while (isspace(* (unsigned char *) s))
|
||||
s++;
|
||||
|
||||
/* Are we at the end of the string? */
|
||||
@@ -347,7 +354,7 @@ char *get_exclude_tok(char *p)
|
||||
s+=2;
|
||||
|
||||
/* Skip to the next space or the end of the string */
|
||||
while(!isspace(*s) && *s!='\0')
|
||||
while (!isspace(* (unsigned char *) s) && *s != '\0')
|
||||
s++;
|
||||
} else {
|
||||
t=NULL;
|
||||
@@ -386,12 +393,11 @@ void add_include_line(char *p)
|
||||
|
||||
|
||||
static char *cvs_ignore_list[] = {
|
||||
"RCS","SCCS","CVS","CVS.adm","RCSLOG","cvslog.*",
|
||||
"tags","TAGS",".make.state",".nse_depinfo",
|
||||
"*~", "#*", ".#*", ",*", "*.old", "*.bak", "*.BAK", "*.orig",
|
||||
"RCS/", "SCCS/", "CVS/", ".svn/", "CVS.adm", "RCSLOG", "cvslog.*",
|
||||
"tags", "TAGS", ".make.state", ".nse_depinfo",
|
||||
"*~", "#*", ".#*", ", *", "*.old", "*.bak", "*.BAK", "*.orig",
|
||||
"*.rej", ".del-*", "*.a", "*.o", "*.obj", "*.so", "*.Z", "*.elc", "*.ln",
|
||||
"core",NULL};
|
||||
|
||||
"core", NULL};
|
||||
|
||||
|
||||
void add_cvs_excludes(void)
|
||||
|
||||
128
flist.c
128
flist.c
@@ -61,8 +61,6 @@ extern int sanitize_paths;
|
||||
extern int read_batch;
|
||||
extern int write_batch;
|
||||
|
||||
static char topsrcname[MAXPATHLEN];
|
||||
|
||||
static struct exclude_struct **local_exclude_list;
|
||||
|
||||
static struct file_struct null_file;
|
||||
@@ -101,12 +99,13 @@ static void finish_filelist_progress(const struct file_list *flist)
|
||||
{
|
||||
if (do_progress) {
|
||||
/* This overwrites the progress line */
|
||||
rprintf(FINFO, "%d files to consider\n", flist->count);
|
||||
} else
|
||||
rprintf(FINFO, "%d file%sto consider\n",
|
||||
flist->count, flist->count == 1 ? " " : "s ");
|
||||
} else {
|
||||
rprintf(FINFO, "done\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void show_flist_stats(void)
|
||||
{
|
||||
/* Nothing yet */
|
||||
@@ -191,44 +190,59 @@ static void list_file_entry(struct file_struct *f)
|
||||
}
|
||||
|
||||
|
||||
int readlink_stat(const char *Path, STRUCT_STAT * Buffer, char *Linkbuf)
|
||||
/**
|
||||
* Stat either a symlink or its referent, depending on the settings of
|
||||
* copy_links, copy_unsafe_links, etc.
|
||||
*
|
||||
* @retval -1 on error
|
||||
*
|
||||
* @retval 0 for success
|
||||
*
|
||||
* @post If @p path is a symlink, then @p linkbuf (of size @c
|
||||
* MAXPATHLEN) contains the symlink target.
|
||||
*
|
||||
* @post @p buffer contains information about the link or the
|
||||
* referrent as appropriate, if they exist.
|
||||
**/
|
||||
int readlink_stat(const char *path, STRUCT_STAT * buffer, char *linkbuf)
|
||||
{
|
||||
#if SUPPORT_LINKS
|
||||
if (copy_links) {
|
||||
return do_stat(Path, Buffer);
|
||||
return do_stat(path, buffer);
|
||||
}
|
||||
if (do_lstat(Path, Buffer) == -1) {
|
||||
if (do_lstat(path, buffer) == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (S_ISLNK(Buffer->st_mode)) {
|
||||
if (S_ISLNK(buffer->st_mode)) {
|
||||
int l;
|
||||
if ((l =
|
||||
readlink((char *) Path, Linkbuf,
|
||||
MAXPATHLEN - 1)) == -1) {
|
||||
l = readlink((char *) path, linkbuf, MAXPATHLEN - 1);
|
||||
if (l == -1)
|
||||
return -1;
|
||||
}
|
||||
Linkbuf[l] = 0;
|
||||
if (copy_unsafe_links && (topsrcname[0] != '\0') &&
|
||||
unsafe_symlink(Linkbuf, topsrcname)) {
|
||||
return do_stat(Path, Buffer);
|
||||
linkbuf[l] = 0;
|
||||
if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) {
|
||||
if (verbose > 1) {
|
||||
rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n",
|
||||
path, linkbuf);
|
||||
}
|
||||
return do_stat(path, buffer);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return do_stat(Path, Buffer);
|
||||
return do_stat(path, buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
int link_stat(const char *Path, STRUCT_STAT * Buffer)
|
||||
int link_stat(const char *path, STRUCT_STAT * buffer)
|
||||
{
|
||||
#if SUPPORT_LINKS
|
||||
if (copy_links) {
|
||||
return do_stat(Path, Buffer);
|
||||
return do_stat(path, buffer);
|
||||
} else {
|
||||
return do_lstat(Path, Buffer);
|
||||
return do_lstat(path, buffer);
|
||||
}
|
||||
#else
|
||||
return do_stat(Path, Buffer);
|
||||
return do_stat(path, buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -341,6 +355,8 @@ static void send_file_entry(struct file_struct *file, int f,
|
||||
return;
|
||||
}
|
||||
|
||||
io_write_phase = "send_file_entry";
|
||||
|
||||
fname = f_name(file);
|
||||
|
||||
flags = base_flags;
|
||||
@@ -436,6 +452,8 @@ static void send_file_entry(struct file_struct *file, int f,
|
||||
|
||||
strlcpy(lastname, fname, MAXPATHLEN);
|
||||
lastname[MAXPATHLEN - 1] = 0;
|
||||
|
||||
io_write_phase = "unknown";
|
||||
}
|
||||
|
||||
|
||||
@@ -521,7 +539,7 @@ static void receive_file_entry(struct file_struct **fptr,
|
||||
(flags & SAME_GID) ? last_gid : (gid_t) read_int(f);
|
||||
if (preserve_devices && IS_DEVICE(file->mode))
|
||||
file->rdev =
|
||||
(flags & SAME_RDEV) ? last_rdev : (dev_t) read_int(f);
|
||||
(flags & SAME_RDEV) ? last_rdev : (DEV64_T) read_int(f);
|
||||
|
||||
if (preserve_links && S_ISLNK(file->mode)) {
|
||||
int l = read_int(f);
|
||||
@@ -643,8 +661,10 @@ struct file_struct *make_file(int f, char *fname, struct string_area **ap,
|
||||
|
||||
if (readlink_stat(fname, &st, linkbuf) != 0) {
|
||||
int save_errno = errno;
|
||||
if ((errno == ENOENT) && copy_links && !noexcludes) {
|
||||
/* symlink pointing nowhere, see if excluded */
|
||||
if ((errno == ENOENT) && !noexcludes) {
|
||||
/* either symlink pointing nowhere or file that
|
||||
* was removed during rsync run; see if excluded
|
||||
* before reporting an error */
|
||||
memset((char *) &st, 0, sizeof(st));
|
||||
if (check_exclude_file(f, fname, &st)) {
|
||||
/* file is excluded anyway, ignore silently */
|
||||
@@ -850,11 +870,11 @@ static void send_directory(int f, struct file_list *flist, char *dir)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
*
|
||||
* I *think* f==-1 means that the list should just be built in memory
|
||||
* and not transmitted. But who can tell? -- mbp
|
||||
*/
|
||||
* I <b>think</b> f==-1 means that the list should just be built in
|
||||
* memory and not transmitted. But who can tell? -- mbp
|
||||
**/
|
||||
struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
{
|
||||
int i, l;
|
||||
@@ -876,7 +896,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
}
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
char *fname = topsrcname;
|
||||
char fname2[MAXPATHLEN];
|
||||
char *fname = fname2;
|
||||
|
||||
strlcpy(fname, argv[i], MAXPATHLEN);
|
||||
|
||||
@@ -981,14 +1002,13 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
topsrcname[0] = '\0';
|
||||
|
||||
if (f != -1) {
|
||||
send_file_entry(NULL, f, 0);
|
||||
}
|
||||
|
||||
if (show_filelist_p())
|
||||
if (show_filelist_p() && f != -1) {
|
||||
finish_filelist_progress(flist);
|
||||
}
|
||||
|
||||
clean_flist(flist, 0);
|
||||
|
||||
@@ -1133,7 +1153,9 @@ int flist_find(struct file_list *flist, struct file_struct *f)
|
||||
{
|
||||
int low = 0, high = flist->count - 1;
|
||||
|
||||
if (flist->count <= 0)
|
||||
while (high >= 0 && !flist->files[high]->basename) high--;
|
||||
|
||||
if (high < 0)
|
||||
return -1;
|
||||
|
||||
while (low != high) {
|
||||
@@ -1175,7 +1197,7 @@ void free_file(struct file_struct *file)
|
||||
/*
|
||||
* allocate a new file list
|
||||
*/
|
||||
struct file_list *flist_new()
|
||||
struct file_list *flist_new(void)
|
||||
{
|
||||
struct file_list *flist;
|
||||
|
||||
@@ -1227,6 +1249,7 @@ void flist_free(struct file_list *flist)
|
||||
static void clean_flist(struct file_list *flist, int strip_root)
|
||||
{
|
||||
int i;
|
||||
char *name, *prev_name = NULL;
|
||||
|
||||
if (!flist || flist->count == 0)
|
||||
return;
|
||||
@@ -1234,30 +1257,34 @@ static void clean_flist(struct file_list *flist, int strip_root)
|
||||
qsort(flist->files, flist->count,
|
||||
sizeof(flist->files[0]), (int (*)()) file_compare);
|
||||
|
||||
for (i = 1; i < flist->count; i++) {
|
||||
if (flist->files[i]->basename &&
|
||||
flist->files[i - 1]->basename &&
|
||||
strcmp(f_name(flist->files[i]),
|
||||
f_name(flist->files[i - 1])) == 0) {
|
||||
if (verbose > 1 && !am_server)
|
||||
for (i = 0; i < flist->count; i++) {
|
||||
if (flist->files[i]->basename) {
|
||||
prev_name = f_name(flist->files[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (++i < flist->count) {
|
||||
if (!flist->files[i]->basename)
|
||||
continue;
|
||||
name = f_name(flist->files[i]);
|
||||
if (strcmp(name, prev_name) == 0) {
|
||||
if (verbose > 1 && !am_server) {
|
||||
rprintf(FINFO,
|
||||
"removing duplicate name %s from file list %d\n",
|
||||
f_name(flist->files[i - 1]),
|
||||
i - 1);
|
||||
/* it's not great that the flist knows the semantics of the
|
||||
* file memory usage, but i'd rather not add a flag byte
|
||||
* to that struct. XXX can i use a bit in the flags field? */
|
||||
name, i);
|
||||
}
|
||||
/* it's not great that the flist knows the semantics of
|
||||
* the file memory usage, but i'd rather not add a flag
|
||||
* byte to that struct.
|
||||
* XXX can i use a bit in the flags field? */
|
||||
if (flist->string_area)
|
||||
flist->files[i][0] = null_file;
|
||||
else
|
||||
free_file(flist->files[i]);
|
||||
}
|
||||
prev_name = name;
|
||||
}
|
||||
|
||||
/* FIXME: There is a bug here when filenames are repeated more
|
||||
* than once, because we don't handle freed files when doing
|
||||
* the comparison. */
|
||||
|
||||
if (strip_root) {
|
||||
/* we need to strip off the root directory in the case
|
||||
of relative paths, but this must be done _after_
|
||||
@@ -1277,7 +1304,6 @@ static void clean_flist(struct file_list *flist, int strip_root)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (verbose <= 3)
|
||||
return;
|
||||
|
||||
|
||||
202
generator.c
202
generator.c
@@ -32,7 +32,6 @@ extern int preserve_devices;
|
||||
extern int preserve_hard_links;
|
||||
extern int update_only;
|
||||
extern int opt_ignore_existing;
|
||||
extern int whole_file;
|
||||
extern int block_size;
|
||||
extern int csum_length;
|
||||
extern int ignore_times;
|
||||
@@ -42,6 +41,7 @@ extern int remote_version;
|
||||
extern int always_checksum;
|
||||
extern int modify_window;
|
||||
extern char *compare_dest;
|
||||
extern int link_dest;
|
||||
|
||||
|
||||
/* choose whether to skip a particular file */
|
||||
@@ -51,6 +51,15 @@ static int skip_file(char *fname,
|
||||
if (st->st_size != file->length) {
|
||||
return 0;
|
||||
}
|
||||
if (link_dest) {
|
||||
if((st->st_mode & ~_S_IFMT) != (file->mode & ~_S_IFMT)) {
|
||||
return 0;
|
||||
}
|
||||
if (st->st_uid != file->uid || st->st_gid != file->gid) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* if always checksum is set then we use the checksum instead
|
||||
of the file time to determine whether to sync */
|
||||
@@ -101,106 +110,110 @@ static int adapt_block_size(struct file_struct *file, int bsize)
|
||||
|
||||
|
||||
/*
|
||||
send a sums struct down a fd
|
||||
send a header that says "we have no checksums" down the f_out fd
|
||||
*/
|
||||
static void send_sums(struct sum_struct *s, int f_out)
|
||||
static void send_null_sums(int f_out)
|
||||
{
|
||||
if (s) {
|
||||
size_t i;
|
||||
|
||||
/* tell the other guy how many we are going to be
|
||||
doing and how many bytes there are in the last
|
||||
chunk */
|
||||
write_int(f_out, s->count);
|
||||
write_int(f_out, s->n);
|
||||
write_int(f_out, s->remainder);
|
||||
|
||||
for (i = 0; i < s->count; i++) {
|
||||
write_int(f_out, s->sums[i].sum1);
|
||||
write_buf(f_out, s->sums[i].sum2, csum_length);
|
||||
}
|
||||
} else {
|
||||
/* we don't have checksums */
|
||||
write_int(f_out, 0);
|
||||
write_int(f_out, block_size);
|
||||
write_int(f_out, 0);
|
||||
}
|
||||
write_int(f_out, 0);
|
||||
write_int(f_out, block_size);
|
||||
write_int(f_out, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
generate a stream of signatures/checksums that describe a buffer
|
||||
|
||||
generate approximately one checksum every n bytes
|
||||
*/
|
||||
static struct sum_struct *generate_sums(struct map_struct *buf,OFF_T len,int n)
|
||||
|
||||
/**
|
||||
* Perhaps we want to just send an empty checksum set for this file,
|
||||
* which will force the whole thing to be literally transferred.
|
||||
*
|
||||
* When do we do this? If the user's explicitly said they
|
||||
* want the whole thing, or if { they haven't explicitly
|
||||
* requested a delta, and it's local but not batch mode.}
|
||||
*
|
||||
* Whew. */
|
||||
static BOOL disable_deltas_p(void)
|
||||
{
|
||||
int i;
|
||||
struct sum_struct *s;
|
||||
int count;
|
||||
int block_len = n;
|
||||
int remainder = (len%block_len);
|
||||
extern int whole_file, no_whole_file;
|
||||
extern int local_server;
|
||||
extern int write_batch;
|
||||
|
||||
assert(whole_file == 0 || whole_file == 1);
|
||||
|
||||
/* whole_file and no_whole_file are never both on at the same time */
|
||||
|
||||
if (whole_file)
|
||||
return True;
|
||||
else if (no_whole_file)
|
||||
return False;
|
||||
else if (write_batch)
|
||||
return False;
|
||||
else
|
||||
return local_server;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generate and send a stream of signatures/checksums that describe a buffer
|
||||
*
|
||||
* Generate approximately one checksum every block_len bytes.
|
||||
*/
|
||||
static void generate_and_send_sums(struct map_struct *buf, OFF_T len,
|
||||
int block_len, int f_out)
|
||||
{
|
||||
size_t i;
|
||||
struct sum_struct sum;
|
||||
OFF_T offset = 0;
|
||||
|
||||
count = (len+(block_len-1))/block_len;
|
||||
sum.count = (len + (block_len - 1)) / block_len;
|
||||
sum.remainder = (len % block_len);
|
||||
sum.n = block_len;
|
||||
sum.flength = len;
|
||||
/* not needed here sum.sums = NULL; */
|
||||
|
||||
s = (struct sum_struct *)malloc(sizeof(*s));
|
||||
if (!s) out_of_memory("generate_sums");
|
||||
|
||||
s->count = count;
|
||||
s->remainder = remainder;
|
||||
s->n = n;
|
||||
s->flength = len;
|
||||
|
||||
if (count==0) {
|
||||
s->sums = NULL;
|
||||
return s;
|
||||
if (sum.count && verbose > 3) {
|
||||
rprintf(FINFO, "count=%ld rem=%ld n=%ld flength=%.0f\n",
|
||||
(long) sum.count, (long) sum.remainder,
|
||||
(long) sum.n, (double) sum.flength);
|
||||
}
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"count=%d rem=%d n=%d flength=%.0f\n",
|
||||
s->count,s->remainder,s->n,(double)s->flength);
|
||||
write_int(f_out, sum.count);
|
||||
write_int(f_out, sum.n);
|
||||
write_int(f_out, sum.remainder);
|
||||
|
||||
s->sums = (struct sum_buf *)malloc(sizeof(s->sums[0])*s->count);
|
||||
if (!s->sums) out_of_memory("generate_sums");
|
||||
|
||||
for (i=0;i<count;i++) {
|
||||
int n1 = MIN(len,n);
|
||||
char *map = map_ptr(buf,offset,n1);
|
||||
for (i = 0; i < sum.count; i++) {
|
||||
int n1 = MIN(len, block_len);
|
||||
char *map = map_ptr(buf, offset, n1);
|
||||
uint32 sum1 = get_checksum1(map, n1);
|
||||
char sum2[SUM_LENGTH];
|
||||
|
||||
s->sums[i].sum1 = get_checksum1(map,n1);
|
||||
get_checksum2(map,n1,s->sums[i].sum2);
|
||||
|
||||
s->sums[i].offset = offset;
|
||||
s->sums[i].len = n1;
|
||||
s->sums[i].i = i;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"chunk[%d] offset=%.0f len=%d sum1=%08x\n",
|
||||
i,(double)s->sums[i].offset,s->sums[i].len,s->sums[i].sum1);
|
||||
get_checksum2(map, n1, sum2);
|
||||
|
||||
if (verbose > 3) {
|
||||
rprintf(FINFO,
|
||||
"chunk[%d] offset=%.0f len=%d sum1=%08lx\n",
|
||||
i, (double) offset, n1, (unsigned long) sum1);
|
||||
}
|
||||
write_int(f_out, sum1);
|
||||
write_buf(f_out, sum2, csum_length);
|
||||
len -= n1;
|
||||
offset += n1;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Acts on file number I from FLIST, whose name is fname.
|
||||
/**
|
||||
* Acts on file number @p i from @p flist, whose name is @p fname.
|
||||
*
|
||||
* First fixes up permissions, then generates checksums for the file.
|
||||
*
|
||||
* (This comment was added later by mbp who was trying to work it out;
|
||||
* it might be wrong.)
|
||||
*/
|
||||
void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
* @note This comment was added later by mbp who was trying to work it
|
||||
* out. It might be wrong.
|
||||
**/
|
||||
void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
|
||||
{
|
||||
int fd;
|
||||
STRUCT_STAT st;
|
||||
struct map_struct *buf;
|
||||
struct sum_struct *s;
|
||||
int statret;
|
||||
struct file_struct *file = flist->files[i];
|
||||
char *fnamecmp;
|
||||
@@ -209,6 +222,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
extern int list_only;
|
||||
extern int preserve_perms;
|
||||
extern int only_existing;
|
||||
extern int orig_umask;
|
||||
|
||||
if (list_only) return;
|
||||
|
||||
@@ -251,7 +265,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
}
|
||||
if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
|
||||
if (!(relative_paths && errno==ENOENT &&
|
||||
create_directory_path(fname)==0 &&
|
||||
create_directory_path(fname, orig_umask)==0 &&
|
||||
do_mkdir(fname,file->mode)==0)) {
|
||||
rprintf(FERROR, RSYNC_NAME ": recv_generator: mkdir \"%s\": %s (2)\n",
|
||||
fname,strerror(errno));
|
||||
@@ -332,7 +346,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
if (preserve_hard_links && check_hard_link(file)) {
|
||||
if (verbose > 1)
|
||||
rprintf(FINFO, "\"%s\" is a hard link\n",f_name(file));
|
||||
rprintf(FINFO, "recv_generator: \"%s\" is a hard link\n",f_name(file));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -352,6 +366,18 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
statret = -1;
|
||||
if (statret == -1)
|
||||
errno = saveerrno;
|
||||
#if HAVE_LINK
|
||||
else if (link_dest && !dry_run) {
|
||||
if (do_link(fnamecmpbuf, fname) != 0) {
|
||||
if (verbose > 0)
|
||||
rprintf(FINFO,"link %s => %s : %s\n",
|
||||
fnamecmpbuf,
|
||||
fname,
|
||||
strerror(errno));
|
||||
}
|
||||
fnamecmp = fnamecmpbuf;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
fnamecmp = fnamecmpbuf;
|
||||
}
|
||||
@@ -359,7 +385,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (statret == -1) {
|
||||
if (errno == ENOENT) {
|
||||
write_int(f_out,i);
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
if (!dry_run) send_null_sums(f_out);
|
||||
} else {
|
||||
if (verbose > 1)
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
@@ -376,7 +402,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
|
||||
/* now pretend the file didn't exist */
|
||||
write_int(f_out,i);
|
||||
if (!dry_run) send_sums(NULL,f_out);
|
||||
if (!dry_run) send_null_sums(f_out);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -403,9 +429,9 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
return;
|
||||
}
|
||||
|
||||
if (whole_file) {
|
||||
if (disable_deltas_p()) {
|
||||
write_int(f_out,i);
|
||||
send_sums(NULL,f_out);
|
||||
send_null_sums(f_out);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -416,7 +442,7 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
rprintf(FERROR,RSYNC_NAME": failed to open \"%s\", continuing : %s\n",fnamecmp,strerror(errno));
|
||||
/* pretend the file didn't exist */
|
||||
write_int(f_out,i);
|
||||
send_sums(NULL,f_out);
|
||||
send_null_sums(f_out);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -429,18 +455,15 @@ void recv_generator(char *fname,struct file_list *flist,int i,int f_out)
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"gen mapped %s of size %.0f\n",fnamecmp,(double)st.st_size);
|
||||
|
||||
s = generate_sums(buf,st.st_size,adapt_block_size(file, block_size));
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"sending sums for %d\n",i);
|
||||
rprintf(FINFO, "generating and sending sums for %d\n", i);
|
||||
|
||||
write_int(f_out,i);
|
||||
send_sums(s,f_out);
|
||||
generate_and_send_sums(buf, st.st_size,
|
||||
adapt_block_size(file, block_size), f_out);
|
||||
|
||||
close(fd);
|
||||
if (buf) unmap_file(buf);
|
||||
|
||||
free_sums(s);
|
||||
}
|
||||
|
||||
|
||||
@@ -454,6 +477,13 @@ void generate_files(int f,struct file_list *flist,char *local_name,int f_recv)
|
||||
rprintf(FINFO,"generator starting pid=%d count=%d\n",
|
||||
(int)getpid(),flist->count);
|
||||
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO,
|
||||
disable_deltas_p()
|
||||
? "delta-transmission disabled for local transfer or --whole-file\n"
|
||||
: "delta transmission enabled\n");
|
||||
}
|
||||
|
||||
/* we expect to just sit around now, so don't exit on a
|
||||
timeout. If we really get a timeout then the other process should
|
||||
exit */
|
||||
|
||||
49
getgroups.c
Normal file
49
getgroups.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file getgroups.c
|
||||
*
|
||||
* Print out the gids of all groups for the current user. This is
|
||||
* like `id -G` on Linux, but it's too hard to find a portable
|
||||
* equivalent.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#ifndef NGROUPS
|
||||
/* It ought to be defined, but just in case. */
|
||||
# define NGROUPS 32
|
||||
#endif
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int n, i;
|
||||
gid_t list[NGROUPS];
|
||||
|
||||
if ((n = getgroups(NGROUPS, list)) == -1) {
|
||||
perror("getgroups");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
printf("%u ", list[i]);
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
9
hlink.c
9
hlink.c
@@ -97,14 +97,21 @@ int check_hard_link(struct file_struct *file)
|
||||
low = mid + 1;
|
||||
}
|
||||
|
||||
/* XXX: To me this looks kind of dodgy -- why do we use [low]
|
||||
* here and [low-1] below? -- mbp */
|
||||
if (hlink_compare(&hlink_list[low], file) != 0)
|
||||
return 0;
|
||||
|
||||
if (low > 0 &&
|
||||
S_ISREG(hlink_list[low - 1].mode) &&
|
||||
file->dev == hlink_list[low - 1].dev &&
|
||||
file->inode == hlink_list[low - 1].inode)
|
||||
file->inode == hlink_list[low - 1].inode) {
|
||||
if (verbose >= 2) {
|
||||
rprintf(FINFO, "check_hard_link: \"%s\" is a hard link to file %d, \"%s\"\n",
|
||||
f_name(file), low-1, f_name(&hlink_list[low-1]));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -208,7 +208,7 @@ else
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
dsttmp=$dstdir/_inst.$$_
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
|
||||
187
io.c
187
io.c
@@ -1,26 +1,25 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2001 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1996-2001 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* @file io.c
|
||||
*
|
||||
* Socket and pipe IO utilities used in rsync.
|
||||
@@ -37,7 +36,7 @@
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* if no timeout is specified then use a 60 second select timeout */
|
||||
/** If no timeout is specified then use a 60 second select timeout */
|
||||
#define SELECT_TIMEOUT 60
|
||||
|
||||
static int io_multiplexing_out;
|
||||
@@ -53,6 +52,24 @@ extern int io_timeout;
|
||||
extern struct stats stats;
|
||||
|
||||
|
||||
const char phase_unknown[] = "unknown";
|
||||
|
||||
/**
|
||||
* The connection might be dropped at some point; perhaps because the
|
||||
* remote instance crashed. Just giving the offset on the stream is
|
||||
* not very helpful. So instead we try to make io_phase_name point to
|
||||
* something useful.
|
||||
*
|
||||
* For buffered/multiplexed IO these names will be somewhat
|
||||
* approximate; perhaps for ease of support we would rather make the
|
||||
* buffer always flush when a single application-level IO finishes.
|
||||
*
|
||||
* @todo Perhaps we want some simple stack functionality, but there's
|
||||
* no need to overdo it.
|
||||
**/
|
||||
const char *io_write_phase = phase_unknown;
|
||||
const char *io_read_phase = phase_unknown;
|
||||
|
||||
/** Ignore EOF errors while reading a module listing if the remote
|
||||
version is 24 or less. */
|
||||
int kludge_around_eof = False;
|
||||
@@ -87,13 +104,13 @@ static void check_timeout(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* setup the fd used to propogate errors */
|
||||
/** Setup the fd used to propagate errors */
|
||||
void io_set_error_fd(int fd)
|
||||
{
|
||||
io_error_fd = fd;
|
||||
}
|
||||
|
||||
/* read some data from the error fd and write it to the write log code */
|
||||
/** Read some data from the error fd and write it to the write log code */
|
||||
static void read_error_fd(void)
|
||||
{
|
||||
char buf[200];
|
||||
@@ -125,21 +142,18 @@ static void read_error_fd(void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* It's almost always an error to get an EOF when we're trying to read
|
||||
* from the network, because the protocol is self-terminating.
|
||||
*
|
||||
* However, there is one unfortunate cases where it is not, which is
|
||||
* rsync <2.4.6 sending a list of modules on a server, since the list
|
||||
* is terminated by closing the socket. So, for the section of the
|
||||
* program where that is a problem (start_socket_client),
|
||||
* kludge_around_eof is True and we just exit.
|
||||
*/
|
||||
static void whine_about_eof (void)
|
||||
{
|
||||
/**
|
||||
It's almost always an error to get an EOF when we're trying
|
||||
to read from the network, because the protocol is
|
||||
self-terminating.
|
||||
|
||||
However, there is one unfortunate cases where it is not,
|
||||
which is rsync <2.4.6 sending a list of modules on a
|
||||
server, since the list is terminated by closing the socket.
|
||||
So, for the section of the program where that is a problem
|
||||
(start_socket_client), kludge_around_eof is True and we
|
||||
just exit.
|
||||
*/
|
||||
|
||||
if (kludge_around_eof)
|
||||
exit_cleanup (0);
|
||||
else {
|
||||
@@ -164,7 +178,7 @@ static void die_from_readerr (int err)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Read from a socket with IO timeout. return the number of bytes
|
||||
* read. If no bytes can be read then exit, never return a number <= 0.
|
||||
*
|
||||
@@ -246,8 +260,10 @@ static int read_timeout (int fd, char *buf, size_t len)
|
||||
|
||||
|
||||
|
||||
/*! Continue trying to read len bytes - don't return until len has
|
||||
been read. */
|
||||
/**
|
||||
* Continue trying to read len bytes - don't return until len has been
|
||||
* read.
|
||||
**/
|
||||
static void read_loop (int fd, char *buf, size_t len)
|
||||
{
|
||||
while (len) {
|
||||
@@ -317,8 +333,11 @@ static int read_unbuffered(int fd, char *buf, size_t len)
|
||||
|
||||
|
||||
|
||||
/* do a buffered read from fd. don't return until all N bytes
|
||||
have been read. If all N can't be read then exit with an error */
|
||||
/**
|
||||
* Do a buffered read from @p fd. Don't return until all @p n bytes
|
||||
* have been read. If all @p n can't be read then exit with an
|
||||
* error.
|
||||
**/
|
||||
static void readfd (int fd, char *buffer, size_t N)
|
||||
{
|
||||
int ret;
|
||||
@@ -388,8 +407,40 @@ unsigned char read_byte(int f)
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Write len bytes to fd. This underlies the multiplexing system,
|
||||
* which is always called by application code. */
|
||||
|
||||
/**
|
||||
* Sleep after writing to limit I/O bandwidth usage.
|
||||
*
|
||||
* @todo Rather than sleeping after each write, it might be better to
|
||||
* use some kind of averaging. The current algorithm seems to always
|
||||
* use a bit less bandwidth than specified, because it doesn't make up
|
||||
* for slow periods. But arguably this is a feature. In addition, we
|
||||
* ought to take the time used to write the data into account.
|
||||
**/
|
||||
static void sleep_for_bwlimit(int bytes_written)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
if (!bwlimit)
|
||||
return;
|
||||
|
||||
assert(bytes_written > 0);
|
||||
assert(bwlimit > 0);
|
||||
|
||||
tv.tv_usec = bytes_written * 1000 / bwlimit;
|
||||
tv.tv_sec = tv.tv_usec / 1000000;
|
||||
tv.tv_usec = tv.tv_usec % 1000000;
|
||||
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write len bytes to the file descriptor @p fd.
|
||||
*
|
||||
* This function underlies the multiplexing system. The body of the
|
||||
* application never calls this function directly.
|
||||
**/
|
||||
static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
{
|
||||
size_t total = 0;
|
||||
@@ -458,24 +509,13 @@ static void writefd_unbuffered(int fd,char *buf,size_t len)
|
||||
* across the stream */
|
||||
io_multiplexing_close();
|
||||
rprintf(FERROR, RSYNC_NAME
|
||||
": error writing %d unbuffered bytes"
|
||||
" - exiting: %s\n", len,
|
||||
": writefd_unbuffered failed to write %ld bytes: phase \"%s\": %s\n",
|
||||
(long) len, io_write_phase,
|
||||
strerror(errno));
|
||||
exit_cleanup(RERR_STREAMIO);
|
||||
}
|
||||
|
||||
/* Sleep after writing to limit I/O bandwidth */
|
||||
if (bwlimit)
|
||||
{
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = ret * 1000 / bwlimit;
|
||||
while (tv.tv_usec > 1000000)
|
||||
{
|
||||
tv.tv_sec++;
|
||||
tv.tv_usec -= 1000000;
|
||||
}
|
||||
select(0, NULL, NULL, NULL, &tv);
|
||||
}
|
||||
sleep_for_bwlimit(ret);
|
||||
|
||||
total += ret;
|
||||
|
||||
@@ -500,8 +540,10 @@ void io_start_buffering(int fd)
|
||||
io_buffer_count = 0;
|
||||
}
|
||||
|
||||
/* write an message to a multiplexed stream. If this fails then rsync
|
||||
exits */
|
||||
/**
|
||||
* Write an message to a multiplexed stream. If this fails then rsync
|
||||
* exits.
|
||||
**/
|
||||
static void mplex_write(int fd, enum logcode code, char *buf, size_t len)
|
||||
{
|
||||
char buffer[4096];
|
||||
@@ -584,6 +626,14 @@ void write_int(int f,int32 x)
|
||||
}
|
||||
|
||||
|
||||
void write_int_named(int f, int32 x, const char *phase)
|
||||
{
|
||||
io_write_phase = phase;
|
||||
write_int(f, x);
|
||||
io_write_phase = phase_unknown;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Note: int64 may actually be a 32-bit type if ./configure couldn't find any
|
||||
* 64-bit types on this platform.
|
||||
@@ -610,7 +660,7 @@ void write_buf(int f,char *buf,size_t len)
|
||||
writefd(f,buf,len);
|
||||
}
|
||||
|
||||
/* write a string to the connection */
|
||||
/** Write a string to the connection */
|
||||
static void write_sbuf(int f,char *buf)
|
||||
{
|
||||
write_buf(f, buf, strlen(buf));
|
||||
@@ -624,12 +674,19 @@ void write_byte(int f,unsigned char c)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read a line of up to @p maxlen characters into @p buf. Does not
|
||||
* contain a trailing newline or carriage return.
|
||||
*
|
||||
* @return 1 for success; 0 for io error or truncation.
|
||||
**/
|
||||
int read_line(int f, char *buf, size_t maxlen)
|
||||
{
|
||||
while (maxlen) {
|
||||
buf[0] = 0;
|
||||
read_buf(f, buf, 1);
|
||||
if (buf[0] == 0) return 0;
|
||||
if (buf[0] == 0)
|
||||
return 0;
|
||||
if (buf[0] == '\n') {
|
||||
buf[0] = 0;
|
||||
break;
|
||||
@@ -664,7 +721,7 @@ void io_printf(int fd, const char *format, ...)
|
||||
}
|
||||
|
||||
|
||||
/* setup for multiplexing an error stream with the data stream */
|
||||
/** Setup for multiplexing an error stream with the data stream */
|
||||
void io_start_multiplex_out(int fd)
|
||||
{
|
||||
multiplex_out_fd = fd;
|
||||
@@ -673,7 +730,7 @@ void io_start_multiplex_out(int fd)
|
||||
io_multiplexing_out = 1;
|
||||
}
|
||||
|
||||
/* setup for multiplexing an error stream with the data stream */
|
||||
/** Setup for multiplexing an error stream with the data stream */
|
||||
void io_start_multiplex_in(int fd)
|
||||
{
|
||||
multiplex_in_fd = fd;
|
||||
@@ -681,7 +738,7 @@ void io_start_multiplex_in(int fd)
|
||||
io_multiplexing_in = 1;
|
||||
}
|
||||
|
||||
/* write an message to the multiplexed error stream */
|
||||
/** Write an message to the multiplexed error stream */
|
||||
int io_multiplex_write(enum logcode code, char *buf, size_t len)
|
||||
{
|
||||
if (!io_multiplexing_out) return 0;
|
||||
@@ -692,7 +749,7 @@ int io_multiplex_write(enum logcode code, char *buf, size_t len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* stop output multiplexing */
|
||||
/** Stop output multiplexing */
|
||||
void io_multiplexing_close(void)
|
||||
{
|
||||
io_multiplexing_out = 0;
|
||||
|
||||
41
lib/compat.c
41
lib/compat.c
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
Copyright (C) Andrew Tridgell 1998
|
||||
Copyright (C) 2002 by Martin Pool
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -16,11 +17,15 @@
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
compatibility functions - replacing functions for platforms that don't
|
||||
have them.
|
||||
/**
|
||||
* @file compat.c
|
||||
*
|
||||
* Reimplementations of standard functions for platforms that don't
|
||||
* have them.
|
||||
**/
|
||||
|
||||
|
||||
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
@@ -78,9 +83,11 @@
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRPBRK
|
||||
/* Find the first ocurrence in S of any character in ACCEPT.
|
||||
derived from glibc
|
||||
*/
|
||||
/**
|
||||
* Find the first ocurrence in @p s of any character in @p accept.
|
||||
*
|
||||
* Derived from glibc
|
||||
**/
|
||||
char *strpbrk(const char *s, const char *accept)
|
||||
{
|
||||
while (*s != '\0') {
|
||||
@@ -97,10 +104,14 @@
|
||||
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
/* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates. bufsize is the size of the destination buffer.
|
||||
/**
|
||||
* Like strncpy but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* Returns the index of the terminating byte. */
|
||||
* @param bufsize is the size of the destination buffer.
|
||||
*
|
||||
* @return index of the terminating byte.
|
||||
**/
|
||||
size_t strlcpy(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len = strlen(s);
|
||||
@@ -114,9 +125,13 @@
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
/* like strncat but does not 0 fill the buffer and always null
|
||||
terminates. bufsize is the length of the buffer, which should
|
||||
be one more than the maximum resulting string length */
|
||||
/**
|
||||
* Like strncat() but does not 0 fill the buffer and always null
|
||||
* terminates.
|
||||
*
|
||||
* @param bufsize length of the buffer, which should be one more than
|
||||
* the maximum resulting string length.
|
||||
**/
|
||||
size_t strlcat(char *d, const char *s, size_t bufsize)
|
||||
{
|
||||
size_t len1 = strlen(d);
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
*/
|
||||
|
||||
static int inet_pton4(const char *src, unsigned char *dst);
|
||||
#ifdef INET6
|
||||
static int inet_pton6(const char *src, unsigned char *dst);
|
||||
#endif
|
||||
|
||||
/* int
|
||||
* isc_net_pton(af, src, dst)
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
|
||||
@@ -47,8 +47,10 @@ void permstring(char *perms,
|
||||
if (mode & S_ISGID)
|
||||
perms[6] = (mode & S_IXGRP) ? 's' : 'S';
|
||||
|
||||
#ifdef S_ISVTX
|
||||
if (mode & S_ISVTX)
|
||||
perms[9] = (mode & S_IXOTH) ? 't' : 'T';
|
||||
#endif
|
||||
|
||||
if (S_ISLNK(mode)) perms[0] = 'l';
|
||||
if (S_ISDIR(mode)) perms[0] = 'd';
|
||||
|
||||
30
loadparm.c
30
loadparm.c
@@ -3,7 +3,7 @@
|
||||
|
||||
/* some fixes
|
||||
*
|
||||
* Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -48,6 +48,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: Parameter to set debug level on server. */
|
||||
|
||||
#include "rsync.h"
|
||||
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
|
||||
#define strequal(a,b) (strcasecmp(a,b)==0)
|
||||
@@ -154,7 +156,16 @@ static service sDefault =
|
||||
False, /* transfer logging */
|
||||
False, /* ignore errors */
|
||||
"nobody",/* uid */
|
||||
|
||||
/* TODO: This causes problems on Debian, where it is called
|
||||
* "nogroup". Debian patch this in their version of the
|
||||
* package, but it would be nice to be consistent. Possibly
|
||||
* other systems are different again.
|
||||
*
|
||||
* What is the best behaviour? Perhaps always using (gid_t)
|
||||
* -2? */
|
||||
"nobody",/* gid */
|
||||
|
||||
NULL, /* hosts allow */
|
||||
NULL, /* hosts deny */
|
||||
NULL, /* auth users */
|
||||
@@ -468,11 +479,12 @@ static int strwicmp(char *psz1, char *psz2)
|
||||
/* sync the strings on first non-whitespace */
|
||||
while (1)
|
||||
{
|
||||
while (isspace(*psz1))
|
||||
while (isspace(* (unsigned char *) psz1))
|
||||
psz1++;
|
||||
while (isspace(*psz2))
|
||||
while (isspace(* (unsigned char *) psz2))
|
||||
psz2++;
|
||||
if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
|
||||
if (toupper(* (unsigned char *) psz1) != toupper(* (unsigned char *) psz2)
|
||||
|| *psz1 == '\0' || *psz2 == '\0')
|
||||
break;
|
||||
psz1++;
|
||||
psz2++;
|
||||
@@ -736,6 +748,9 @@ False on failure.
|
||||
***************************************************************************/
|
||||
BOOL lp_load(char *pszFname, int globals_only)
|
||||
{
|
||||
extern int am_server;
|
||||
extern int am_daemon;
|
||||
extern int am_root;
|
||||
pstring n2;
|
||||
BOOL bRetval;
|
||||
|
||||
@@ -745,7 +760,12 @@ BOOL lp_load(char *pszFname, int globals_only)
|
||||
|
||||
init_globals();
|
||||
|
||||
pstrcpy(n2,pszFname);
|
||||
if (pszFname)
|
||||
pstrcpy(n2,pszFname);
|
||||
else if (am_server && am_daemon && !am_root)
|
||||
pstrcpy(n2,RSYNCD_USERCONF);
|
||||
else
|
||||
pstrcpy(n2,RSYNCD_SYSCONF);
|
||||
|
||||
/* We get sections first, so have to start 'behind' to make up */
|
||||
iServiceIndex = -1;
|
||||
|
||||
31
log.c
31
log.c
@@ -27,9 +27,11 @@
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
static int log_initialised;
|
||||
static char *logfname;
|
||||
static FILE *logfile;
|
||||
static int log_error_fd = -1;
|
||||
struct stats stats;
|
||||
|
||||
int log_got_error=0;
|
||||
|
||||
@@ -50,7 +52,7 @@ struct {
|
||||
{ RERR_SIGNAL , "received SIGUSR1 or SIGINT" },
|
||||
{ RERR_WAITCHILD , "some error returned by waitpid()" },
|
||||
{ RERR_MALLOC , "error allocating core memory buffers" },
|
||||
{ RERR_PARTIAL , "partial transfer" },
|
||||
{ RERR_PARTIAL , "some files could not be transferred" },
|
||||
{ RERR_TIMEOUT , "timeout in data send/receive" },
|
||||
{ RERR_CMD_FAILED , "remote shell failed" },
|
||||
{ RERR_CMD_KILLED , "remote shell killed" },
|
||||
@@ -145,12 +147,11 @@ static void logit(int priority, char *buf)
|
||||
|
||||
void log_init(void)
|
||||
{
|
||||
static int initialised;
|
||||
int options = LOG_PID;
|
||||
time_t t;
|
||||
|
||||
if (initialised) return;
|
||||
initialised = 1;
|
||||
if (log_initialised) return;
|
||||
log_initialised = 1;
|
||||
|
||||
/* this looks pointless, but it is needed in order for the
|
||||
C library on some systems to fetch the timezone info
|
||||
@@ -183,7 +184,7 @@ void log_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void log_open()
|
||||
void log_open(void)
|
||||
{
|
||||
if (logfname && !logfile) {
|
||||
extern int orig_umask;
|
||||
@@ -193,7 +194,7 @@ void log_open()
|
||||
}
|
||||
}
|
||||
|
||||
void log_close()
|
||||
void log_close(void)
|
||||
{
|
||||
if (logfile) {
|
||||
fclose(logfile);
|
||||
@@ -237,16 +238,20 @@ void rwrite(enum logcode code, char *buf, int len)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If that fails, try to pass it to the other end.
|
||||
*
|
||||
* io_multiplex_write can fail if we do not have a multiplexed
|
||||
* connection at the moment, in which case we fall through and
|
||||
* log locally instead. */
|
||||
if (am_server && io_multiplex_write(code, buf, len)) {
|
||||
/* next, if we are a server but not in daemon mode, and multiplexing
|
||||
* is enabled, pass it to the other side. */
|
||||
if (am_server && !am_daemon && io_multiplex_write(code, buf, len)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (am_daemon) {
|
||||
/* otherwise, if in daemon mode and either we are not a server
|
||||
* (that is, we are not running --daemon over a remote shell) or
|
||||
* the log has already been initialised, log the message on this
|
||||
* side because we don't want the client to see most errors for
|
||||
* security reasons. We do want early messages when running daemon
|
||||
* mode over a remote shell to go to the remote side; those will
|
||||
* fall through to the next case. */
|
||||
if (am_daemon && (!am_server || log_initialised)) {
|
||||
static int depth;
|
||||
int priority = LOG_INFO;
|
||||
if (code == FERROR) priority = LOG_WARNING;
|
||||
|
||||
219
main.c
219
main.c
@@ -23,10 +23,19 @@
|
||||
|
||||
time_t starttime = 0;
|
||||
|
||||
struct stats stats;
|
||||
|
||||
extern struct stats stats;
|
||||
extern int verbose;
|
||||
|
||||
/* there's probably never more than at most 2 outstanding child processes,
|
||||
* but set it higher just in case.
|
||||
*/
|
||||
#define MAXCHILDPROCS 5
|
||||
|
||||
struct pid_status {
|
||||
pid_t pid;
|
||||
int status;
|
||||
} pid_stat_table[MAXCHILDPROCS];
|
||||
|
||||
static void show_malloc_stats(void);
|
||||
|
||||
/****************************************************************************
|
||||
@@ -34,11 +43,27 @@ wait for a process to exit, calling io_flush while waiting
|
||||
****************************************************************************/
|
||||
void wait_process(pid_t pid, int *status)
|
||||
{
|
||||
while (waitpid(pid, status, WNOHANG) == 0) {
|
||||
pid_t waited_pid;
|
||||
int cnt;
|
||||
|
||||
while ((waited_pid = waitpid(pid, status, WNOHANG)) == 0) {
|
||||
msleep(20);
|
||||
io_flush();
|
||||
}
|
||||
|
||||
if ((waited_pid == -1) && (errno == ECHILD)) {
|
||||
/* status of requested child no longer available.
|
||||
* check to see if it was processed by the sigchld_handler.
|
||||
*/
|
||||
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
|
||||
if (pid == pid_stat_table[cnt].pid) {
|
||||
*status = pid_stat_table[cnt].status;
|
||||
pid_stat_table[cnt].pid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: If the child exited on a signal, then log an
|
||||
* appropriate error message. Perhaps we should also accept a
|
||||
* message describing the purpose of the child. Also indicate
|
||||
@@ -172,9 +197,11 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
|
||||
int i,argc=0;
|
||||
pid_t ret;
|
||||
char *tok,*dir=NULL;
|
||||
int dash_l_set = 0;
|
||||
extern int local_server;
|
||||
extern char *rsync_path;
|
||||
extern int blocking_io;
|
||||
extern int daemon_over_rsh;
|
||||
extern int read_batch;
|
||||
|
||||
if (!read_batch && !local_server) {
|
||||
@@ -190,15 +217,22 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
|
||||
args[argc++] = tok;
|
||||
}
|
||||
|
||||
/* check to see if we've already been given '-l user' in
|
||||
the remote-shell command */
|
||||
for (i = 0; i < argc-1; i++) {
|
||||
if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
|
||||
dash_l_set = 1;
|
||||
}
|
||||
|
||||
#if HAVE_REMSH
|
||||
/* remsh (on HPUX) takes the arguments the other way around */
|
||||
args[argc++] = machine;
|
||||
if (user) {
|
||||
if (user && !(daemon_over_rsh && dash_l_set)) {
|
||||
args[argc++] = "-l";
|
||||
args[argc++] = user;
|
||||
}
|
||||
#else
|
||||
if (user) {
|
||||
if (user && !(daemon_over_rsh && dash_l_set)) {
|
||||
args[argc++] = "-l";
|
||||
args[argc++] = user;
|
||||
}
|
||||
@@ -216,7 +250,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
|
||||
|
||||
args[argc++] = ".";
|
||||
|
||||
if (path && *path)
|
||||
if (!daemon_over_rsh && path && *path)
|
||||
args[argc++] = path;
|
||||
|
||||
args[argc] = NULL;
|
||||
@@ -231,7 +265,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
|
||||
if (local_server) {
|
||||
if (read_batch)
|
||||
create_flist_from_batch(); /* sets batch_flist */
|
||||
ret = local_child(argc, args, f_in, f_out);
|
||||
ret = local_child(argc, args, f_in, f_out, child_main);
|
||||
} else {
|
||||
ret = piped_child(args,f_in,f_out);
|
||||
}
|
||||
@@ -427,6 +461,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
|
||||
}
|
||||
io_flush();
|
||||
|
||||
io_set_error_fd(-1);
|
||||
kill(pid, SIGUSR2);
|
||||
wait_process(pid, &status);
|
||||
return status;
|
||||
@@ -493,6 +528,13 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
|
||||
}
|
||||
|
||||
|
||||
int child_main(int argc, char *argv[])
|
||||
{
|
||||
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void start_server(int f_in, int f_out, int argc, char *argv[])
|
||||
{
|
||||
extern int cvs_exclude;
|
||||
@@ -640,14 +682,14 @@ static int copy_argv (char *argv[])
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
* Start a client for either type of remote connection. Work out
|
||||
* whether the arguments request a remote shell or rsyncd connection,
|
||||
* and call the appropriate connection function, then run_client.
|
||||
*
|
||||
* Calls either start_socket_client (for sockets) or do_cmd and
|
||||
* client_run (for ssh).
|
||||
*/
|
||||
**/
|
||||
static int start_client(int argc, char *argv[])
|
||||
{
|
||||
char *p;
|
||||
@@ -661,16 +703,16 @@ static int start_client(int argc, char *argv[])
|
||||
extern int am_sender;
|
||||
extern char *shell_cmd;
|
||||
extern int rsync_port;
|
||||
extern int whole_file;
|
||||
extern int write_batch;
|
||||
extern int daemon_over_rsh;
|
||||
extern int read_batch;
|
||||
int rc;
|
||||
|
||||
/* Don't clobber argv[] so that ps(1) can still show the right
|
||||
command line. */
|
||||
if ((rc = copy_argv (argv)))
|
||||
if ((rc = copy_argv(argv)))
|
||||
return rc;
|
||||
|
||||
/* rsync:// always uses rsync server over direct socket connection */
|
||||
if (strncasecmp(URL_PREFIX, argv[0], strlen(URL_PREFIX)) == 0) {
|
||||
char *host, *path;
|
||||
|
||||
@@ -680,7 +722,7 @@ static int start_client(int argc, char *argv[])
|
||||
*p = 0;
|
||||
path = p+1;
|
||||
} else {
|
||||
path="";
|
||||
path = "";
|
||||
}
|
||||
p = strchr(host,':');
|
||||
if (p) {
|
||||
@@ -691,12 +733,17 @@ static int start_client(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (!read_batch) {
|
||||
p = find_colon(argv[0]);
|
||||
p = find_colon(argv[0]);
|
||||
|
||||
if (p) {
|
||||
if (p[1] == ':') {
|
||||
if (p[1] == ':') { /* double colon */
|
||||
*p = 0;
|
||||
return start_socket_client(argv[0], p+2, argc-1, argv+1);
|
||||
if (!shell_cmd) {
|
||||
return start_socket_client(argv[0], p+2,
|
||||
argc-1, argv+1);
|
||||
}
|
||||
p++;
|
||||
daemon_over_rsh = 1;
|
||||
}
|
||||
|
||||
if (argc < 1) {
|
||||
@@ -713,18 +760,37 @@ static int start_client(int argc, char *argv[])
|
||||
} else {
|
||||
am_sender = 1;
|
||||
|
||||
/* rsync:// destination uses rsync server over direct socket */
|
||||
if (strncasecmp(URL_PREFIX, argv[argc-1], strlen(URL_PREFIX)) == 0) {
|
||||
char *host, *path;
|
||||
|
||||
host = argv[argc-1] + strlen(URL_PREFIX);
|
||||
p = strchr(host,'/');
|
||||
if (p) {
|
||||
*p = 0;
|
||||
path = p+1;
|
||||
} else {
|
||||
path = "";
|
||||
}
|
||||
p = strchr(host,':');
|
||||
if (p) {
|
||||
rsync_port = atoi(p+1);
|
||||
*p = 0;
|
||||
}
|
||||
return start_socket_client(host, path, argc-1, argv);
|
||||
}
|
||||
|
||||
p = find_colon(argv[argc-1]);
|
||||
if (!p) {
|
||||
local_server = 1;
|
||||
/*
|
||||
* disable "rsync algorithm" when both sides local,
|
||||
* except when creating a batch update
|
||||
*/
|
||||
if (!write_batch && whole_file == -1)
|
||||
whole_file = 1;
|
||||
} else if (p[1] == ':') {
|
||||
} else if (p[1] == ':') { /* double colon */
|
||||
*p = 0;
|
||||
return start_socket_client(argv[argc-1], p+2, argc-1, argv);
|
||||
if (!shell_cmd) {
|
||||
return start_socket_client(argv[argc-1], p+2,
|
||||
argc-1, argv);
|
||||
}
|
||||
p++;
|
||||
daemon_over_rsh = 1;
|
||||
}
|
||||
|
||||
if (argc < 2) {
|
||||
@@ -775,8 +841,19 @@ static int start_client(int argc, char *argv[])
|
||||
list_only = 1;
|
||||
}
|
||||
|
||||
pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
|
||||
|
||||
pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,
|
||||
&f_in,&f_out);
|
||||
|
||||
/* if we're running an rsync server on the remote host over a
|
||||
remote shell command, we need to do the RSYNCD protocol first */
|
||||
if (daemon_over_rsh) {
|
||||
int tmpret;
|
||||
tmpret = start_inband_exchange(shell_user, shell_path,
|
||||
f_in, f_out, argc);
|
||||
if (tmpret < 0)
|
||||
return tmpret;
|
||||
}
|
||||
|
||||
ret = client_run(f_in, f_out, pid, argc, argv);
|
||||
|
||||
fflush(stdout);
|
||||
@@ -798,10 +875,79 @@ static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
|
||||
|
||||
static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
|
||||
#ifdef WNOHANG
|
||||
while (waitpid(-1, NULL, WNOHANG) > 0) ;
|
||||
int cnt, status;
|
||||
pid_t pid;
|
||||
/* An empty waitpid() loop was put here by Tridge and we could never
|
||||
* get him to explain why he put it in, so rather than taking it
|
||||
* out we're instead saving the child exit statuses for later use.
|
||||
* The waitpid() loop presumably eliminates all possibility of leaving
|
||||
* zombie children, maybe that's why he did it.
|
||||
*/
|
||||
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
|
||||
/* save the child's exit status */
|
||||
for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
|
||||
if (pid_stat_table[cnt].pid == 0) {
|
||||
pid_stat_table[cnt].pid = pid;
|
||||
pid_stat_table[cnt].status = status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This routine catches signals and tries to send them to gdb.
|
||||
*
|
||||
* Because it's called from inside a signal handler it ought not to
|
||||
* use too many library routines.
|
||||
*
|
||||
* @todo Perhaps use "screen -X" instead/as well, to help people
|
||||
* debugging without easy access to X. Perhaps use an environment
|
||||
* variable, or just call a script?
|
||||
*
|
||||
* @todo The /proc/ magic probably only works on Linux (and
|
||||
* Solaris?) Can we be more portable?
|
||||
**/
|
||||
#ifdef MAINTAINER_MODE
|
||||
const char *get_panic_action(void)
|
||||
{
|
||||
const char *cmd_fmt = getenv("RSYNC_PANIC_ACTION");
|
||||
|
||||
if (cmd_fmt)
|
||||
return cmd_fmt;
|
||||
else
|
||||
return "xterm -display :0 -T Panic -n Panic "
|
||||
"-e gdb /proc/%d/exe %d";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle a fatal signal by launching a debugger, controlled by $RSYNC_PANIC_ACTION.
|
||||
*
|
||||
* This signal handler is only installed if we were configured with
|
||||
* --enable-maintainer-mode. Perhaps it should always be on and we
|
||||
* should just look at the environment variable, but I'm a bit leery
|
||||
* of a signal sending us into a busy loop.
|
||||
**/
|
||||
static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
|
||||
{
|
||||
char cmd_buf[300];
|
||||
int ret;
|
||||
|
||||
sprintf(cmd_buf, get_panic_action(),
|
||||
getpid(), getpid());
|
||||
|
||||
/* Unless we failed to execute gdb, we allow the process to
|
||||
* continue. I'm not sure if that's right. */
|
||||
ret = system(cmd_buf);
|
||||
if (ret)
|
||||
_exit(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
extern int am_root;
|
||||
@@ -820,6 +966,12 @@ int main(int argc,char *argv[])
|
||||
signal(SIGUSR1, sigusr1_handler);
|
||||
signal(SIGUSR2, sigusr2_handler);
|
||||
signal(SIGCHLD, sigchld_handler);
|
||||
#ifdef MAINTAINER_MODE
|
||||
signal(SIGSEGV, rsync_panic_handler);
|
||||
signal(SIGFPE, rsync_panic_handler);
|
||||
signal(SIGABRT, rsync_panic_handler);
|
||||
signal(SIGBUS, rsync_panic_handler);
|
||||
#endif /* def MAINTAINER_MODE */
|
||||
|
||||
starttime = time(NULL);
|
||||
am_root = (getuid() == 0);
|
||||
@@ -860,9 +1012,8 @@ int main(int argc,char *argv[])
|
||||
write_batch_argvs_file(orig_argc, orig_argv);
|
||||
}
|
||||
|
||||
if (am_daemon) {
|
||||
if (am_daemon && !am_server)
|
||||
return daemon_main();
|
||||
}
|
||||
|
||||
if (argc < 1) {
|
||||
usage(FERROR);
|
||||
@@ -882,13 +1033,17 @@ int main(int argc,char *argv[])
|
||||
if (am_server) {
|
||||
set_nonblocking(STDIN_FILENO);
|
||||
set_nonblocking(STDOUT_FILENO);
|
||||
if (am_daemon)
|
||||
return start_daemon(STDIN_FILENO, STDOUT_FILENO);
|
||||
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
|
||||
}
|
||||
|
||||
ret = start_client(argc, argv);
|
||||
if (ret == -1)
|
||||
exit_cleanup(RERR_STARTCLIENT);
|
||||
exit_cleanup(RERR_STARTCLIENT);
|
||||
else
|
||||
exit_cleanup(ret);
|
||||
return ret;
|
||||
exit_cleanup(ret);
|
||||
|
||||
exit(ret);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
39
match.c
39
match.c
@@ -90,6 +90,18 @@ static void build_hash_table(struct sum_struct *s)
|
||||
static OFF_T last_match;
|
||||
|
||||
|
||||
/**
|
||||
* Transmit a literal and/or match token.
|
||||
*
|
||||
* This delightfully-named function is called either when we find a
|
||||
* match and need to transmit all the unmatched data leading up to it,
|
||||
* or when we get bored of accumulating literal data and just need to
|
||||
* transmit it. As a result of this second case, it is called even if
|
||||
* we have not matched at all!
|
||||
*
|
||||
* @param i If >0, the number of a matched token. If 0, indicates we
|
||||
* have only literal data.
|
||||
**/
|
||||
static void matched(int f,struct sum_struct *s,struct map_struct *buf,
|
||||
OFF_T offset,int i)
|
||||
{
|
||||
@@ -141,9 +153,12 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
last_i = -1;
|
||||
|
||||
if (verbose > 2)
|
||||
rprintf(FINFO,"hash search b=%d len=%.0f\n",s->n,(double)len);
|
||||
rprintf(FINFO,"hash search b=%ld len=%.0f\n",
|
||||
(long) s->n, (double)len);
|
||||
|
||||
k = MIN(len, s->n);
|
||||
/* cast is to make s->n signed; it should always be reasonably
|
||||
* small */
|
||||
k = MIN(len, (OFF_T) s->n);
|
||||
|
||||
map = (schar *)map_ptr(buf,0,k);
|
||||
|
||||
@@ -158,8 +173,8 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
end = len + 1 - s->sums[s->count-1].len;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"hash search s->n=%d len=%.0f count=%d\n",
|
||||
s->n,(double)len,s->count);
|
||||
rprintf(FINFO, "hash search s->n=%ld len=%.0f count=%ld\n",
|
||||
(long) s->n, (double) len, (long) s->count);
|
||||
|
||||
do {
|
||||
tag t = gettag2(s1,s2);
|
||||
@@ -258,7 +273,21 @@ static void hash_search(int f,struct sum_struct *s,
|
||||
}
|
||||
|
||||
|
||||
void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
|
||||
/**
|
||||
* Scan through a origin file, looking for sections that match
|
||||
* checksums from the generator, and transmit either literal or token
|
||||
* data.
|
||||
*
|
||||
* Also calculates the MD4 checksum of the whole file, using the md
|
||||
* accumulator. This is transmitted with the file as protection
|
||||
* against corruption on the wire.
|
||||
*
|
||||
* @param s Checksums received from the generator. If <tt>s->count ==
|
||||
* 0</tt>, then there are actually no checksums for this file.
|
||||
*
|
||||
* @param len Length of the file to send.
|
||||
**/
|
||||
void match_sums(int f, struct sum_struct *s, struct map_struct *buf, OFF_T len)
|
||||
{
|
||||
char file_sum[MD4_SUM_LENGTH];
|
||||
extern int write_batch; /* dw */
|
||||
|
||||
321
options.c
321
options.c
@@ -1,28 +1,40 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1998-2001 by Andrew Tridgell <tridge@samba.org>
|
||||
* Copyright (C) 2000, 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
#include "popt.h"
|
||||
|
||||
int make_backups = 0;
|
||||
int whole_file = -1;
|
||||
|
||||
/**
|
||||
* If True, send the whole file as literal data rather than trying to
|
||||
* create an incremental diff.
|
||||
*
|
||||
* If both are 0, then look at whether we're local or remote and go by
|
||||
* that.
|
||||
*
|
||||
* @sa disable_deltas_p()
|
||||
**/
|
||||
int whole_file = 0;
|
||||
int no_whole_file = 0;
|
||||
|
||||
int copy_links = 0;
|
||||
int preserve_links = 0;
|
||||
int preserve_hard_links = 0;
|
||||
@@ -54,7 +66,8 @@ int module_id = -1;
|
||||
int am_server = 0;
|
||||
int am_sender = 0;
|
||||
int recurse = 0;
|
||||
int am_daemon=0;
|
||||
int am_daemon = 0;
|
||||
int daemon_over_rsh = 0;
|
||||
int do_stats=0;
|
||||
int do_progress=0;
|
||||
int keep_partial=0;
|
||||
@@ -68,13 +81,10 @@ int only_existing=0;
|
||||
int opt_ignore_existing=0;
|
||||
int max_delete=0;
|
||||
int ignore_errors=0;
|
||||
#ifdef _WIN32
|
||||
int modify_window=2;
|
||||
#else
|
||||
int modify_window=0;
|
||||
#endif
|
||||
int blocking_io=-1;
|
||||
|
||||
|
||||
/** Network address family. **/
|
||||
#ifdef INET6
|
||||
int default_af_hint = 0; /* Any protocol */
|
||||
@@ -89,17 +99,19 @@ int no_detach = 0;
|
||||
|
||||
int write_batch = 0;
|
||||
int read_batch = 0;
|
||||
int suffix_specified = 0;
|
||||
|
||||
char *backup_suffix = BACKUP_SUFFIX;
|
||||
char *tmpdir = NULL;
|
||||
char *compare_dest = NULL;
|
||||
char *config_file = RSYNCD_CONF;
|
||||
char *config_file = NULL;
|
||||
char *shell_cmd = NULL;
|
||||
char *log_format = NULL;
|
||||
char *password_file = NULL;
|
||||
char *rsync_path = RSYNC_PATH;
|
||||
char *backup_dir = NULL;
|
||||
int rsync_port = RSYNC_PORT;
|
||||
int link_dest = 0;
|
||||
|
||||
int verbose = 0;
|
||||
int quiet = 0;
|
||||
@@ -146,20 +158,32 @@ static void print_rsync_version(enum logcode f)
|
||||
"Copyright (C) 1996-2002 by Andrew Tridgell and others\n");
|
||||
rprintf(f, "<http://rsync.samba.org/>\n");
|
||||
rprintf(f, "Capabilities: %d-bit files, %ssocketpairs, "
|
||||
"%shard links, %ssymlinks, batchfiles, %sIPv6,\n",
|
||||
"%shard links, %ssymlinks, batchfiles, \n",
|
||||
(int) (sizeof(OFF_T) * 8),
|
||||
got_socketpair, hardlinks, links, ipv6);
|
||||
got_socketpair, hardlinks, links);
|
||||
|
||||
/* Note that this field may not have type ino_t. It depends
|
||||
* on the complicated interaction between largefile feature
|
||||
* macros. */
|
||||
rprintf(f, " %d-bit system inums, %d-bit internal inums\n",
|
||||
rprintf(f, " %sIPv6, %d-bit system inums, %d-bit internal inums\n",
|
||||
ipv6,
|
||||
(int) (sizeof(dumstat->st_ino) * 8),
|
||||
(int) (sizeof(INO64_T) * 8));
|
||||
#ifdef MAINTAINER_MODE
|
||||
rprintf(f, " panic action: \"%s\"\n",
|
||||
get_panic_action());
|
||||
#endif
|
||||
|
||||
#ifdef NO_INT64
|
||||
rprintf(f, "WARNING: no 64-bit integers on this platform!\n");
|
||||
#endif
|
||||
|
||||
rprintf(f,
|
||||
"\n"
|
||||
"rsync comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n"
|
||||
"are welcome to redistribute it under certain conditions. See the GNU\n"
|
||||
"General Public Licence for details.\n"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +191,7 @@ void usage(enum logcode F)
|
||||
{
|
||||
print_rsync_version(F);
|
||||
|
||||
rprintf(F,"rsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
|
||||
rprintf(F,"\nrsync is a file transfer program capable of efficient remote update\nvia a fast differencing algorithm.\n\n");
|
||||
|
||||
rprintf(F,"Usage: rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST:SRC DEST\n");
|
||||
@@ -175,6 +199,7 @@ void usage(enum logcode F)
|
||||
rprintf(F," or rsync [OPTION]... [USER@]HOST::SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST\n");
|
||||
rprintf(F," or rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]\n");
|
||||
rprintf(F," or rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST\n");
|
||||
rprintf(F,"SRC on single-colon remote HOST will be expanded by remote shell\n");
|
||||
rprintf(F,"SRC on server remote HOST may contain shell wildcards or multiple\n");
|
||||
rprintf(F," sources separated by space as long as they have same top-level\n");
|
||||
@@ -182,7 +207,7 @@ void usage(enum logcode F)
|
||||
rprintf(F," -v, --verbose increase verbosity\n");
|
||||
rprintf(F," -q, --quiet decrease verbosity\n");
|
||||
rprintf(F," -c, --checksum always checksum\n");
|
||||
rprintf(F," -a, --archive archive mode\n");
|
||||
rprintf(F," -a, --archive archive mode, equivalent to -rlptgoD\n");
|
||||
rprintf(F," -r, --recursive recurse into directories\n");
|
||||
rprintf(F," -R, --relative use relative path names\n");
|
||||
rprintf(F," -b, --backup make backups (default %s suffix)\n",BACKUP_SUFFIX);
|
||||
@@ -205,7 +230,7 @@ void usage(enum logcode F)
|
||||
rprintf(F," --no-whole-file turn off --whole-file\n");
|
||||
rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
|
||||
rprintf(F," -B, --block-size=SIZE checksum blocking size (default %d)\n",BLOCK_SIZE);
|
||||
rprintf(F," -e, --rsh=COMMAND specify rsh replacement\n");
|
||||
rprintf(F," -e, --rsh=COMMAND specify the remote shell\n");
|
||||
rprintf(F," --rsync-path=PATH specify path to rsync on the remote machine\n");
|
||||
rprintf(F," -C, --cvs-exclude auto ignore files in the same way CVS does\n");
|
||||
rprintf(F," --existing only update files that already exist\n");
|
||||
@@ -261,99 +286,102 @@ enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
|
||||
OPT_EXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS,
|
||||
OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT,
|
||||
OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
|
||||
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
|
||||
OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST, OPT_LINK_DEST,
|
||||
OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
|
||||
OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR,
|
||||
OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
|
||||
OPT_NO_BLOCKING_IO, OPT_NO_WHOLE_FILE,
|
||||
OPT_NO_BLOCKING_IO, OPT_WHOLE_FILE, OPT_NO_WHOLE_FILE,
|
||||
OPT_MODIFY_WINDOW, OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_IGNORE_EXISTING};
|
||||
|
||||
static struct poptOption long_options[] = {
|
||||
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
|
||||
{"version", 0, POPT_ARG_NONE, 0, OPT_VERSION},
|
||||
{"suffix", 0, POPT_ARG_STRING, &backup_suffix},
|
||||
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path},
|
||||
{"password-file", 0, POPT_ARG_STRING, &password_file},
|
||||
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times},
|
||||
{"size-only", 0, POPT_ARG_NONE, &size_only},
|
||||
{"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW},
|
||||
{"one-file-system", 'x', POPT_ARG_NONE, &one_file_system},
|
||||
{"delete", 0, POPT_ARG_NONE, &delete_mode},
|
||||
{"existing", 0, POPT_ARG_NONE, &only_existing},
|
||||
{"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing},
|
||||
{"delete-after", 0, POPT_ARG_NONE, &delete_after},
|
||||
{"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED},
|
||||
{"force", 0, POPT_ARG_NONE, &force_delete},
|
||||
{"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids},
|
||||
{"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE},
|
||||
{"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE},
|
||||
{"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM},
|
||||
{"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM},
|
||||
{"safe-links", 0, POPT_ARG_NONE, &safe_symlinks},
|
||||
{"help", 'h', POPT_ARG_NONE, 0, 'h'},
|
||||
{"backup", 'b', POPT_ARG_NONE, &make_backups},
|
||||
{"dry-run", 'n', POPT_ARG_NONE, &dry_run},
|
||||
{"sparse", 'S', POPT_ARG_NONE, &sparse_files},
|
||||
{"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude},
|
||||
{"update", 'u', POPT_ARG_NONE, &update_only},
|
||||
{"links", 'l', POPT_ARG_NONE, &preserve_links},
|
||||
{"copy-links", 'L', POPT_ARG_NONE, ©_links},
|
||||
{"whole-file", 'W', POPT_ARG_NONE, &whole_file},
|
||||
{"no-whole-file", 0, POPT_ARG_NONE, 0, OPT_NO_WHOLE_FILE},
|
||||
{"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links},
|
||||
{"perms", 'p', POPT_ARG_NONE, &preserve_perms},
|
||||
{"owner", 'o', POPT_ARG_NONE, &preserve_uid},
|
||||
{"group", 'g', POPT_ARG_NONE, &preserve_gid},
|
||||
{"devices", 'D', POPT_ARG_NONE, &preserve_devices},
|
||||
{"times", 't', POPT_ARG_NONE, &preserve_times},
|
||||
{"checksum", 'c', POPT_ARG_NONE, &always_checksum},
|
||||
{"verbose", 'v', POPT_ARG_NONE, 0, 'v'},
|
||||
{"quiet", 'q', POPT_ARG_NONE, 0, 'q'},
|
||||
{"archive", 'a', POPT_ARG_NONE, 0, 'a'},
|
||||
{"server", 0, POPT_ARG_NONE, &am_server},
|
||||
{"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER},
|
||||
{"recursive", 'r', POPT_ARG_NONE, &recurse},
|
||||
{"relative", 'R', POPT_ARG_NONE, &relative_paths},
|
||||
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd},
|
||||
{"block-size", 'B', POPT_ARG_INT, &block_size},
|
||||
{"max-delete", 0, POPT_ARG_INT, &max_delete},
|
||||
{"timeout", 0, POPT_ARG_INT, &io_timeout},
|
||||
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir},
|
||||
{"compare-dest", 0, POPT_ARG_STRING, &compare_dest},
|
||||
{"version", 0, POPT_ARG_NONE, 0, OPT_VERSION, 0, 0},
|
||||
{"suffix", 0, POPT_ARG_STRING, &backup_suffix, OPT_SUFFIX, 0, 0 },
|
||||
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
|
||||
{"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
|
||||
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times , 0, 0, 0 },
|
||||
{"size-only", 0, POPT_ARG_NONE, &size_only , 0, 0, 0 },
|
||||
{"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
|
||||
{"one-file-system", 'x', POPT_ARG_NONE, &one_file_system , 0, 0, 0 },
|
||||
{"delete", 0, POPT_ARG_NONE, &delete_mode , 0, 0, 0 },
|
||||
{"existing", 0, POPT_ARG_NONE, &only_existing , 0, 0, 0 },
|
||||
{"ignore-existing", 0, POPT_ARG_NONE, &opt_ignore_existing , 0, 0, 0 },
|
||||
{"delete-after", 0, POPT_ARG_NONE, 0, OPT_DELETE_AFTER, 0, 0 },
|
||||
{"delete-excluded", 0, POPT_ARG_NONE, 0, OPT_DELETE_EXCLUDED, 0, 0 },
|
||||
{"force", 0, POPT_ARG_NONE, &force_delete , 0, 0, 0 },
|
||||
{"numeric-ids", 0, POPT_ARG_NONE, &numeric_ids , 0, 0, 0 },
|
||||
{"exclude", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE, 0, 0 },
|
||||
{"include", 0, POPT_ARG_STRING, 0, OPT_INCLUDE, 0, 0 },
|
||||
{"exclude-from", 0, POPT_ARG_STRING, 0, OPT_EXCLUDE_FROM, 0, 0 },
|
||||
{"include-from", 0, POPT_ARG_STRING, 0, OPT_INCLUDE_FROM, 0, 0 },
|
||||
{"safe-links", 0, POPT_ARG_NONE, &safe_symlinks , 0, 0, 0 },
|
||||
{"help", 'h', POPT_ARG_NONE, 0, 'h', 0, 0 },
|
||||
{"backup", 'b', POPT_ARG_NONE, &make_backups , 0, 0, 0 },
|
||||
{"dry-run", 'n', POPT_ARG_NONE, &dry_run , 0, 0, 0 },
|
||||
{"sparse", 'S', POPT_ARG_NONE, &sparse_files , 0, 0, 0 },
|
||||
{"cvs-exclude", 'C', POPT_ARG_NONE, &cvs_exclude , 0, 0, 0 },
|
||||
{"update", 'u', POPT_ARG_NONE, &update_only , 0, 0, 0 },
|
||||
{"links", 'l', POPT_ARG_NONE, &preserve_links , 0, 0, 0 },
|
||||
{"copy-links", 'L', POPT_ARG_NONE, ©_links , 0, 0, 0 },
|
||||
{"whole-file", 'W', POPT_ARG_NONE, 0, OPT_WHOLE_FILE, 0, 0 },
|
||||
{"no-whole-file", 0, POPT_ARG_NONE, 0, OPT_NO_WHOLE_FILE, 0, 0 },
|
||||
{"copy-unsafe-links", 0, POPT_ARG_NONE, ©_unsafe_links , 0, 0, 0 },
|
||||
{"perms", 'p', POPT_ARG_NONE, &preserve_perms , 0, 0, 0 },
|
||||
{"owner", 'o', POPT_ARG_NONE, &preserve_uid , 0, 0, 0 },
|
||||
{"group", 'g', POPT_ARG_NONE, &preserve_gid , 0, 0, 0 },
|
||||
{"devices", 'D', POPT_ARG_NONE, &preserve_devices , 0, 0, 0 },
|
||||
{"times", 't', POPT_ARG_NONE, &preserve_times , 0, 0, 0 },
|
||||
{"checksum", 'c', POPT_ARG_NONE, &always_checksum , 0, 0, 0 },
|
||||
{"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
|
||||
{"quiet", 'q', POPT_ARG_NONE, 0, 'q', 0, 0 },
|
||||
{"archive", 'a', POPT_ARG_NONE, 0, 'a', 0, 0 },
|
||||
{"server", 0, POPT_ARG_NONE, &am_server , 0, 0, 0 },
|
||||
{"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
|
||||
{"recursive", 'r', POPT_ARG_NONE, &recurse , 0, 0, 0 },
|
||||
{"relative", 'R', POPT_ARG_NONE, &relative_paths , 0, 0, 0 },
|
||||
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd , 0, 0, 0 },
|
||||
{"block-size", 'B', POPT_ARG_INT, &block_size , 0, 0, 0 },
|
||||
{"max-delete", 0, POPT_ARG_INT, &max_delete , 0, 0, 0 },
|
||||
{"timeout", 0, POPT_ARG_INT, &io_timeout , 0, 0, 0 },
|
||||
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir , 0, 0, 0 },
|
||||
{"compare-dest", 0, POPT_ARG_STRING, &compare_dest , 0, 0, 0 },
|
||||
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
|
||||
/* TODO: Should this take an optional int giving the compression level? */
|
||||
{"compress", 'z', POPT_ARG_NONE, &do_compression},
|
||||
{"daemon", 0, POPT_ARG_NONE, &am_daemon},
|
||||
{"no-detach", 0, POPT_ARG_NONE, &no_detach},
|
||||
{"stats", 0, POPT_ARG_NONE, &do_stats},
|
||||
{"progress", 0, POPT_ARG_NONE, &do_progress},
|
||||
{"partial", 0, POPT_ARG_NONE, &keep_partial},
|
||||
{"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors},
|
||||
{"blocking-io", 0, POPT_ARG_NONE, &blocking_io},
|
||||
{"no-blocking-io", 0, POPT_ARG_NONE, 0, OPT_NO_BLOCKING_IO},
|
||||
{0, 'P', POPT_ARG_NONE, 0, 'P'},
|
||||
{"config", 0, POPT_ARG_STRING, &config_file},
|
||||
{"port", 0, POPT_ARG_INT, &rsync_port},
|
||||
{"log-format", 0, POPT_ARG_STRING, &log_format},
|
||||
{"bwlimit", 0, POPT_ARG_INT, &bwlimit},
|
||||
{"address", 0, POPT_ARG_STRING, &bind_address, 0},
|
||||
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir},
|
||||
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links},
|
||||
{"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH},
|
||||
{"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH},
|
||||
{"compress", 'z', POPT_ARG_NONE, &do_compression , 0, 0, 0 },
|
||||
{"daemon", 0, POPT_ARG_NONE, &am_daemon , 0, 0, 0 },
|
||||
{"no-detach", 0, POPT_ARG_NONE, &no_detach , 0, 0, 0 },
|
||||
{"stats", 0, POPT_ARG_NONE, &do_stats , 0, 0, 0 },
|
||||
{"progress", 0, POPT_ARG_NONE, &do_progress , 0, 0, 0 },
|
||||
{"partial", 0, POPT_ARG_NONE, &keep_partial , 0, 0, 0 },
|
||||
{"ignore-errors", 0, POPT_ARG_NONE, &ignore_errors , 0, 0, 0 },
|
||||
{"blocking-io", 0, POPT_ARG_NONE, &blocking_io , 0, 0, 0 },
|
||||
{"no-blocking-io", 0, POPT_ARG_NONE, 0, OPT_NO_BLOCKING_IO, 0, 0 },
|
||||
{0, 'P', POPT_ARG_NONE, 0, 'P', 0, 0 },
|
||||
{"config", 0, POPT_ARG_STRING, &config_file , 0, 0, 0 },
|
||||
{"port", 0, POPT_ARG_INT, &rsync_port , 0, 0, 0 },
|
||||
{"log-format", 0, POPT_ARG_STRING, &log_format , 0, 0, 0 },
|
||||
{"bwlimit", 0, POPT_ARG_INT, &bwlimit , 0, 0, 0 },
|
||||
{"address", 0, POPT_ARG_STRING, &bind_address, 0, 0, 0 },
|
||||
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir , 0, 0, 0 },
|
||||
{"hard-links", 'H', POPT_ARG_NONE, &preserve_hard_links , 0, 0, 0 },
|
||||
{"read-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_READ_BATCH, 0, 0 },
|
||||
{"write-batch", 0, POPT_ARG_STRING, &batch_prefix, OPT_WRITE_BATCH, 0, 0 },
|
||||
#ifdef INET6
|
||||
{0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET },
|
||||
{0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6 },
|
||||
{0, '4', POPT_ARG_VAL, &default_af_hint, AF_INET , 0, 0 },
|
||||
{0, '6', POPT_ARG_VAL, &default_af_hint, AF_INET6 , 0, 0 },
|
||||
#endif
|
||||
{0,0,0,0}
|
||||
{0,0,0,0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
||||
static char err_buf[100];
|
||||
|
||||
|
||||
/* We store the option error message, if any, so that we can log the
|
||||
connection attempt (which requires parsing the options), and then
|
||||
show the error later on. */
|
||||
/**
|
||||
* Store the option error message, if any, so that we can log the
|
||||
* connection attempt (which requires parsing the options), and then
|
||||
* show the error later on.
|
||||
**/
|
||||
void option_error(void)
|
||||
{
|
||||
if (err_buf[0]) {
|
||||
@@ -367,7 +395,10 @@ void option_error(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* check to see if we should refuse this option */
|
||||
|
||||
/**
|
||||
* Check to see if we should refuse this option
|
||||
**/
|
||||
static int check_refuse_options(char *ref, int opt)
|
||||
{
|
||||
int i, len;
|
||||
@@ -407,9 +438,14 @@ static int count_args(char const **argv)
|
||||
}
|
||||
|
||||
|
||||
/* Process command line arguments. Called on both local and remote.
|
||||
* Returns if all options are OK, otherwise fills in err_buf and
|
||||
* returns 0. */
|
||||
/**
|
||||
* Process command line arguments. Called on both local and remote.
|
||||
*
|
||||
* @retval 1 if all options are OK; with globals set to appropriate
|
||||
* values
|
||||
*
|
||||
* @retval 0 on error, with err_buf containing an explanation
|
||||
**/
|
||||
int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
{
|
||||
int opt;
|
||||
@@ -435,13 +471,25 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
print_rsync_version(FINFO);
|
||||
exit_cleanup(0);
|
||||
|
||||
case OPT_SUFFIX:
|
||||
/* The value has already been set by popt, but
|
||||
* we need to remember that a suffix was specified
|
||||
* in case a backup-directory is used. */
|
||||
suffix_specified = 1;
|
||||
break;
|
||||
|
||||
case OPT_MODIFY_WINDOW:
|
||||
/* The value has already been set by popt, but
|
||||
* we need to remember that we're using a
|
||||
* non-default setting. */
|
||||
modify_window_set = 1;
|
||||
break;
|
||||
|
||||
|
||||
case OPT_DELETE_AFTER:
|
||||
delete_after = 1;
|
||||
delete_mode = 1;
|
||||
break;
|
||||
|
||||
case OPT_DELETE_EXCLUDED:
|
||||
delete_excluded = 1;
|
||||
delete_mode = 1;
|
||||
@@ -463,7 +511,13 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
add_exclude_file(poptGetOptArg(pc), 1, 1);
|
||||
break;
|
||||
|
||||
case OPT_WHOLE_FILE:
|
||||
whole_file = 1;
|
||||
no_whole_file = 0;
|
||||
break;
|
||||
|
||||
case OPT_NO_WHOLE_FILE:
|
||||
no_whole_file = 1;
|
||||
whole_file = 0;
|
||||
break;
|
||||
|
||||
@@ -535,6 +589,19 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
/* popt stores the filename in batch_prefix for us */
|
||||
read_batch = 1;
|
||||
break;
|
||||
case OPT_LINK_DEST:
|
||||
#if HAVE_LINK
|
||||
compare_dest = (char *)poptGetOptArg(pc);
|
||||
link_dest = 1;
|
||||
break;
|
||||
#else
|
||||
snprintf(err_buf,sizeof(err_buf),
|
||||
"hard links are not supported on this %s\n",
|
||||
am_server ? "server" : "client");
|
||||
rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
|
||||
default:
|
||||
/* FIXME: If --daemon is specified, then errors for later
|
||||
@@ -574,8 +641,14 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
|
||||
}
|
||||
|
||||
|
||||
/* Construct a filtered list of options to pass through from the
|
||||
* client to the server */
|
||||
/**
|
||||
* Construct a filtered list of options to pass through from the
|
||||
* client to the server.
|
||||
*
|
||||
* This involves setting options that will tell the server how to
|
||||
* behave, and also filtering out options that are processed only
|
||||
* locally.
|
||||
**/
|
||||
void server_options(char **args,int *argc)
|
||||
{
|
||||
int ac = *argc;
|
||||
@@ -590,13 +663,18 @@ void server_options(char **args,int *argc)
|
||||
|
||||
int i, x;
|
||||
|
||||
if (whole_file == -1)
|
||||
whole_file = 0;
|
||||
if (blocking_io == -1)
|
||||
blocking_io = 0;
|
||||
|
||||
args[ac++] = "--server";
|
||||
|
||||
if (daemon_over_rsh) {
|
||||
args[ac++] = "--daemon";
|
||||
*argc = ac;
|
||||
/* if we're passing --daemon, we're done */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!am_sender)
|
||||
args[ac++] = "--sender";
|
||||
|
||||
@@ -616,8 +694,14 @@ void server_options(char **args,int *argc)
|
||||
argstr[x++] = 'l';
|
||||
if (copy_links)
|
||||
argstr[x++] = 'L';
|
||||
|
||||
assert(whole_file == 0 || whole_file == 1);
|
||||
if (whole_file)
|
||||
argstr[x++] = 'W';
|
||||
/* We don't need to send --no-whole-file, because it's the
|
||||
* default for remote transfers, and in any case old versions
|
||||
* of rsync will not understand it. */
|
||||
|
||||
if (preserve_hard_links)
|
||||
argstr[x++] = 'H';
|
||||
if (preserve_uid)
|
||||
@@ -754,11 +838,10 @@ void server_options(char **args,int *argc)
|
||||
* and it may be an older version that doesn't know this
|
||||
* option, so don't send it if client is the sender.
|
||||
*/
|
||||
args[ac++] = "--compare-dest";
|
||||
args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
|
||||
args[ac++] = compare_dest;
|
||||
}
|
||||
|
||||
|
||||
*argc = ac;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Version: 2.5.6
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.6.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Version: 2.5.6
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.6.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Summary: Program for efficient remote updates of files.
|
||||
Name: rsync
|
||||
Version: 2.5.1
|
||||
Version: 2.5.6
|
||||
Release: 1
|
||||
Copyright: GPL
|
||||
Group: Applications/Networking
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
|
||||
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.6.tar.gz
|
||||
URL: http://samba.anu.edu.au/rsync/
|
||||
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
|
||||
BuildRoot: /tmp/rsync
|
||||
|
||||
94
packaging/solaris/build_pkg.sh
Normal file
94
packaging/solaris/build_pkg.sh
Normal file
@@ -0,0 +1,94 @@
|
||||
#!/bin/sh
|
||||
# Shell script for building Solaris package of rsync
|
||||
# Author: Jens Apel <jens.apel@web.de>
|
||||
# License: GPL
|
||||
#
|
||||
# BASEDIR is /usr/local and should be the same as the
|
||||
# --prefix parameter of configure
|
||||
#
|
||||
# this script should be copied under
|
||||
# packaging/solaris/5.8/build_pkg.sh
|
||||
|
||||
# Definitions start here
|
||||
# you can edit this, if you like
|
||||
|
||||
# The Package name under which rsync will b installed
|
||||
PKGNAME=SMBrsync
|
||||
|
||||
# Extract common info requires for the 'info' part of the package.
|
||||
# This should be made generic and generated by the configure script
|
||||
# but for now it is hard coded
|
||||
BASEDIR=/usr/local
|
||||
VERSION="2.5.5"
|
||||
ARCH=`uname -p`
|
||||
NAME=rsync
|
||||
|
||||
# Definitions end here
|
||||
# Please do not edit below this line or you know what you do.
|
||||
|
||||
## Start by faking root install
|
||||
echo "Creating install directory (fake $BASEDIR)..."
|
||||
START=`pwd`
|
||||
FAKE_ROOT=$START/${PKGNAME}
|
||||
mkdir $FAKE_ROOT
|
||||
|
||||
# copy the binary and the man page to their places
|
||||
mkdir $FAKE_ROOT/bin
|
||||
mkdir -p $FAKE_ROOT/doc/rsync
|
||||
mkdir -p $FAKE_ROOT/man/man1
|
||||
mkdir -p $FAKE_ROOT/man/man5
|
||||
|
||||
cp ../../../rsync $FAKE_ROOT/bin/rsync
|
||||
cp ../../../rsync.1 $FAKE_ROOT/man/man1/rsync.1
|
||||
cp ../../../rsyncd.conf.5 $FAKE_ROOT/man/man5/rsyncd.conf.5
|
||||
cp ../../../README $FAKE_ROOT/doc/rsync/README
|
||||
cp ../../../COPYING $FAKE_ROOT/doc/rsync/COPYING
|
||||
cp ../../../tech_report.pdf $FAKE_ROOT/doc/rsync/tech_report.pdf
|
||||
cp ../../../COPYING $FAKE_ROOT/COPYING
|
||||
|
||||
## Build info file
|
||||
echo "Building pkginfo file..."
|
||||
cat > $FAKE_ROOT/pkginfo << EOF_INFO
|
||||
PKG=$PKGNAME
|
||||
NAME=$NAME
|
||||
DESC="Program for efficient remote updates of files."
|
||||
VENDOR="Samba Team URL: http://samba.anu.edu.au/rsync/"
|
||||
BASEDIR=$BASEDIR
|
||||
ARCH=$ARCH
|
||||
VERSION=$VERSION
|
||||
CATEGORY=application
|
||||
CLASSES=none
|
||||
EOF_INFO
|
||||
|
||||
## Build prototype file
|
||||
cat > $FAKE_ROOT/prototype << EOFPROTO
|
||||
i copyright=COPYING
|
||||
i pkginfo=pkginfo
|
||||
d none bin 0755 bin bin
|
||||
f none bin/rsync 0755 bin bin
|
||||
d none doc 0755 bin bin
|
||||
d none doc/$NAME 0755 bin bin
|
||||
f none doc/$NAME/README 0644 bin bin
|
||||
f none doc/$NAME/COPYING 0644 bin bin
|
||||
f none doc/$NAME/tech_report.pdf 0644 bin bin
|
||||
d none man 0755 bin bin
|
||||
d none man/man1 0755 bin bin
|
||||
f none man/man1/rsync.1 0644 bin bin
|
||||
d none man/man5 0755 bin bin
|
||||
f none man/man5/rsyncd.conf.5 0644 bin bin
|
||||
EOFPROTO
|
||||
|
||||
## And now build the package.
|
||||
OUTPUTFILE=$PKGNAME-$VERSION-sol8-$ARCH-local.pkg
|
||||
echo "Building package.."
|
||||
echo FAKE_ROOT = $FAKE_ROOT
|
||||
cd $FAKE_ROOT
|
||||
pkgmk -d . -r . -f ./prototype -o
|
||||
pkgtrans -os . $OUTPUTFILE $PKGNAME
|
||||
|
||||
mv $OUTPUTFILE ..
|
||||
cd ..
|
||||
|
||||
# Comment this out if you want to see, which file structure has been created
|
||||
rm -rf $FAKE_ROOT
|
||||
|
||||
8
params.c
8
params.c
@@ -164,7 +164,7 @@ static int Continuation( char *line, int pos )
|
||||
*/
|
||||
{
|
||||
pos--;
|
||||
while( (pos >= 0) && isspace(line[pos]) )
|
||||
while( (pos >= 0) && isspace(((unsigned char *)line)[pos]) )
|
||||
pos--;
|
||||
|
||||
return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
|
||||
@@ -386,7 +386,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
|
||||
c = 0;
|
||||
else
|
||||
{
|
||||
for( end = i; (end >= 0) && isspace(bufr[end]); end-- )
|
||||
for( end = i; (end >= 0) && isspace(((unsigned char *) bufr)[end]); end-- )
|
||||
;
|
||||
c = getc( InFile );
|
||||
}
|
||||
@@ -491,8 +491,8 @@ static FILE *OpenConfFile( char *FileName )
|
||||
OpenedFile = fopen( FileName, "r" );
|
||||
if( NULL == OpenedFile )
|
||||
{
|
||||
rprintf(FERROR,"%s Unable to open configuration file \"%s\":\n\t%s\n",
|
||||
func, FileName, strerror(errno));
|
||||
rprintf(FERROR,"rsync: unable to open configuration file \"%s\": %s\n",
|
||||
FileName, strerror(errno));
|
||||
}
|
||||
|
||||
return( OpenedFile );
|
||||
|
||||
148
pipe.c
Normal file
148
pipe.c
Normal file
@@ -0,0 +1,148 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* Create a child connected to use on stdin/stdout.
|
||||
*
|
||||
* This is derived from CVS code
|
||||
*
|
||||
* Note that in the child STDIN is set to blocking and STDOUT
|
||||
* is set to non-blocking. This is necessary as rsh relies on stdin being blocking
|
||||
* and ssh relies on stdout being non-blocking
|
||||
*
|
||||
* If blocking_io is set then use blocking io on both fds. That can be
|
||||
* used to cope with badly broken rsh implementations like the one on
|
||||
* Solaris.
|
||||
**/
|
||||
pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int blocking_io;
|
||||
|
||||
if (verbose >= 2) {
|
||||
print_child_argv(command);
|
||||
}
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR, "pipe: %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR, "fork: %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int orig_umask;
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR, "Failed to dup/close : %s\n",
|
||||
strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO)
|
||||
close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO)
|
||||
close(from_child_pipe[1]);
|
||||
umask(orig_umask);
|
||||
set_blocking(STDIN_FILENO);
|
||||
if (blocking_io) {
|
||||
set_blocking(STDOUT_FILENO);
|
||||
}
|
||||
execvp(command[0], command);
|
||||
rprintf(FERROR, "Failed to exec %s : %s\n",
|
||||
command[0], strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR, "Failed to close : %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
pid_t local_child(int argc, char **argv,int *f_in,int *f_out,
|
||||
int (*child_main)(int, char*[]))
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int read_batch; /* dw */
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 ||
|
||||
fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR,"pipe: %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR,"fork: %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
|
||||
am_sender = read_batch ? 0 : !am_sender;
|
||||
am_server = 1;
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
|
||||
child_main(argc, argv);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
1.3 ->
|
||||
1.5 -> 1.6
|
||||
- add ability to perform callbacks for every, not just first, match.
|
||||
|
||||
1.3 -> 1.5
|
||||
- heavy dose of const's
|
||||
- poptParseArgvString() now NULL terminates the list
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ to getopt(3), it contains a number of enhancements, including:
|
||||
2) popt can parse arbitrary argv[] style arrays while
|
||||
getopt(2) makes this quite difficult
|
||||
3) popt allows users to alias command line arguments
|
||||
4) popt provides convience functions for parsting strings
|
||||
4) popt provides convience functions for parsing strings
|
||||
into argv[] style arrays
|
||||
|
||||
popt is used by rpm, the Red Hat install program, and many other Red Hat
|
||||
|
||||
4
popt/README.rsync
Normal file
4
popt/README.rsync
Normal file
@@ -0,0 +1,4 @@
|
||||
This is a perfectly ordinary copy of libpopt. It is only used on platforms
|
||||
that do not have a sufficiently up-to-date copy of their own. If you build
|
||||
rsync on a platform which has popt, this directory should not be used. (You
|
||||
can control that using the --with-included-popt configure flag.)
|
||||
@@ -1,6 +1,10 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/findme.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
#include "findme.h"
|
||||
@@ -9,38 +13,38 @@ const char * findProgramPath(const char * argv0) {
|
||||
char * path = getenv("PATH");
|
||||
char * pathbuf;
|
||||
char * start, * chptr;
|
||||
char * buf, *local = NULL;
|
||||
char * buf;
|
||||
|
||||
/* If there is a / in the argv[0], it has to be an absolute
|
||||
path */
|
||||
if (argv0 == NULL) return NULL; /* XXX can't happen */
|
||||
/* If there is a / in the argv[0], it has to be an absolute path */
|
||||
if (strchr(argv0, '/'))
|
||||
return xstrdup(argv0);
|
||||
|
||||
if (!path) return NULL;
|
||||
if (path == NULL) return NULL;
|
||||
|
||||
local = start = pathbuf = malloc(strlen(path) + 1);
|
||||
buf = malloc(strlen(path) + strlen(argv0) + 2);
|
||||
start = pathbuf = alloca(strlen(path) + 1);
|
||||
buf = malloc(strlen(path) + strlen(argv0) + sizeof("/"));
|
||||
if (buf == NULL) return NULL; /* XXX can't happen */
|
||||
strcpy(pathbuf, path);
|
||||
|
||||
chptr = NULL;
|
||||
/*@-branchstate@*/
|
||||
do {
|
||||
if ((chptr = strchr(start, ':')))
|
||||
*chptr = '\0';
|
||||
sprintf(buf, "%s/%s", start, argv0);
|
||||
|
||||
if (!access(buf, X_OK)) {
|
||||
if (local) free(local);
|
||||
return buf;
|
||||
}
|
||||
if (!access(buf, X_OK))
|
||||
return buf;
|
||||
|
||||
if (chptr)
|
||||
start = chptr + 1;
|
||||
else
|
||||
start = NULL;
|
||||
} while (start && *start);
|
||||
/*@=branchstate@*/
|
||||
|
||||
free(buf);
|
||||
if (local) free(local);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/findme.h
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#ifndef H_FINDME
|
||||
#define H_FINDME
|
||||
|
||||
const char * findProgramPath(const char * argv0);
|
||||
/**
|
||||
* Return absolute path to executable by searching PATH.
|
||||
* @param argv0 name of executable
|
||||
* @return (malloc'd) absolute path to executable (or NULL)
|
||||
*/
|
||||
/*@null@*/ const char * findProgramPath(/*@null@*/ const char * argv0)
|
||||
/*@*/;
|
||||
|
||||
#endif
|
||||
|
||||
1055
popt/popt.c
1055
popt/popt.c
File diff suppressed because it is too large
Load Diff
480
popt/popt.h
480
popt/popt.h
@@ -1,128 +1,444 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \file popt/popt.h
|
||||
* \ingroup popt
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#ifndef H_POPT
|
||||
#define H_POPT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h> /* for FILE * */
|
||||
|
||||
#define POPT_OPTION_DEPTH 10
|
||||
|
||||
#define POPT_ARG_NONE 0
|
||||
#define POPT_ARG_STRING 1
|
||||
#define POPT_ARG_INT 2
|
||||
#define POPT_ARG_LONG 3
|
||||
#define POPT_ARG_INCLUDE_TABLE 4 /* arg points to table */
|
||||
#define POPT_ARG_CALLBACK 5 /* table-wide callback... must be
|
||||
/** \ingroup popt
|
||||
* \name Arg type identifiers
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_ARG_NONE 0 /*!< no arg */
|
||||
#define POPT_ARG_STRING 1 /*!< arg will be saved as string */
|
||||
#define POPT_ARG_INT 2 /*!< arg will be converted to int */
|
||||
#define POPT_ARG_LONG 3 /*!< arg will be converted to long */
|
||||
#define POPT_ARG_INCLUDE_TABLE 4 /*!< arg points to table */
|
||||
#define POPT_ARG_CALLBACK 5 /*!< table-wide callback... must be
|
||||
set first in table; arg points
|
||||
to callback, descrip points to
|
||||
callback data to pass */
|
||||
#define POPT_ARG_INTL_DOMAIN 6 /* set the translation domain
|
||||
#define POPT_ARG_INTL_DOMAIN 6 /*!< set the translation domain
|
||||
for this table and any
|
||||
included tables; arg points
|
||||
to the domain string */
|
||||
#define POPT_ARG_VAL 7 /* arg should take value val */
|
||||
#define POPT_ARG_VAL 7 /*!< arg should take value val */
|
||||
#define POPT_ARG_FLOAT 8 /*!< arg will be converted to float */
|
||||
#define POPT_ARG_DOUBLE 9 /*!< arg will be converted to double */
|
||||
|
||||
#define POPT_ARG_MASK 0x0000FFFF
|
||||
#define POPT_ARGFLAG_ONEDASH 0x80000000 /* allow -longoption */
|
||||
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /* don't show in help/usage */
|
||||
#define POPT_ARGFLAG_STRIP 0x20000000 /* strip this arg from argv (only applies to long args) */
|
||||
#define POPT_CBFLAG_PRE 0x80000000 /* call the callback before parse */
|
||||
#define POPT_CBFLAG_POST 0x40000000 /* call the callback after parse */
|
||||
#define POPT_CBFLAG_INC_DATA 0x20000000 /* use data from the include line,
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
* \name Arg modifiers
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_ARGFLAG_ONEDASH 0x80000000 /*!< allow -longoption */
|
||||
#define POPT_ARGFLAG_DOC_HIDDEN 0x40000000 /*!< don't show in help/usage */
|
||||
#define POPT_ARGFLAG_STRIP 0x20000000 /*!< strip this arg from argv(only applies to long args) */
|
||||
#define POPT_ARGFLAG_OPTIONAL 0x10000000 /*!< arg may be missing */
|
||||
|
||||
#define POPT_ARGFLAG_OR 0x08000000 /*!< arg will be or'ed */
|
||||
#define POPT_ARGFLAG_NOR 0x09000000 /*!< arg will be nor'ed */
|
||||
#define POPT_ARGFLAG_AND 0x04000000 /*!< arg will be and'ed */
|
||||
#define POPT_ARGFLAG_NAND 0x05000000 /*!< arg will be nand'ed */
|
||||
#define POPT_ARGFLAG_XOR 0x02000000 /*!< arg will be xor'ed */
|
||||
#define POPT_ARGFLAG_NOT 0x01000000 /*!< arg will be negated */
|
||||
#define POPT_ARGFLAG_LOGICALOPS \
|
||||
(POPT_ARGFLAG_OR|POPT_ARGFLAG_AND|POPT_ARGFLAG_XOR)
|
||||
|
||||
#define POPT_BIT_SET (POPT_ARG_VAL|POPT_ARGFLAG_OR)
|
||||
/*!< set arg bit(s) */
|
||||
#define POPT_BIT_CLR (POPT_ARG_VAL|POPT_ARGFLAG_NAND)
|
||||
/*!< clear arg bit(s) */
|
||||
|
||||
#define POPT_ARGFLAG_SHOW_DEFAULT 0x00800000 /*!< show default value in --help */
|
||||
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
* \name Callback modifiers
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_CBFLAG_PRE 0x80000000 /*!< call the callback before parse */
|
||||
#define POPT_CBFLAG_POST 0x40000000 /*!< call the callback after parse */
|
||||
#define POPT_CBFLAG_INC_DATA 0x20000000 /*!< use data from the include line,
|
||||
not the subtable */
|
||||
#define POPT_CBFLAG_SKIPOPTION 0x10000000 /*!< don't callback with option */
|
||||
#define POPT_CBFLAG_CONTINUE 0x08000000 /*!< continue callbacks with option */
|
||||
/*@}*/
|
||||
|
||||
#define POPT_ERROR_NOARG -10
|
||||
#define POPT_ERROR_BADOPT -11
|
||||
#define POPT_ERROR_OPTSTOODEEP -13
|
||||
#define POPT_ERROR_BADQUOTE -15 /* only from poptParseArgString() */
|
||||
#define POPT_ERROR_ERRNO -16 /* only from poptParseArgString() */
|
||||
#define POPT_ERROR_BADNUMBER -17
|
||||
#define POPT_ERROR_OVERFLOW -18
|
||||
/** \ingroup popt
|
||||
* \name Error return values
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_ERROR_NOARG -10 /*!< missing argument */
|
||||
#define POPT_ERROR_BADOPT -11 /*!< unknown option */
|
||||
#define POPT_ERROR_OPTSTOODEEP -13 /*!< aliases nested too deeply */
|
||||
#define POPT_ERROR_BADQUOTE -15 /*!< error in paramter quoting */
|
||||
#define POPT_ERROR_ERRNO -16 /*!< errno set, use strerror(errno) */
|
||||
#define POPT_ERROR_BADNUMBER -17 /*!< invalid numeric value */
|
||||
#define POPT_ERROR_OVERFLOW -18 /*!< number too large or too small */
|
||||
#define POPT_ERROR_BADOPERATION -19 /*!< mutually exclusive logical operations requested */
|
||||
#define POPT_ERROR_NULLARG -20 /*!< opt->arg should not be NULL */
|
||||
#define POPT_ERROR_MALLOC -21 /*!< memory allocation failed */
|
||||
/*@}*/
|
||||
|
||||
/* poptBadOption() flags */
|
||||
#define POPT_BADOPTION_NOALIAS (1 << 0) /* don't go into an alias */
|
||||
/** \ingroup popt
|
||||
* \name poptBadOption() flags
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_BADOPTION_NOALIAS (1 << 0) /*!< don't go into an alias */
|
||||
/*@}*/
|
||||
|
||||
/* poptGetContext() flags */
|
||||
#define POPT_CONTEXT_NO_EXEC (1 << 0) /* ignore exec expansions */
|
||||
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /* pay attention to argv[0] */
|
||||
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /* options can't follow args */
|
||||
/** \ingroup popt
|
||||
* \name poptGetContext() flags
|
||||
*/
|
||||
/*@{*/
|
||||
#define POPT_CONTEXT_NO_EXEC (1 << 0) /*!< ignore exec expansions */
|
||||
#define POPT_CONTEXT_KEEP_FIRST (1 << 1) /*!< pay attention to argv[0] */
|
||||
#define POPT_CONTEXT_POSIXMEHARDER (1 << 2) /*!< options can't follow args */
|
||||
#define POPT_CONTEXT_ARG_OPTS (1 << 4) /*!< return args as options with value 0 */
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
*/
|
||||
struct poptOption {
|
||||
/*@observer@*/ /*@null@*/ const char * longName; /* may be NULL */
|
||||
char shortName; /* may be '\0' */
|
||||
/*@observer@*/ /*@null@*/ const char * longName; /*!< may be NULL */
|
||||
char shortName; /*!< may be '\0' */
|
||||
int argInfo;
|
||||
/*@shared@*/ /*@null@*/ void * arg; /* depends on argInfo */
|
||||
int val; /* 0 means don't return, just update flag */
|
||||
/*@shared@*/ /*@null@*/ const char * descrip; /* description for autohelp -- may be NULL */
|
||||
/*@shared@*/ /*@null@*/ const char * argDescrip; /* argument description for autohelp */
|
||||
/*@shared@*/ /*@null@*/ void * arg; /*!< depends on argInfo */
|
||||
int val; /*!< 0 means don't return, just update flag */
|
||||
/*@observer@*/ /*@null@*/ const char * descrip; /*!< description for autohelp -- may be NULL */
|
||||
/*@observer@*/ /*@null@*/ const char * argDescrip; /*!< argument description for autohelp */
|
||||
};
|
||||
|
||||
/** \ingroup popt
|
||||
* A popt alias argument for poptAddAlias().
|
||||
*/
|
||||
struct poptAlias {
|
||||
/*@owned@*/ /*@null@*/ const char * longName; /* may be NULL */
|
||||
char shortName; /* may be '\0' */
|
||||
/*@owned@*/ /*@null@*/ const char * longName; /*!< may be NULL */
|
||||
char shortName; /*!< may be '\0' */
|
||||
int argc;
|
||||
/*@owned@*/ const char ** argv; /* must be free()able */
|
||||
/*@owned@*/ const char ** argv; /*!< must be free()able */
|
||||
};
|
||||
|
||||
/** \ingroup popt
|
||||
* A popt alias or exec argument for poptAddItem().
|
||||
*/
|
||||
typedef struct poptItem_s {
|
||||
struct poptOption option; /*!< alias/exec name(s) and description. */
|
||||
int argc; /*!< (alias) no. of args. */
|
||||
/*@owned@*/ const char ** argv; /*!< (alias) args, must be free()able. */
|
||||
} * poptItem;
|
||||
|
||||
/** \ingroup popt
|
||||
* \name Auto-generated help/usage
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* Empty table marker to enable displaying popt alias/exec options.
|
||||
*/
|
||||
/*@observer@*/ /*@checked@*/
|
||||
extern struct poptOption poptAliasOptions[];
|
||||
#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
|
||||
0, "Options implemented via popt alias/exec:", NULL },
|
||||
|
||||
/**
|
||||
* Auto help table options.
|
||||
*/
|
||||
/*@observer@*/ /*@checked@*/
|
||||
extern struct poptOption poptHelpOptions[];
|
||||
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
|
||||
0, "Help options", NULL },
|
||||
0, "Help options:", NULL },
|
||||
|
||||
typedef struct poptContext_s * poptContext;
|
||||
#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL }
|
||||
/*@}*/
|
||||
|
||||
/** \ingroup popt
|
||||
*/
|
||||
typedef /*@abstract@*/ struct poptContext_s * poptContext;
|
||||
|
||||
/** \ingroup popt
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
/*@-typeuse@*/
|
||||
typedef struct poptOption * poptOption;
|
||||
/*@=typeuse@*/
|
||||
#endif
|
||||
|
||||
enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
|
||||
POPT_CALLBACK_REASON_POST,
|
||||
POPT_CALLBACK_REASON_OPTION };
|
||||
typedef void (*poptCallbackType)(poptContext con,
|
||||
enum poptCallbackReason reason,
|
||||
const struct poptOption * opt,
|
||||
const char * arg, const void * data);
|
||||
|
||||
/*@only@*/ poptContext poptGetContext(/*@keep@*/ const char * name,
|
||||
int argc, /*@keep@*/ const char ** argv,
|
||||
/*@keep@*/ const struct poptOption * options, int flags);
|
||||
void poptResetContext(poptContext con);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*@-type@*/
|
||||
|
||||
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
|
||||
int poptGetNextOpt(poptContext con);
|
||||
/* returns NULL if no argument is available */
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetOptArg(poptContext con);
|
||||
/* returns NULL if no more options are available */
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetArg(poptContext con);
|
||||
/*@observer@*/ /*@null@*/ const char * poptPeekArg(poptContext con);
|
||||
/*@observer@*/ /*@null@*/ const char ** poptGetArgs(poptContext con);
|
||||
/* returns the option which caused the most recent error */
|
||||
/*@observer@*/ const char * poptBadOption(poptContext con, int flags);
|
||||
void poptFreeContext( /*@only@*/ poptContext con);
|
||||
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv);
|
||||
int poptAddAlias(poptContext con, struct poptAlias alias, int flags);
|
||||
int poptReadConfigFile(poptContext con, const char * fn);
|
||||
/* like above, but reads /etc/popt and $HOME/.popt along with environment
|
||||
vars */
|
||||
int poptReadDefaultConfig(poptContext con, int useEnv);
|
||||
/* argv should be freed -- this allows ', ", and \ quoting, but ' is treated
|
||||
the same as " and both may include \ quotes */
|
||||
int poptDupArgv(int argc, const char **argv,
|
||||
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr);
|
||||
/** \ingroup popt
|
||||
* Table callback prototype.
|
||||
* @param con context
|
||||
* @param reason reason for callback
|
||||
* @param opt option that triggered callback
|
||||
* @param arg @todo Document.
|
||||
* @param data @todo Document.
|
||||
*/
|
||||
typedef void (*poptCallbackType) (poptContext con,
|
||||
enum poptCallbackReason reason,
|
||||
/*@null@*/ const struct poptOption * opt,
|
||||
/*@null@*/ const char * arg,
|
||||
/*@null@*/ const void * data)
|
||||
/*@*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Initialize popt context.
|
||||
* @param name
|
||||
* @param argc no. of arguments
|
||||
* @param argv argument array
|
||||
* @param options address of popt option table
|
||||
* @param flags or'd POPT_CONTEXT_* bits
|
||||
* @return initialized popt context
|
||||
*/
|
||||
/*@only@*/ /*@null@*/ poptContext poptGetContext(
|
||||
/*@dependent@*/ /*@keep@*/ const char * name,
|
||||
int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
|
||||
/*@dependent@*/ /*@keep@*/ const struct poptOption * options,
|
||||
int flags)
|
||||
/*@*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Reinitialize popt context.
|
||||
* @param con context
|
||||
*/
|
||||
void poptResetContext(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return value of next option found.
|
||||
* @param con context
|
||||
* @return next option val, -1 on last item, POPT_ERROR_* on error
|
||||
*/
|
||||
int poptGetNextOpt(/*@null@*/poptContext con)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies con, fileSystem @*/;
|
||||
|
||||
/*@-redecl@*/
|
||||
/** \ingroup popt
|
||||
* Return next option argument (if any).
|
||||
* @param con context
|
||||
* @return option argument, NULL if no more options are available
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return current option's argument.
|
||||
* @param con context
|
||||
* @return option argument, NULL if no more options are available
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Peek at current option's argument.
|
||||
* @param con context
|
||||
* @return option argument
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con)
|
||||
/*@*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return remaining arguments.
|
||||
* @param con context
|
||||
* @return argument array, terminated with NULL
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return the option which caused the most recent error.
|
||||
* @param con context
|
||||
* @return offending option
|
||||
*/
|
||||
/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags)
|
||||
/*@*/;
|
||||
/*@=redecl@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Destroy context.
|
||||
* @param con context
|
||||
* @return NULL always
|
||||
*/
|
||||
/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Add arguments to context.
|
||||
* @param con context
|
||||
* @param argv argument array, NULL terminated
|
||||
* @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure
|
||||
*/
|
||||
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Add alias to context.
|
||||
* @todo Pass alias by reference, not value.
|
||||
* @deprecated Use poptAddItem instead.
|
||||
* @param con context
|
||||
* @param alias alias to add
|
||||
* @param flags (unused)
|
||||
* @return 0 on success
|
||||
*/
|
||||
/*@unused@*/
|
||||
int poptAddAlias(poptContext con, struct poptAlias alias, int flags)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Add alias/exec item to context.
|
||||
* @param con context
|
||||
* @param item alias/exec item to add
|
||||
* @param flags 0 for alias, 1 for exec
|
||||
* @return 0 on success
|
||||
*/
|
||||
int poptAddItem(poptContext con, poptItem newItem, int flags)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Read configuration file.
|
||||
* @param con context
|
||||
* @param fn file name to read
|
||||
* @return 0 on success, POPT_ERROR_ERRNO on failure
|
||||
*/
|
||||
int poptReadConfigFile(poptContext con, const char * fn)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies fileSystem,
|
||||
con->execs, con->numExecs @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Read default configuration from /etc/popt and $HOME/.popt.
|
||||
* @param con context
|
||||
* @param useEnv (unused)
|
||||
* @return 0 on success, POPT_ERROR_ERRNO on failure
|
||||
*/
|
||||
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies fileSystem,
|
||||
con->execs, con->numExecs @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Duplicate an argument array.
|
||||
* @note: The argument array is malloc'd as a single area, so only argv must
|
||||
* be free'd.
|
||||
*
|
||||
* @param argc no. of arguments
|
||||
* @param argv argument array
|
||||
* @retval argcPtr address of returned no. of arguments
|
||||
* @retval argvPtr address of returned argument array
|
||||
* @return 0 on success, POPT_ERROR_NOARG on failure
|
||||
*/
|
||||
int poptDupArgv(int argc, /*@null@*/ const char **argv,
|
||||
/*@null@*/ /*@out@*/ int * argcPtr,
|
||||
/*@null@*/ /*@out@*/ const char *** argvPtr)
|
||||
/*@modifies *argcPtr, *argvPtr @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Parse a string into an argument array.
|
||||
* The parse allows ', ", and \ quoting, but ' is treated the same as " and
|
||||
* both may include \ quotes.
|
||||
* @note: The argument array is malloc'd as a single area, so only argv must
|
||||
* be free'd.
|
||||
*
|
||||
* @param s string to parse
|
||||
* @retval argcPtr address of returned no. of arguments
|
||||
* @retval argvPtr address of returned argument array
|
||||
*/
|
||||
int poptParseArgvString(const char * s,
|
||||
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr);
|
||||
/*@observer@*/ const char *const poptStrerror(const int error);
|
||||
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute);
|
||||
void poptPrintHelp(poptContext con, FILE * f, int flags);
|
||||
void poptPrintUsage(poptContext con, FILE * f, int flags);
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text);
|
||||
/*@observer@*/ const char * poptGetInvocationName(poptContext con);
|
||||
/* shuffles argv pointers to remove stripped args, returns new argc */
|
||||
int poptStrippedArgv(poptContext con, int argc, char **argv);
|
||||
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr)
|
||||
/*@modifies *argcPtr, *argvPtr @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Return formatted error string for popt failure.
|
||||
* @param error popt error
|
||||
* @return error string
|
||||
*/
|
||||
/*@-redecl@*/
|
||||
/*@observer@*/ const char *const poptStrerror(const int error)
|
||||
/*@*/;
|
||||
/*@=redecl@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Limit search for executables.
|
||||
* @param con context
|
||||
* @param path single path to search for executables
|
||||
* @param allowAbsolute absolute paths only?
|
||||
*/
|
||||
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
|
||||
/*@modifies con @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Print detailed description of options.
|
||||
* @param con context
|
||||
* @param fp ouput file handle
|
||||
* @param flags (unused)
|
||||
*/
|
||||
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Print terse description of options.
|
||||
* @param con context
|
||||
* @param fp ouput file handle
|
||||
* @param flags (unused)
|
||||
*/
|
||||
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/;
|
||||
|
||||
/** \ingroup popt
|
||||
* Provide text to replace default "[OPTION...]" in help/usage output.
|
||||
* @param con context
|
||||
* @param text replacement text
|
||||
*/
|
||||
/*@-fcnuse@*/
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text)
|
||||
/*@modifies con @*/;
|
||||
/*@=fcnuse@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Return argv[0] from context.
|
||||
* @param con context
|
||||
* @return argv[0]
|
||||
*/
|
||||
/*@-redecl -fcnuse@*/
|
||||
/*@observer@*/ const char * poptGetInvocationName(poptContext con)
|
||||
/*@*/;
|
||||
/*@=redecl =fcnuse@*/
|
||||
|
||||
/** \ingroup popt
|
||||
* Shuffle argv pointers to remove stripped args, returns new argc.
|
||||
* @param con context
|
||||
* @param argc no. of args
|
||||
* @param argv arg vector
|
||||
* @return new argc
|
||||
*/
|
||||
/*@-fcnuse@*/
|
||||
int poptStrippedArgv(poptContext con, int argc, char ** argv)
|
||||
/*@modifies *argv @*/;
|
||||
/*@=fcnuse@*/
|
||||
|
||||
/*@=type@*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,101 +1,144 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/poptconfig.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
#include "poptint.h"
|
||||
|
||||
static void configLine(poptContext con, char * line) {
|
||||
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
|
||||
static void configLine(poptContext con, char * line)
|
||||
/*@modifies con @*/
|
||||
{
|
||||
/*@-type@*/
|
||||
int nameLength = strlen(con->appName);
|
||||
char * opt;
|
||||
struct poptAlias alias;
|
||||
char * entryType;
|
||||
char * longName = NULL;
|
||||
char shortName = '\0';
|
||||
/*@=type@*/
|
||||
const char * entryType;
|
||||
const char * opt;
|
||||
poptItem item = (poptItem) alloca(sizeof(*item));
|
||||
int i, j;
|
||||
|
||||
memset(item, 0, sizeof(*item));
|
||||
|
||||
/*@-type@*/
|
||||
if (strncmp(line, con->appName, nameLength)) return;
|
||||
/*@=type@*/
|
||||
|
||||
line += nameLength;
|
||||
if (!*line || !isspace(*line)) return;
|
||||
while (*line && isspace(*line)) line++;
|
||||
if (*line == '\0' || !isspace(*line)) return;
|
||||
|
||||
while (*line != '\0' && isspace(*line)) line++;
|
||||
entryType = line;
|
||||
|
||||
while (!*line || !isspace(*line)) line++;
|
||||
while (*line == '\0' || !isspace(*line)) line++;
|
||||
*line++ = '\0';
|
||||
while (*line && isspace(*line)) line++;
|
||||
if (!*line) return;
|
||||
|
||||
while (*line != '\0' && isspace(*line)) line++;
|
||||
if (*line == '\0') return;
|
||||
opt = line;
|
||||
|
||||
while (!*line || !isspace(*line)) line++;
|
||||
while (*line == '\0' || !isspace(*line)) line++;
|
||||
*line++ = '\0';
|
||||
while (*line && isspace(*line)) line++;
|
||||
if (!*line) return;
|
||||
|
||||
while (*line != '\0' && isspace(*line)) line++;
|
||||
if (*line == '\0') return;
|
||||
|
||||
/*@-temptrans@*/ /* FIX: line alias is saved */
|
||||
if (opt[0] == '-' && opt[1] == '-')
|
||||
longName = opt + 2;
|
||||
else if (opt[0] == '-' && !opt[2])
|
||||
shortName = opt[1];
|
||||
item->option.longName = opt + 2;
|
||||
else if (opt[0] == '-' && opt[2] == '\0')
|
||||
item->option.shortName = opt[1];
|
||||
/*@=temptrans@*/
|
||||
|
||||
if (!strcmp(entryType, "alias")) {
|
||||
if (poptParseArgvString(line, &alias.argc, &alias.argv)) return;
|
||||
alias.longName = longName, alias.shortName = shortName;
|
||||
poptAddAlias(con, alias, 0);
|
||||
} else if (!strcmp(entryType, "exec")) {
|
||||
con->execs = realloc(con->execs,
|
||||
sizeof(*con->execs) * (con->numExecs + 1));
|
||||
if (longName)
|
||||
con->execs[con->numExecs].longName = xstrdup(longName);
|
||||
else
|
||||
con->execs[con->numExecs].longName = NULL;
|
||||
if (poptParseArgvString(line, &item->argc, &item->argv)) return;
|
||||
|
||||
con->execs[con->numExecs].shortName = shortName;
|
||||
con->execs[con->numExecs].script = xstrdup(line);
|
||||
|
||||
con->numExecs++;
|
||||
/*@-modobserver@*/
|
||||
item->option.argInfo = POPT_ARGFLAG_DOC_HIDDEN;
|
||||
for (i = 0, j = 0; i < item->argc; i++, j++) {
|
||||
const char * f;
|
||||
if (!strncmp(item->argv[i], "--POPTdesc=", sizeof("--POPTdesc=")-1)) {
|
||||
f = item->argv[i] + sizeof("--POPTdesc=");
|
||||
if (f[0] == '$' && f[1] == '"') f++;
|
||||
item->option.descrip = f;
|
||||
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
|
||||
j--;
|
||||
} else
|
||||
if (!strncmp(item->argv[i], "--POPTargs=", sizeof("--POPTargs=")-1)) {
|
||||
f = item->argv[i] + sizeof("--POPTargs=");
|
||||
if (f[0] == '$' && f[1] == '"') f++;
|
||||
item->option.argDescrip = f;
|
||||
item->option.argInfo &= ~POPT_ARGFLAG_DOC_HIDDEN;
|
||||
item->option.argInfo |= POPT_ARG_STRING;
|
||||
j--;
|
||||
} else
|
||||
if (j != i)
|
||||
item->argv[j] = item->argv[i];
|
||||
}
|
||||
if (j != i) {
|
||||
item->argv[j] = NULL;
|
||||
item->argc = j;
|
||||
}
|
||||
/*@=modobserver@*/
|
||||
|
||||
/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
|
||||
if (!strcmp(entryType, "alias"))
|
||||
(void) poptAddItem(con, item, 0);
|
||||
else if (!strcmp(entryType, "exec"))
|
||||
(void) poptAddItem(con, item, 1);
|
||||
/*@=nullstate@*/
|
||||
}
|
||||
/*@=compmempass@*/
|
||||
|
||||
int poptReadConfigFile(poptContext con, const char * fn) {
|
||||
char * file=NULL, * chptr, * end;
|
||||
char * buf=NULL, * dst;
|
||||
int poptReadConfigFile(poptContext con, const char * fn)
|
||||
{
|
||||
const char * file, * chptr, * end;
|
||||
char * buf;
|
||||
/*@dependent@*/ char * dst;
|
||||
int fd, rc;
|
||||
int fileLength;
|
||||
off_t fileLength;
|
||||
|
||||
fd = open(fn, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
else
|
||||
return POPT_ERROR_ERRNO;
|
||||
}
|
||||
if (fd < 0)
|
||||
return (errno == ENOENT ? 0 : POPT_ERROR_ERRNO);
|
||||
|
||||
fileLength = lseek(fd, 0, SEEK_END);
|
||||
(void) lseek(fd, 0, 0);
|
||||
|
||||
file = malloc(fileLength + 1);
|
||||
if (read(fd, file, fileLength) != fileLength) {
|
||||
if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
|
||||
rc = errno;
|
||||
close(fd);
|
||||
(void) close(fd);
|
||||
/*@-mods@*/
|
||||
errno = rc;
|
||||
if (file) free(file);
|
||||
/*@=mods@*/
|
||||
return POPT_ERROR_ERRNO;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
dst = buf = malloc(fileLength + 1);
|
||||
file = alloca(fileLength + 1);
|
||||
if (read(fd, (char *)file, fileLength) != fileLength) {
|
||||
rc = errno;
|
||||
(void) close(fd);
|
||||
/*@-mods@*/
|
||||
errno = rc;
|
||||
/*@=mods@*/
|
||||
return POPT_ERROR_ERRNO;
|
||||
}
|
||||
if (close(fd) == -1)
|
||||
return POPT_ERROR_ERRNO;
|
||||
|
||||
dst = buf = alloca(fileLength + 1);
|
||||
|
||||
chptr = file;
|
||||
end = (file + fileLength);
|
||||
/*@-infloops@*/ /* LCL: can't detect chptr++ */
|
||||
while (chptr < end) {
|
||||
switch (*chptr) {
|
||||
case '\n':
|
||||
*dst = '\0';
|
||||
dst = buf;
|
||||
while (*dst && isspace(*dst)) dst++;
|
||||
if (*dst && *dst != '#') {
|
||||
if (*dst && *dst != '#')
|
||||
configLine(con, dst);
|
||||
}
|
||||
chptr++;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
case '\\':
|
||||
*dst++ = *chptr++;
|
||||
if (chptr < end) {
|
||||
@@ -105,15 +148,13 @@ int poptReadConfigFile(poptContext con, const char * fn) {
|
||||
else
|
||||
*dst++ = *chptr++;
|
||||
}
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
default:
|
||||
*dst++ = *chptr++;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
free(file);
|
||||
free(buf);
|
||||
/*@=infloops@*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -122,21 +163,21 @@ int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv) {
|
||||
char * fn, * home;
|
||||
int rc;
|
||||
|
||||
/*@-type@*/
|
||||
if (!con->appName) return 0;
|
||||
/*@=type@*/
|
||||
|
||||
rc = poptReadConfigFile(con, "/etc/popt");
|
||||
if (rc) return rc;
|
||||
if (getuid() != geteuid()) return 0;
|
||||
|
||||
if ((home = getenv("HOME"))) {
|
||||
fn = malloc(strlen(home) + 20);
|
||||
fn = alloca(strlen(home) + 20);
|
||||
strcpy(fn, home);
|
||||
strcat(fn, "/.popt");
|
||||
rc = poptReadConfigFile(con, fn);
|
||||
free(fn);
|
||||
if (rc) return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
612
popt/popthelp.c
612
popt/popthelp.c
@@ -1,48 +1,92 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/*@-type@*/
|
||||
/** \ingroup popt
|
||||
* \file popt/popthelp.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
#include "poptint.h"
|
||||
|
||||
/**
|
||||
* @param con context
|
||||
* @param key option(s)
|
||||
*/
|
||||
static void displayArgs(poptContext con,
|
||||
/*@unused@*/ enum poptCallbackReason foo,
|
||||
struct poptOption * key,
|
||||
/*@unused@*/ const char * arg, /*@unused@*/ void * data) {
|
||||
if (key->shortName== '?')
|
||||
/*@unused@*/ const char * arg, /*@unused@*/ void * data)
|
||||
/*@globals fileSystem@*/
|
||||
/*@modifies fileSystem@*/
|
||||
{
|
||||
if (key->shortName == '?')
|
||||
poptPrintHelp(con, stdout, 0);
|
||||
else
|
||||
poptPrintUsage(con, stdout, 0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef NOTYET
|
||||
/*@unchecked@*/
|
||||
static int show_option_defaults = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Empty table marker to enable displaying popt alias/exec options.
|
||||
*/
|
||||
/*@observer@*/ /*@unchecked@*/
|
||||
struct poptOption poptAliasOptions[] = {
|
||||
POPT_TABLEEND
|
||||
};
|
||||
|
||||
/**
|
||||
* Auto help table options.
|
||||
*/
|
||||
/*@-castfcnptr@*/
|
||||
/*@observer@*/ /*@unchecked@*/
|
||||
struct poptOption poptHelpOptions[] = {
|
||||
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
|
||||
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
|
||||
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
|
||||
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
|
||||
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
|
||||
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
|
||||
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
|
||||
#ifdef NOTYET
|
||||
{ "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
|
||||
N_("Display option defaults in message"), NULL },
|
||||
#endif
|
||||
POPT_TABLEEND
|
||||
} ;
|
||||
/*@=castfcnptr@*/
|
||||
|
||||
|
||||
/**
|
||||
* @param table option(s)
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ static const char *const
|
||||
getTableTranslationDomain(const struct poptOption *table)
|
||||
getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
|
||||
/*@*/
|
||||
{
|
||||
const struct poptOption *opt;
|
||||
const struct poptOption *opt;
|
||||
|
||||
for(opt = table;
|
||||
opt->longName || opt->shortName || opt->arg;
|
||||
opt++) {
|
||||
if(opt->argInfo == POPT_ARG_INTL_DOMAIN)
|
||||
return opt->arg;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (table != NULL)
|
||||
for (opt = table; opt->longName || opt->shortName || opt->arg; opt++) {
|
||||
if (opt->argInfo == POPT_ARG_INTL_DOMAIN)
|
||||
return opt->arg;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
/*@observer@*/ /*@null@*/ static const char *const
|
||||
getArgDescrip(const struct poptOption * opt, const char *translation_domain)
|
||||
getArgDescrip(const struct poptOption * opt,
|
||||
/*@-paramuse@*/ /* FIX: wazzup? */
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@=paramuse@*/
|
||||
/*@*/
|
||||
{
|
||||
if (!(opt->argInfo & POPT_ARG_MASK)) return NULL;
|
||||
|
||||
@@ -50,45 +94,229 @@ getArgDescrip(const struct poptOption * opt, const char *translation_domain)
|
||||
if (opt->argDescrip) return POPT_(opt->argDescrip);
|
||||
|
||||
if (opt->argDescrip) return D_(translation_domain, opt->argDescrip);
|
||||
return POPT_("ARG");
|
||||
|
||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
||||
case POPT_ARG_NONE: return POPT_("NONE");
|
||||
case POPT_ARG_VAL: return POPT_("VAL");
|
||||
case POPT_ARG_INT: return POPT_("INT");
|
||||
case POPT_ARG_LONG: return POPT_("LONG");
|
||||
case POPT_ARG_STRING: return POPT_("STRING");
|
||||
case POPT_ARG_FLOAT: return POPT_("FLOAT");
|
||||
case POPT_ARG_DOUBLE: return POPT_("DOUBLE");
|
||||
default: return POPT_("ARG");
|
||||
}
|
||||
}
|
||||
|
||||
static void singleOptionHelp(FILE * f, int maxLeftCol,
|
||||
const struct poptOption * opt,
|
||||
const char *translation_domain) {
|
||||
/**
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static /*@only@*/ /*@null@*/ char *
|
||||
singleOptionDefaultValue(int lineLength,
|
||||
const struct poptOption * opt,
|
||||
/*@-paramuse@*/ /* FIX: i18n macros disable with lclint */
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@=paramuse@*/
|
||||
/*@*/
|
||||
{
|
||||
const char * defstr = D_(translation_domain, "default");
|
||||
char * le = malloc(4*lineLength + 1);
|
||||
char * l = le;
|
||||
|
||||
if (le == NULL) return NULL; /* XXX can't happen */
|
||||
*le = '\0';
|
||||
*le++ = '(';
|
||||
strcpy(le, defstr); le += strlen(le);
|
||||
*le++ = ':';
|
||||
*le++ = ' ';
|
||||
if (opt->arg) /* XXX programmer error */
|
||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
||||
case POPT_ARG_VAL:
|
||||
case POPT_ARG_INT:
|
||||
{ long aLong = *((int *)opt->arg);
|
||||
sprintf(le, "%ld", aLong);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_LONG:
|
||||
{ long aLong = *((long *)opt->arg);
|
||||
sprintf(le, "%ld", aLong);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_FLOAT:
|
||||
{ double aDouble = *((float *)opt->arg);
|
||||
sprintf(le, "%g", aDouble);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_DOUBLE:
|
||||
{ double aDouble = *((double *)opt->arg);
|
||||
sprintf(le, "%g", aDouble);
|
||||
le += strlen(le);
|
||||
} break;
|
||||
case POPT_ARG_STRING:
|
||||
{ const char * s = *(const char **)opt->arg;
|
||||
if (s == NULL) {
|
||||
strcpy(le, "null"); le += strlen(le);
|
||||
} else {
|
||||
size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
|
||||
*le++ = '"';
|
||||
strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
|
||||
if (slen < strlen(s)) {
|
||||
strcpy(le, "..."); le += strlen(le);
|
||||
}
|
||||
*le++ = '"';
|
||||
}
|
||||
} break;
|
||||
case POPT_ARG_NONE:
|
||||
default:
|
||||
l = _free(l);
|
||||
return NULL;
|
||||
/*@notreached@*/ break;
|
||||
}
|
||||
*le++ = ')';
|
||||
*le = '\0';
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static void singleOptionHelp(FILE * fp, int maxLeftCol,
|
||||
const struct poptOption * opt,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int indentLength = maxLeftCol + 5;
|
||||
int lineLength = 79 - indentLength;
|
||||
const char * help = D_(translation_domain, opt->descrip);
|
||||
int helpLength;
|
||||
const char * ch;
|
||||
char format[10];
|
||||
char * left;
|
||||
const char * argDescrip = getArgDescrip(opt, translation_domain);
|
||||
int helpLength;
|
||||
char * defs = NULL;
|
||||
char * left;
|
||||
int nb = maxLeftCol + 1;
|
||||
|
||||
left = malloc(maxLeftCol + 1);
|
||||
*left = '\0';
|
||||
/* Make sure there's more than enough room in target buffer. */
|
||||
if (opt->longName) nb += strlen(opt->longName);
|
||||
if (argDescrip) nb += strlen(argDescrip);
|
||||
|
||||
left = malloc(nb);
|
||||
if (left == NULL) return; /* XXX can't happen */
|
||||
left[0] = '\0';
|
||||
left[maxLeftCol] = '\0';
|
||||
|
||||
if (opt->longName && opt->shortName)
|
||||
sprintf(left, "-%c, --%s", opt->shortName, opt->longName);
|
||||
else if (opt->shortName)
|
||||
sprintf(left, "-%c, %s%s", opt->shortName,
|
||||
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
|
||||
opt->longName);
|
||||
else if (opt->shortName != '\0')
|
||||
sprintf(left, "-%c", opt->shortName);
|
||||
else if (opt->longName)
|
||||
sprintf(left, "--%s", opt->longName);
|
||||
if (!*left) return ;
|
||||
sprintf(left, "%s%s",
|
||||
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
|
||||
opt->longName);
|
||||
if (!*left) goto out;
|
||||
if (argDescrip) {
|
||||
strcat(left, "=");
|
||||
strcat(left, argDescrip);
|
||||
char * le = left + strlen(left);
|
||||
|
||||
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
|
||||
*le++ = '[';
|
||||
|
||||
/* Choose type of output */
|
||||
/*@-branchstate@*/
|
||||
if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
|
||||
defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
|
||||
if (defs) {
|
||||
char * t = malloc((help ? strlen(help) : 0) +
|
||||
strlen(defs) + sizeof(" "));
|
||||
if (t) {
|
||||
char * te = t;
|
||||
*te = '\0';
|
||||
if (help) {
|
||||
strcpy(te, help); te += strlen(te);
|
||||
}
|
||||
*te++ = ' ';
|
||||
strcpy(te, defs);
|
||||
defs = _free(defs);
|
||||
}
|
||||
defs = t;
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
if (opt->argDescrip == NULL) {
|
||||
switch (opt->argInfo & POPT_ARG_MASK) {
|
||||
case POPT_ARG_NONE:
|
||||
break;
|
||||
case POPT_ARG_VAL:
|
||||
{ long aLong = opt->val;
|
||||
int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
|
||||
int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
|
||||
|
||||
/* Don't bother displaying typical values */
|
||||
if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L))
|
||||
break;
|
||||
*le++ = '[';
|
||||
switch (ops) {
|
||||
case POPT_ARGFLAG_OR:
|
||||
*le++ = '|';
|
||||
/*@innerbreak@*/ break;
|
||||
case POPT_ARGFLAG_AND:
|
||||
*le++ = '&';
|
||||
/*@innerbreak@*/ break;
|
||||
case POPT_ARGFLAG_XOR:
|
||||
*le++ = '^';
|
||||
/*@innerbreak@*/ break;
|
||||
default:
|
||||
/*@innerbreak@*/ break;
|
||||
}
|
||||
*le++ = '=';
|
||||
if (negate) *le++ = '~';
|
||||
/*@-formatconst@*/
|
||||
sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
|
||||
le += strlen(le);
|
||||
/*@=formatconst@*/
|
||||
*le++ = ']';
|
||||
} break;
|
||||
case POPT_ARG_INT:
|
||||
case POPT_ARG_LONG:
|
||||
case POPT_ARG_FLOAT:
|
||||
case POPT_ARG_DOUBLE:
|
||||
case POPT_ARG_STRING:
|
||||
*le++ = '=';
|
||||
strcpy(le, argDescrip); le += strlen(le);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
*le++ = '=';
|
||||
strcpy(le, argDescrip); le += strlen(le);
|
||||
}
|
||||
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
|
||||
*le++ = ']';
|
||||
*le = '\0';
|
||||
}
|
||||
|
||||
if (help)
|
||||
fprintf(f," %-*s ", maxLeftCol, left);
|
||||
fprintf(fp," %-*s ", maxLeftCol, left);
|
||||
else {
|
||||
fprintf(f," %s\n", left);
|
||||
fprintf(fp," %s\n", left);
|
||||
goto out;
|
||||
}
|
||||
|
||||
left = _free(left);
|
||||
if (defs) {
|
||||
help = defs; defs = NULL;
|
||||
}
|
||||
|
||||
helpLength = strlen(help);
|
||||
while (helpLength > lineLength) {
|
||||
const char * ch;
|
||||
char format[10];
|
||||
|
||||
ch = help + lineLength - 1;
|
||||
while (ch > help && !isspace(*ch)) ch--;
|
||||
if (ch == help) break; /* give up */
|
||||
@@ -96,39 +324,56 @@ static void singleOptionHelp(FILE * f, int maxLeftCol,
|
||||
ch++;
|
||||
|
||||
sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
|
||||
fprintf(f, format, help, " ");
|
||||
/*@-formatconst@*/
|
||||
fprintf(fp, format, help, " ");
|
||||
/*@=formatconst@*/
|
||||
help = ch;
|
||||
while (isspace(*help) && *help) help++;
|
||||
helpLength = strlen(help);
|
||||
}
|
||||
|
||||
if (helpLength) fprintf(f, "%s\n", help);
|
||||
if (helpLength) fprintf(fp, "%s\n", help);
|
||||
|
||||
out:
|
||||
free(left);
|
||||
/*@-dependenttrans@*/
|
||||
defs = _free(defs);
|
||||
/*@=dependenttrans@*/
|
||||
left = _free(left);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int maxArgWidth(const struct poptOption * opt,
|
||||
const char * translation_domain) {
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@*/
|
||||
{
|
||||
int max = 0;
|
||||
int this;
|
||||
int len = 0;
|
||||
const char * s;
|
||||
|
||||
if (opt != NULL)
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
||||
this = maxArgWidth(opt->arg, translation_domain);
|
||||
if (this > max) max = this;
|
||||
if (opt->arg) /* XXX program error */
|
||||
len = maxArgWidth(opt->arg, translation_domain);
|
||||
if (len > max) max = len;
|
||||
} else if (!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
||||
this = opt->shortName ? 2 : 0;
|
||||
len = sizeof(" ")-1;
|
||||
if (opt->shortName != '\0') len += sizeof("-X")-1;
|
||||
if (opt->shortName != '\0' && opt->longName) len += sizeof(", ")-1;
|
||||
if (opt->longName) {
|
||||
if (this) this += 2;
|
||||
this += strlen(opt->longName) + 2;
|
||||
len += ((opt->argInfo & POPT_ARGFLAG_ONEDASH)
|
||||
? sizeof("-")-1 : sizeof("--")-1);
|
||||
len += strlen(opt->longName);
|
||||
}
|
||||
|
||||
s = getArgDescrip(opt, translation_domain);
|
||||
if (s)
|
||||
this += strlen(s) + 1;
|
||||
if (this > max) max = this;
|
||||
len += sizeof("=")-1 + strlen(s);
|
||||
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
|
||||
if (len > max) max = len;
|
||||
}
|
||||
|
||||
opt++;
|
||||
@@ -137,77 +382,134 @@ static int maxArgWidth(const struct poptOption * opt,
|
||||
return max;
|
||||
}
|
||||
|
||||
static void singleTableHelp(FILE * f, const struct poptOption * table,
|
||||
int left,
|
||||
const char *translation_domain) {
|
||||
const struct poptOption * opt;
|
||||
const char *sub_transdom;
|
||||
/**
|
||||
* Display popt alias and exec help.
|
||||
* @param fp output file handle
|
||||
* @param items alias/exec array
|
||||
* @param nitems no. of alias/exec entries
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static void itemHelp(FILE * fp,
|
||||
/*@null@*/ poptItem items, int nitems, int left,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
poptItem item;
|
||||
int i;
|
||||
|
||||
opt = table;
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if (items != NULL)
|
||||
for (i = 0, item = items; i < nitems; i++, item++) {
|
||||
const struct poptOption * opt;
|
||||
opt = &item->option;
|
||||
if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
||||
singleOptionHelp(f, left, opt, translation_domain);
|
||||
opt++;
|
||||
}
|
||||
|
||||
opt = table;
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
||||
sub_transdom = getTableTranslationDomain(opt->arg);
|
||||
if(!sub_transdom)
|
||||
sub_transdom = translation_domain;
|
||||
|
||||
if (opt->descrip)
|
||||
fprintf(f, "\n%s\n", D_(sub_transdom, opt->descrip));
|
||||
|
||||
singleTableHelp(f, opt->arg, left, sub_transdom);
|
||||
}
|
||||
opt++;
|
||||
singleOptionHelp(fp, left, opt, translation_domain);
|
||||
}
|
||||
}
|
||||
|
||||
static int showHelpIntro(poptContext con, FILE * f) {
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param table option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static void singleTableHelp(poptContext con, FILE * fp,
|
||||
/*@null@*/ const struct poptOption * table, int left,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
const struct poptOption * opt;
|
||||
const char *sub_transdom;
|
||||
|
||||
if (table == poptAliasOptions) {
|
||||
itemHelp(fp, con->aliases, con->numAliases, left, NULL);
|
||||
itemHelp(fp, con->execs, con->numExecs, left, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (table != NULL)
|
||||
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
|
||||
if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
||||
singleOptionHelp(fp, left, opt, translation_domain);
|
||||
}
|
||||
|
||||
if (table != NULL)
|
||||
for (opt = table; (opt->longName || opt->shortName || opt->arg); opt++) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_INCLUDE_TABLE)
|
||||
continue;
|
||||
sub_transdom = getTableTranslationDomain(opt->arg);
|
||||
if (sub_transdom == NULL)
|
||||
sub_transdom = translation_domain;
|
||||
|
||||
if (opt->descrip)
|
||||
fprintf(fp, "\n%s\n", D_(sub_transdom, opt->descrip));
|
||||
|
||||
singleTableHelp(con, fp, opt->arg, left, sub_transdom);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param con context
|
||||
* @param fp output file handle
|
||||
*/
|
||||
static int showHelpIntro(poptContext con, FILE * fp)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int len = 6;
|
||||
const char * fn;
|
||||
|
||||
fprintf(f, POPT_("Usage:"));
|
||||
fprintf(fp, POPT_("Usage:"));
|
||||
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
|
||||
/*@-nullderef@*/ /* LCL: wazzup? */
|
||||
fn = con->optionStack->argv[0];
|
||||
if (strchr(fn, '/')) fn = strchr(fn, '/') + 1;
|
||||
fprintf(f, " %s", fn);
|
||||
/*@=nullderef@*/
|
||||
if (fn == NULL) return len;
|
||||
if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
|
||||
fprintf(fp, " %s", fn);
|
||||
len += strlen(fn) + 1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
void poptPrintHelp(poptContext con, FILE * f, /*@unused@*/ int flags) {
|
||||
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
{
|
||||
int leftColWidth;
|
||||
|
||||
showHelpIntro(con, f);
|
||||
(void) showHelpIntro(con, fp);
|
||||
if (con->otherHelp)
|
||||
fprintf(f, " %s\n", con->otherHelp);
|
||||
fprintf(fp, " %s\n", con->otherHelp);
|
||||
else
|
||||
fprintf(f, " %s\n", POPT_("[OPTION...]"));
|
||||
fprintf(fp, " %s\n", POPT_("[OPTION...]"));
|
||||
|
||||
leftColWidth = maxArgWidth(con->options, NULL);
|
||||
singleTableHelp(f, con->options, leftColWidth, NULL);
|
||||
singleTableHelp(con, fp, con->options, leftColWidth, NULL);
|
||||
}
|
||||
|
||||
static int singleOptionUsage(FILE * f, int cursor,
|
||||
const struct poptOption * opt,
|
||||
const char *translation_domain) {
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int singleOptionUsage(FILE * fp, int cursor,
|
||||
const struct poptOption * opt,
|
||||
/*@null@*/ const char *translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int len = 3;
|
||||
char shortStr[2] = { '\0', '\0' };
|
||||
const char * item = shortStr;
|
||||
const char * argDescrip = getArgDescrip(opt, translation_domain);
|
||||
|
||||
if (opt->shortName) {
|
||||
if (opt->shortName!= '\0' ) {
|
||||
if (!(opt->argInfo & POPT_ARG_MASK))
|
||||
return cursor; /* we did these already */
|
||||
len++;
|
||||
*shortStr = opt->shortName;
|
||||
shortStr[0] = opt->shortName;
|
||||
shortStr[1] = '\0';
|
||||
} else if (opt->longName) {
|
||||
len += 1 + strlen(opt->longName);
|
||||
@@ -220,82 +522,140 @@ static int singleOptionUsage(FILE * f, int cursor,
|
||||
len += strlen(argDescrip) + 1;
|
||||
|
||||
if ((cursor + len) > 79) {
|
||||
fprintf(f, "\n ");
|
||||
fprintf(fp, "\n ");
|
||||
cursor = 7;
|
||||
}
|
||||
|
||||
fprintf(f, " [-%s%s%s%s]", opt->shortName ? "" : "-", item,
|
||||
argDescrip ? (opt->shortName ? " " : "=") : "",
|
||||
argDescrip ? argDescrip : "");
|
||||
fprintf(fp, " [-%s%s%s%s]",
|
||||
((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
|
||||
item,
|
||||
(argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
|
||||
(argDescrip ? argDescrip : ""));
|
||||
|
||||
return cursor + len + 1;
|
||||
}
|
||||
|
||||
static int singleTableUsage(FILE * f, int cursor, const struct poptOption * table,
|
||||
const char *translation_domain) {
|
||||
const struct poptOption * opt;
|
||||
|
||||
opt = table;
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN)
|
||||
translation_domain = (const char *)opt->arg;
|
||||
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
|
||||
cursor = singleTableUsage(f, cursor, opt->arg,
|
||||
translation_domain);
|
||||
else if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN))
|
||||
cursor = singleOptionUsage(f, cursor, opt, translation_domain);
|
||||
/**
|
||||
* Display popt alias and exec usage.
|
||||
* @param fp output file handle
|
||||
* @param item alias/exec array
|
||||
* @param nitems no. of ara/exec entries
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
int i;
|
||||
|
||||
opt++;
|
||||
/*@-branchstate@*/ /* FIX: W2DO? */
|
||||
if (item != NULL)
|
||||
for (i = 0; i < nitems; i++, item++) {
|
||||
const struct poptOption * opt;
|
||||
opt = &item->option;
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
|
||||
translation_domain = (const char *)opt->arg;
|
||||
} else if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
||||
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
static int showShortOptions(const struct poptOption * opt, FILE * f,
|
||||
char * str) {
|
||||
char s[300]; /* this is larger then the ascii set, so
|
||||
it should do just fine */
|
||||
/**
|
||||
* @param fp output file handle
|
||||
* @param opt option(s)
|
||||
* @param translation_domain translation domain
|
||||
*/
|
||||
static int singleTableUsage(poptContext con, FILE * fp,
|
||||
int cursor, const struct poptOption * opt,
|
||||
/*@null@*/ const char * translation_domain)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *fp, fileSystem @*/
|
||||
{
|
||||
/*@-branchstate@*/ /* FIX: W2DO? */
|
||||
if (opt != NULL)
|
||||
for (; (opt->longName || opt->shortName || opt->arg) ; opt++) {
|
||||
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
|
||||
translation_domain = (const char *)opt->arg;
|
||||
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
|
||||
if (opt->arg) /* XXX program error */
|
||||
cursor = singleTableUsage(con, fp, cursor, opt->arg,
|
||||
translation_domain);
|
||||
} else if ((opt->longName || opt->shortName) &&
|
||||
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
|
||||
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
|
||||
}
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return concatenated short options for display.
|
||||
* @param opt option(s)
|
||||
* @param fp output file handle
|
||||
* @retval str concatenation of short options
|
||||
* @return length of display string
|
||||
*/
|
||||
static int showShortOptions(const struct poptOption * opt, FILE * fp,
|
||||
/*@null@*/ char * str)
|
||||
/*@globals fileSystem @*/
|
||||
/*@modifies *str, *fp, fileSystem @*/
|
||||
{
|
||||
char * s = alloca(300); /* larger then the ascii set */
|
||||
|
||||
s[0] = '\0';
|
||||
/*@-branchstate@*/ /* FIX: W2DO? */
|
||||
if (str == NULL) {
|
||||
memset(s, 0, sizeof(s));
|
||||
str = s;
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
|
||||
while (opt->longName || opt->shortName || opt->arg) {
|
||||
if (opt != NULL)
|
||||
for (; (opt->longName || opt->shortName || opt->arg); opt++) {
|
||||
if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
|
||||
str[strlen(str)] = opt->shortName;
|
||||
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
|
||||
showShortOptions(opt->arg, f, str);
|
||||
|
||||
opt++;
|
||||
if (opt->arg) /* XXX program error */
|
||||
(void) showShortOptions(opt->arg, fp, str);
|
||||
}
|
||||
|
||||
if (s != str || !*s)
|
||||
if (s != str || *s != '\0')
|
||||
return 0;
|
||||
|
||||
fprintf(f, " [-%s]", s);
|
||||
fprintf(fp, " [-%s]", s);
|
||||
return strlen(s) + 4;
|
||||
}
|
||||
|
||||
void poptPrintUsage(poptContext con, FILE * f, /*@unused@*/ int flags) {
|
||||
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ int flags)
|
||||
{
|
||||
int cursor;
|
||||
|
||||
cursor = showHelpIntro(con, f);
|
||||
cursor += showShortOptions(con->options, f, NULL);
|
||||
singleTableUsage(f, cursor, con->options, NULL);
|
||||
cursor = showHelpIntro(con, fp);
|
||||
cursor += showShortOptions(con->options, fp, NULL);
|
||||
(void) singleTableUsage(con, fp, cursor, con->options, NULL);
|
||||
(void) itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
|
||||
(void) itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
|
||||
|
||||
if (con->otherHelp) {
|
||||
cursor += strlen(con->otherHelp) + 1;
|
||||
if (cursor > 79) fprintf(f, "\n ");
|
||||
fprintf(f, " %s", con->otherHelp);
|
||||
if (cursor > 79) fprintf(fp, "\n ");
|
||||
fprintf(fp, " %s", con->otherHelp);
|
||||
}
|
||||
|
||||
fprintf(f, "\n");
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text) {
|
||||
if (con->otherHelp) xfree(con->otherHelp);
|
||||
void poptSetOtherOptionHelp(poptContext con, const char * text)
|
||||
{
|
||||
con->otherHelp = _free(con->otherHelp);
|
||||
con->otherHelp = xstrdup(text);
|
||||
}
|
||||
/*@=type@*/
|
||||
|
||||
@@ -1,69 +1,78 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/poptint.h
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#ifndef H_POPTINT
|
||||
#define H_POPTINT
|
||||
|
||||
/**
|
||||
* Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
|
||||
* @param p memory to free
|
||||
* @retval NULL always
|
||||
*/
|
||||
/*@unused@*/ static inline /*@null@*/ void *
|
||||
_free(/*@only@*/ /*@null@*/ const void * p)
|
||||
/*@modifies p @*/
|
||||
{
|
||||
if (p != NULL) free((void *)p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Bit mask macros. */
|
||||
typedef unsigned int __pbm_bits;
|
||||
#define __PBM_NBITS (8 * sizeof (__pbm_bits))
|
||||
#define __PBM_IX(d) ((d) / __PBM_NBITS)
|
||||
#define __PBM_MASK(d) ((__pbm_bits) 1 << ((d) % __PBM_NBITS))
|
||||
#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
|
||||
typedef struct {
|
||||
__pbm_bits bits[1];
|
||||
} pbm_set;
|
||||
#define __PBM_BITS(set) ((set)->bits)
|
||||
|
||||
#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
|
||||
#define PBM_FREE(s) free(s);
|
||||
#define PBM_FREE(s) _free(s);
|
||||
#define PBM_SET(d, s) (__PBM_BITS (s)[__PBM_IX (d)] |= __PBM_MASK (d))
|
||||
#define PBM_CLR(d, s) (__PBM_BITS (s)[__PBM_IX (d)] &= ~__PBM_MASK (d))
|
||||
#define PBM_ISSET(d, s) ((__PBM_BITS (s)[__PBM_IX (d)] & __PBM_MASK (d)) != 0)
|
||||
|
||||
struct optionStackEntry {
|
||||
int argc;
|
||||
/*@only@*/ const char ** argv;
|
||||
/*@only@*/ pbm_set * argb;
|
||||
/*@only@*/ /*@null@*/ const char ** argv;
|
||||
/*@only@*/ /*@null@*/ pbm_set * argb;
|
||||
int next;
|
||||
/*@only@*/ const char * nextArg;
|
||||
/*@keep@*/ const char * nextCharArg;
|
||||
/*@dependent@*/ struct poptAlias * currAlias;
|
||||
/*@only@*/ /*@null@*/ const char * nextArg;
|
||||
/*@keep@*/ /*@null@*/ const char * nextCharArg;
|
||||
/*@dependent@*/ /*@null@*/ poptItem currAlias;
|
||||
int stuffed;
|
||||
};
|
||||
|
||||
struct execEntry {
|
||||
const char * longName;
|
||||
char shortName;
|
||||
const char * script;
|
||||
};
|
||||
|
||||
struct poptContext_s {
|
||||
struct optionStackEntry optionStack[POPT_OPTION_DEPTH];
|
||||
/*@dependent@*/ struct optionStackEntry * os;
|
||||
/*@owned@*/ const char ** leftovers;
|
||||
/*@dependent@*/ struct optionStackEntry * os;
|
||||
/*@owned@*/ /*@null@*/ const char ** leftovers;
|
||||
int numLeftovers;
|
||||
int nextLeftover;
|
||||
/*@keep@*/ const struct poptOption * options;
|
||||
/*@keep@*/ const struct poptOption * options;
|
||||
int restLeftover;
|
||||
/*@only@*/ const char * appName;
|
||||
/*@only@*/ struct poptAlias * aliases;
|
||||
/*@only@*/ /*@null@*/ const char * appName;
|
||||
/*@only@*/ /*@null@*/ poptItem aliases;
|
||||
int numAliases;
|
||||
int flags;
|
||||
struct execEntry * execs;
|
||||
/*@owned@*/ /*@null@*/ poptItem execs;
|
||||
int numExecs;
|
||||
/*@only@*/ const char ** finalArgv;
|
||||
/*@only@*/ /*@null@*/ const char ** finalArgv;
|
||||
int finalArgvCount;
|
||||
int finalArgvAlloced;
|
||||
/*@dependent@*/ struct execEntry * doExec;
|
||||
/*@only@*/ const char * execPath;
|
||||
/*@dependent@*/ /*@null@*/ poptItem doExec;
|
||||
/*@only@*/ const char * execPath;
|
||||
int execAbsolute;
|
||||
/*@only@*/ const char * otherHelp;
|
||||
pbm_set * arg_strip;
|
||||
/*@only@*/ const char * otherHelp;
|
||||
/*@null@*/ pbm_set * arg_strip;
|
||||
};
|
||||
|
||||
#define xfree(_a) free((void *)_a)
|
||||
|
||||
#ifdef HAVE_LIBINTL_H
|
||||
#include <libintl.h>
|
||||
#endif
|
||||
@@ -71,17 +80,17 @@ struct poptContext_s {
|
||||
#if defined(HAVE_GETTEXT) && !defined(__LCLINT__)
|
||||
#define _(foo) gettext(foo)
|
||||
#else
|
||||
#define _(foo) (foo)
|
||||
#define _(foo) foo
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DGETTEXT) && !defined(__LCLINT__)
|
||||
#define D_(dom, str) dgettext(dom, str)
|
||||
#define POPT_(foo) D_("popt", foo)
|
||||
#else
|
||||
#define POPT_(foo) (foo)
|
||||
#define D_(dom, str) (str)
|
||||
#define D_(dom, str) str
|
||||
#define POPT_(foo) foo
|
||||
#endif
|
||||
|
||||
#define N_(foo) (foo)
|
||||
#define N_(foo) foo
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING
|
||||
/** \ingroup popt
|
||||
* \file popt/poptparse.c
|
||||
*/
|
||||
|
||||
/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
|
||||
file accompanying popt source distributions, available from
|
||||
ftp://ftp.redhat.com/pub/code/popt */
|
||||
ftp://ftp.rpm.org/pub/rpm/dist. */
|
||||
|
||||
#include "system.h"
|
||||
|
||||
@@ -14,6 +18,8 @@ int poptDupArgv(int argc, const char **argv,
|
||||
char * dst;
|
||||
int i;
|
||||
|
||||
if (argc <= 0 || argv == NULL) /* XXX can't happen */
|
||||
return POPT_ERROR_NOARG;
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i] == NULL)
|
||||
return POPT_ERROR_NOARG;
|
||||
@@ -21,17 +27,27 @@ int poptDupArgv(int argc, const char **argv,
|
||||
}
|
||||
|
||||
dst = malloc(nb);
|
||||
if (dst == NULL) /* XXX can't happen */
|
||||
return POPT_ERROR_MALLOC;
|
||||
argv2 = (void *) dst;
|
||||
dst += (argc + 1) * sizeof(*argv);
|
||||
|
||||
/*@-branchstate@*/
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv2[i] = dst;
|
||||
dst += strlen(strcpy(dst, argv[i])) + 1;
|
||||
}
|
||||
/*@=branchstate@*/
|
||||
argv2[argc] = NULL;
|
||||
|
||||
*argvPtr = argv2;
|
||||
*argcPtr = argc;
|
||||
if (argvPtr) {
|
||||
*argvPtr = argv2;
|
||||
} else {
|
||||
free(argv2);
|
||||
argv2 = NULL;
|
||||
}
|
||||
if (argcPtr)
|
||||
*argcPtr = argc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -43,31 +59,32 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
|
||||
const char ** argv = malloc(sizeof(*argv) * argvAlloced);
|
||||
int argc = 0;
|
||||
int buflen = strlen(s) + 1;
|
||||
char *buf0 = calloc(buflen, 1);
|
||||
char *buf = buf0;
|
||||
char * buf = memset(alloca(buflen), 0, buflen);
|
||||
int rc = POPT_ERROR_MALLOC;
|
||||
|
||||
if (argv == NULL) return rc;
|
||||
argv[argc] = buf;
|
||||
|
||||
for (src = s; *src; src++) {
|
||||
for (src = s; *src != '\0'; src++) {
|
||||
if (quote == *src) {
|
||||
quote = '\0';
|
||||
} else if (quote) {
|
||||
} else if (quote != '\0') {
|
||||
if (*src == '\\') {
|
||||
src++;
|
||||
if (!*src) {
|
||||
free(argv);
|
||||
free(buf0);
|
||||
return POPT_ERROR_BADQUOTE;
|
||||
rc = POPT_ERROR_BADQUOTE;
|
||||
goto exit;
|
||||
}
|
||||
if (*src != quote) *buf++ = '\\';
|
||||
}
|
||||
*buf++ = *src;
|
||||
} else if (isspace(*src)) {
|
||||
if (*argv[argc]) {
|
||||
if (*argv[argc] != '\0') {
|
||||
buf++, argc++;
|
||||
if (argc == argvAlloced) {
|
||||
argvAlloced += POPT_ARGV_ARRAY_GROW_DELTA;
|
||||
argv = realloc(argv, sizeof(*argv) * argvAlloced);
|
||||
if (argv == NULL) goto exit;
|
||||
}
|
||||
argv[argc] = buf;
|
||||
}
|
||||
@@ -75,18 +92,17 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
|
||||
case '"':
|
||||
case '\'':
|
||||
quote = *src;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
case '\\':
|
||||
src++;
|
||||
if (!*src) {
|
||||
free(argv);
|
||||
free(buf0);
|
||||
return POPT_ERROR_BADQUOTE;
|
||||
rc = POPT_ERROR_BADQUOTE;
|
||||
goto exit;
|
||||
}
|
||||
/*@fallthrough@*/
|
||||
default:
|
||||
*buf++ = *src;
|
||||
break;
|
||||
/*@switchbreak@*/ break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,9 +110,9 @@ int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
|
||||
argc++, buf++;
|
||||
}
|
||||
|
||||
(void) poptDupArgv(argc, argv, argcPtr, argvPtr);
|
||||
rc = poptDupArgv(argc, argv, argcPtr, argvPtr);
|
||||
|
||||
free(argv);
|
||||
free(buf0);
|
||||
return 0;
|
||||
exit:
|
||||
if (argv) free(argv);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -25,6 +25,14 @@
|
||||
#include <libc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__LCLINT__)
|
||||
/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */
|
||||
/*@only@*/ void * alloca (size_t __size)
|
||||
/*@ensures MaxSet(result) == (__size - 1) @*/
|
||||
/*@*/;
|
||||
/*@=declundef =incondefs =redecl@*/
|
||||
#endif
|
||||
|
||||
/* AIX requires this to be the first thing in the file. */
|
||||
#ifndef __GNUC__
|
||||
# if HAVE_ALLOCA_H
|
||||
@@ -33,8 +41,15 @@
|
||||
# ifdef _AIX
|
||||
#pragma alloca
|
||||
# else
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
# if HAVE_ALLOCA
|
||||
# ifndef alloca /* predefined by HP cc +Olibcalls */
|
||||
char *alloca ();
|
||||
# endif
|
||||
# else
|
||||
# ifdef alloca
|
||||
# undef alloca
|
||||
# endif
|
||||
# define alloca(sz) malloc(sz) /* Kludge this for now */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
@@ -42,7 +57,10 @@ char *alloca ();
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
|
||||
/*@only@*/ char * xstrdup (const char *str);
|
||||
/*@-redecl -redef@*/
|
||||
/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str)
|
||||
/*@*/;
|
||||
/*@=redecl =redef@*/
|
||||
|
||||
#if HAVE_MCHECK_H && defined(__GNUC__)
|
||||
#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL)
|
||||
|
||||
117
progress.c
Normal file
117
progress.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
static OFF_T last_ofs;
|
||||
static struct timeval print_time;
|
||||
static struct timeval start_time;
|
||||
static OFF_T start_ofs;
|
||||
|
||||
static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return (t2->tv_sec - t1->tv_sec) * 1000
|
||||
+ (t2->tv_usec - t1->tv_usec) / 1000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ofs Current position in file
|
||||
* @param size Total size of file
|
||||
* @param is_last True if this is the last time progress will be
|
||||
* printed for this file, so we should output a newline. (Not
|
||||
* necessarily the same as all bytes being received.)
|
||||
**/
|
||||
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
int is_last)
|
||||
{
|
||||
int pct = (ofs == size) ? 100 : (int)((100.0*ofs)/size);
|
||||
unsigned long diff = msdiff(&start_time, now);
|
||||
double rate = diff ? (double) (ofs-start_ofs) * 1000.0 / diff / 1024.0 : 0;
|
||||
const char *units;
|
||||
/* If we've finished transferring this file, show the time taken;
|
||||
* otherwise show expected time to complete. That's kind of
|
||||
* inconsistent, but people can probably cope. Hopefully we'll
|
||||
* get more consistent and complete progress reporting soon. --
|
||||
* mbp */
|
||||
double remain = is_last
|
||||
? (double) diff / 1000.0
|
||||
: rate ? (double) (size-ofs) / rate / 1000.0 : 0.0;
|
||||
int remain_h, remain_m, remain_s;
|
||||
|
||||
if (rate > 1024*1024) {
|
||||
rate /= 1024.0 * 1024.0;
|
||||
units = "GB/s";
|
||||
} else if (rate > 1024) {
|
||||
rate /= 1024.0;
|
||||
units = "MB/s";
|
||||
} else {
|
||||
units = "kB/s";
|
||||
}
|
||||
|
||||
remain_s = (int) remain % 60;
|
||||
remain_m = (int) (remain / 60.0) % 60;
|
||||
remain_h = (int) (remain / 3600.0);
|
||||
|
||||
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
(double) ofs, pct, rate, units,
|
||||
remain_h, remain_m, remain_s,
|
||||
is_last ? "\n" : "\r");
|
||||
}
|
||||
|
||||
void end_progress(OFF_T size)
|
||||
{
|
||||
extern int do_progress, am_server;
|
||||
|
||||
if (do_progress && !am_server) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
rprint_progress(size, size, &now, True);
|
||||
}
|
||||
last_ofs = 0;
|
||||
start_ofs = 0;
|
||||
print_time.tv_sec = print_time.tv_usec = 0;
|
||||
start_time.tv_sec = start_time.tv_usec = 0;
|
||||
}
|
||||
|
||||
void show_progress(OFF_T ofs, OFF_T size)
|
||||
{
|
||||
extern int do_progress, am_server;
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
if (!start_time.tv_sec && !start_time.tv_usec) {
|
||||
start_time.tv_sec = now.tv_sec;
|
||||
start_time.tv_usec = now.tv_usec;
|
||||
start_ofs = ofs;
|
||||
}
|
||||
|
||||
if (do_progress
|
||||
&& !am_server
|
||||
&& ofs > last_ofs + 1000
|
||||
&& msdiff(&print_time, &now) > 250) {
|
||||
rprint_progress(ofs, size, &now, False);
|
||||
last_ofs = ofs;
|
||||
print_time.tv_sec = now.tv_sec;
|
||||
print_time.tv_usec = now.tv_usec;
|
||||
}
|
||||
}
|
||||
18
receiver.c
18
receiver.c
@@ -297,9 +297,10 @@ static int receive_data(int f_in,struct map_struct *buf,int fd,char *fname,
|
||||
}
|
||||
|
||||
|
||||
/* main routine for receiver process. Receiver process runs on the
|
||||
same host as the generator process. */
|
||||
|
||||
/**
|
||||
* main routine for receiver process.
|
||||
*
|
||||
* Receiver process runs on the same host as the generator process. */
|
||||
int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
{
|
||||
int fd1,fd2;
|
||||
@@ -317,6 +318,7 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
extern struct stats stats;
|
||||
extern int preserve_perms;
|
||||
extern int delete_after;
|
||||
extern int orig_umask;
|
||||
struct stats initial_stats;
|
||||
|
||||
if (verbose > 2) {
|
||||
@@ -423,23 +425,17 @@ int recv_files(int f_in,struct file_list *flist,char *local_name,int f_gen)
|
||||
this out. We also set it initially without group
|
||||
access because of a similar race condition. */
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* in most cases parent directories will already exist
|
||||
because their information should have been previously
|
||||
transferred, but that may not be the case with -R */
|
||||
if (fd2 == -1 && relative_paths && errno == ENOENT &&
|
||||
create_directory_path(fnametmp) == 0) {
|
||||
create_directory_path(fnametmp, orig_umask) == 0) {
|
||||
strlcpy(fnametmp, template, sizeof(fnametmp));
|
||||
fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS);
|
||||
}
|
||||
if (fd2 == -1) {
|
||||
rprintf(FERROR,"cannot create %s : %s\n",fnametmp,strerror(errno));
|
||||
rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno));
|
||||
receive_data(f_in,buf,-1,NULL,file->length);
|
||||
if (buf) unmap_file(buf);
|
||||
if (fd1 != -1) close(fd1);
|
||||
|
||||
60
rsync.h
60
rsync.h
@@ -26,7 +26,8 @@
|
||||
#define RSYNC_RSH_ENV "RSYNC_RSH"
|
||||
|
||||
#define RSYNC_NAME "rsync"
|
||||
#define RSYNCD_CONF "/etc/rsyncd.conf"
|
||||
#define RSYNCD_SYSCONF "/etc/rsyncd.conf"
|
||||
#define RSYNCD_USERCONF "rsyncd.conf"
|
||||
|
||||
#define DEFAULT_LOCK_FILE "/var/run/rsyncd.lock"
|
||||
#define URL_PREFIX "rsync://"
|
||||
@@ -217,6 +218,8 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
#include <compat.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#define BOOL int
|
||||
|
||||
@@ -328,6 +331,10 @@ enum logcode {FNONE=0, FERROR=1, FINFO=2, FLOG=3 };
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
#ifndef IN_LOOPBACKNET
|
||||
#define IN_LOOPBACKNET 127
|
||||
#endif
|
||||
|
||||
struct file_struct {
|
||||
unsigned flags;
|
||||
time_t modtime;
|
||||
@@ -367,19 +374,19 @@ struct file_list {
|
||||
};
|
||||
|
||||
struct sum_buf {
|
||||
OFF_T offset; /* offset in file of this chunk */
|
||||
int len; /* length of chunk of file */
|
||||
int i; /* index of this chunk */
|
||||
uint32 sum1; /* simple checksum */
|
||||
char sum2[SUM_LENGTH]; /* checksum */
|
||||
OFF_T offset; /**< offset in file of this chunk */
|
||||
int len; /**< length of chunk of file */
|
||||
int i; /**< index of this chunk */
|
||||
uint32 sum1; /**< simple checksum */
|
||||
char sum2[SUM_LENGTH]; /**< checksum */
|
||||
};
|
||||
|
||||
struct sum_struct {
|
||||
OFF_T flength; /* total file length */
|
||||
size_t count; /* how many chunks */
|
||||
size_t remainder; /* flength % block_length */
|
||||
size_t n; /* block_length */
|
||||
struct sum_buf *sums; /* points to info for each chunk */
|
||||
OFF_T flength; /**< total file length */
|
||||
size_t count; /**< how many chunks */
|
||||
size_t remainder; /**< flength % block_length */
|
||||
size_t n; /**< block_length */
|
||||
struct sum_buf *sums; /**< points to info for each chunk */
|
||||
};
|
||||
|
||||
struct map_struct {
|
||||
@@ -564,19 +571,24 @@ extern int errno;
|
||||
/* handler for null strings in printf format */
|
||||
#define NS(s) ((s)?(s):"<NULL>")
|
||||
|
||||
#if !defined(__GNUC__) || defined(APPLE)
|
||||
/* Apparently the OS X port of gcc gags on __attribute__.
|
||||
*
|
||||
* <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
|
||||
#define __attribute__(x)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* use magic gcc attributes to catch format errors */
|
||||
void rprintf(enum logcode , const char *, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
__attribute__((format (printf, 2, 3)))
|
||||
;
|
||||
|
||||
/* This is just like rprintf, but it also tries to print some
|
||||
* representation of the error code. Normally errcode = errno. */
|
||||
void rsyserr(enum logcode, int, const char *, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 3, 4)))
|
||||
#endif
|
||||
__attribute__((format (printf, 3, 4)))
|
||||
;
|
||||
|
||||
#ifdef REPLACE_INET_NTOA
|
||||
@@ -607,11 +619,13 @@ inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
#endif /* !HAVE_INET_NTOP */
|
||||
|
||||
#ifndef HAVE_INET_PTON
|
||||
int isc_net_pton(int af, const char *src, void *dst);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define UNUSED(x) x __attribute__((__unused__))
|
||||
#else
|
||||
# define UNUSED(x) x
|
||||
#endif /* ndef __GNUC__ */
|
||||
#ifdef MAINTAINER_MODE
|
||||
const char *get_panic_action(void);
|
||||
#endif
|
||||
|
||||
#define UNUSED(x) x __attribute__((__unused__))
|
||||
|
||||
extern const char *io_write_phase, *io_read_phase;
|
||||
|
||||
196
rsync.yo
196
rsync.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsync)(1)(25 Jan 2002)()()
|
||||
manpage(rsync)(1)(26 Jan 2003)()()
|
||||
manpagename(rsync)(faster, flexible replacement for rcp)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -15,6 +15,8 @@ rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
|
||||
|
||||
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
|
||||
|
||||
rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST
|
||||
|
||||
manpagedescription()
|
||||
|
||||
rsync is a program that behaves in much the same way that rcp does,
|
||||
@@ -42,7 +44,7 @@ itemize(
|
||||
|
||||
manpagesection(GENERAL)
|
||||
|
||||
There are six different ways of using rsync. They are:
|
||||
There are eight different ways of using rsync. They are:
|
||||
|
||||
itemize(
|
||||
it() for copying local files. This is invoked when neither
|
||||
@@ -63,7 +65,19 @@ itemize(
|
||||
|
||||
it() for copying from the local machine to a remote rsync
|
||||
server. This is invoked when the destination path contains a ::
|
||||
separator.
|
||||
separator or a rsync:// URL.
|
||||
|
||||
it() for copying from a remote machine using a remote shell
|
||||
program as the transport, using rsync server on the remote
|
||||
machine. This is invoked when the source path contains a ::
|
||||
separator and the --rsh=COMMAND (aka "-e COMMAND") option is
|
||||
also provided.
|
||||
|
||||
it() for copying from the local machine to a remote machine
|
||||
using a remote shell program as the transport, using rsync
|
||||
server on the remote machine. This is invoked when the
|
||||
destination path contains a :: separator and the
|
||||
--rsh=COMMMAND option is also provided.
|
||||
|
||||
it() for listing files on a remote machine. This is done the
|
||||
same way as rsync transfers except that you leave off the
|
||||
@@ -77,11 +91,13 @@ manpagesection(SETUP)
|
||||
|
||||
See the file README for installation instructions.
|
||||
|
||||
Once installed you can use rsync to any machine that you can use rsh
|
||||
to. rsync uses rsh for its communications, unless both the source and
|
||||
destination are local.
|
||||
Once installed, you can use rsync to any machine that you can access via
|
||||
a remote shell (as well as some that you can access using the rsync
|
||||
daemon-mode protocol). For remote transfers, rsync typically uses rsh
|
||||
for its communications, but it may have been configured to use a
|
||||
different remote shell by default, such as ssh.
|
||||
|
||||
You can also specify an alternative to rsh, either by using the -e
|
||||
You can also specify any remote shell you like, either by using the -e
|
||||
command line option, or by setting the RSYNC_RSH environment variable.
|
||||
|
||||
One common substitute is to use ssh, which offers a high degree of
|
||||
@@ -135,7 +151,7 @@ somehost.mydomain.com. (See the following section for more details.)
|
||||
|
||||
manpagesection(CONNECTING TO AN RSYNC SERVER)
|
||||
|
||||
It is also possible to use rsync without using rsh or ssh as the
|
||||
It is also possible to use rsync without a remote shell as the
|
||||
transport. In this case you will connect to a remote rsync server
|
||||
running on TCP port 873.
|
||||
|
||||
@@ -144,12 +160,12 @@ environment variable RSYNC_PROXY to a hostname:port pair pointing to
|
||||
your web proxy. Note that your web proxy's configuration must allow
|
||||
proxying to port 873.
|
||||
|
||||
Using rsync in this way is the same as using it with rsh or ssh except
|
||||
Using rsync in this way is the same as using it with a remote shell except
|
||||
that:
|
||||
|
||||
itemize(
|
||||
it() you use a double colon :: instead of a single colon to
|
||||
separate the hostname from the path.
|
||||
separate the hostname from the path or a rsync:// URL.
|
||||
|
||||
it() the remote server may print a message of the day when you
|
||||
connect.
|
||||
@@ -170,11 +186,61 @@ may be useful when scripting rsync.
|
||||
WARNING: On some systems environment variables are visible to all
|
||||
users. On those systems using --password-file is recommended.
|
||||
|
||||
manpagesection(CONNECTING TO AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM)
|
||||
|
||||
It is sometimes useful to be able to set up file transfers using rsync
|
||||
server capabilities on the remote machine, while still using rsh or
|
||||
ssh for transport. This is especially useful when you want to connect
|
||||
to a remote machine via ssh (for encryption or to get through a
|
||||
firewall), but you still want to have access to the rsync server
|
||||
features (see RUNNING AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM,
|
||||
below).
|
||||
|
||||
From the user's perspective, using rsync in this way is the same as
|
||||
using it to connect to an rsync server, except that you must
|
||||
explicitly set the remote shell program on the command line with
|
||||
--rsh=COMMAND. (Setting RSYNC_RSH in the environment will not turn on
|
||||
this functionality.)
|
||||
|
||||
In order to distinguish between the remote-shell user and the rsync
|
||||
server user, you can use '-l user' on your remote-shell command:
|
||||
|
||||
quote(rsync -av --rsh="ssh -l ssh-user" rsync-user@host::module[/path] local-path)
|
||||
|
||||
The "ssh-user" will be used at the ssh level; the "rsync-user" will be
|
||||
used to check against the rsyncd.conf on the remote host.
|
||||
|
||||
manpagesection(RUNNING AN RSYNC SERVER)
|
||||
|
||||
An rsync server is configured using a config file which by default is
|
||||
called /etc/rsyncd.conf. Please see the rsyncd.conf(5) man page for more
|
||||
information.
|
||||
An rsync server is configured using a config file. Please see the
|
||||
rsyncd.conf(5) man page for more information. By default the configuration
|
||||
file is called /etc/rsyncd.conf, unless rsync is running over a remote
|
||||
shell program and is not running as root; in that case, the default name
|
||||
is rsyncd.conf in the current directory on the remote computer
|
||||
(typically $HOME).
|
||||
|
||||
manpagesection(RUNNING AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM)
|
||||
|
||||
See the rsyncd.conf(5) man page for full information on the rsync
|
||||
server configuration file.
|
||||
|
||||
Several configuration options will not be available unless the remote
|
||||
user is root (e.g. chroot, setuid/setgid, etc.). There is no need to
|
||||
configure inetd or the services map to include the rsync server port
|
||||
if you run an rsync server only via a remote shell program.
|
||||
|
||||
To run an rsync server out of a single-use ssh key, use the
|
||||
"command=em(COMMAND)" syntax in the remote user's
|
||||
authorized_keys entry, where command would be
|
||||
|
||||
quote(rsync --server --daemon .)
|
||||
|
||||
NOTE: rsync's argument parsing expects the trailing ".", so make sure
|
||||
that it's there. If you want to use a rsyncd.conf(5)-style
|
||||
configuration file other than the default, you can added a
|
||||
--config option to the em(command):
|
||||
|
||||
quote(rsync --server --daemon --config=em(file) .)
|
||||
|
||||
manpagesection(EXAMPLES)
|
||||
|
||||
@@ -219,12 +285,12 @@ verb(
|
||||
-v, --verbose increase verbosity
|
||||
-q, --quiet decrease verbosity
|
||||
-c, --checksum always checksum
|
||||
-a, --archive archive mode
|
||||
-a, --archive archive mode, equivalent to -rlptgoD
|
||||
-r, --recursive recurse into directories
|
||||
-R, --relative use relative path names
|
||||
-b, --backup make backups (default ~ suffix)
|
||||
--backup-dir make backups into this directory
|
||||
--suffix=SUFFIX override backup suffix
|
||||
--suffix=SUFFIX define backup suffix
|
||||
-u, --update update only (don't overwrite newer files)
|
||||
-l, --links copy symlinks as symlinks
|
||||
-L, --copy-links copy the referent of symlinks
|
||||
@@ -242,7 +308,7 @@ verb(
|
||||
--no-whole-file turn off --whole-file
|
||||
-x, --one-file-system don't cross filesystem boundaries
|
||||
-B, --block-size=SIZE checksum blocking size (default 700)
|
||||
-e, --rsh=COMMAND specify rsh replacement
|
||||
-e, --rsh=COMMAND specify the remote shell to use
|
||||
--rsync-path=PATH specify path to rsync on the remote machine
|
||||
-C, --cvs-exclude auto ignore files in the same way CVS does
|
||||
--existing only update files that already exist
|
||||
@@ -261,6 +327,7 @@ verb(
|
||||
--modify-window=NUM Timestamp window (seconds) for file match (default=0)
|
||||
-T --temp-dir=DIR create temporary files in directory DIR
|
||||
--compare-dest=DIR also compare destination files relative to DIR
|
||||
--link-dest=DIR create hardlinks to DIR for unchanged files
|
||||
-P equivalent to --partial --progress
|
||||
-z, --compress compress file data
|
||||
--exclude=PATTERN exclude files matching PATTERN
|
||||
@@ -329,8 +396,8 @@ dit(bf(--modify-window)) When comparing two timestamps rsync treats
|
||||
the timestamps as being equal if they are within the value of
|
||||
modify_window. This is normally zero, but you may find it useful to
|
||||
set this to a larger value in some situations. In particular, when
|
||||
transferring to/from FAT filesystems which cannot represent times with
|
||||
a 1 second resolution this option is useful.
|
||||
transferring to Windows FAT filesystems which cannot represent times
|
||||
with a 1 second resolution --modify-window=1 is useful.
|
||||
|
||||
dit(bf(-c, --checksum)) This forces the sender to checksum all files using
|
||||
a 128-bit MD4 checksum before transfer. The checksum is then
|
||||
@@ -372,10 +439,15 @@ control the backup suffix using the --suffix option.
|
||||
|
||||
dit(bf(--backup-dir=DIR)) In combination with the --backup option, this
|
||||
tells rsync to store all backups in the specified directory. This is
|
||||
very useful for incremental backups.
|
||||
very useful for incremental backups. You can additionally
|
||||
specify a backup suffix using the --suffix option
|
||||
(otherwise the files backed up in the specified directory
|
||||
will keep their original filenames).
|
||||
|
||||
dit(bf(--suffix=SUFFIX)) This option allows you to override the default
|
||||
backup suffix used with the -b option. The default is a ~.
|
||||
If --backup-dir and --suffix are both specified,
|
||||
the SUFFIX is appended to the filename even in the backup directory.
|
||||
|
||||
dit(bf(-u, --update)) This forces rsync to skip any files for which the
|
||||
destination file already exists and has a date later than the source
|
||||
@@ -421,7 +493,9 @@ permissions to be the same as the local permissions.
|
||||
|
||||
dit(bf(-o, --owner)) This option causes rsync to set the owner of the
|
||||
destination file to be the same as the source file. On most systems,
|
||||
only the super-user can set file ownership.
|
||||
only the super-user can set file ownership. Note that if the remote system
|
||||
is a daemon using chroot, the --numeric-ids option is implied because the
|
||||
remote system cannot get access to the usernames from /etc/passwd.
|
||||
|
||||
dit(bf(-g, --group)) This option causes rsync to set the group of the
|
||||
destination file to be the same as the source file. If the receiving
|
||||
@@ -485,11 +559,12 @@ destination. You can override this with the --ignore-errors option.
|
||||
dit(bf(--delete-excluded)) In addition to deleting the files on the
|
||||
receiving side that are not on the sending side, this tells rsync to also
|
||||
delete any files on the receiving side that are excluded (see --exclude).
|
||||
Implies --delete.
|
||||
|
||||
dit(bf(--delete-after)) By default rsync does file deletions before
|
||||
transferring files to try to ensure that there is sufficient space on
|
||||
the receiving filesystem. If you want to delete after transferring
|
||||
then use the --delete-after switch.
|
||||
then use the --delete-after switch. Implies --delete.
|
||||
|
||||
dit(bf(--ignore-errors)) Tells --delete to go ahead and delete files
|
||||
even when there are IO errors.
|
||||
@@ -504,11 +579,26 @@ the rsync algorithm. See the technical report for details.
|
||||
|
||||
dit(bf(-e, --rsh=COMMAND)) This option allows you to choose an alternative
|
||||
remote shell program to use for communication between the local and
|
||||
remote copies of rsync. By default, rsync will use rsh, but you may
|
||||
like to instead use ssh because of its high security.
|
||||
remote copies of rsync. Typically, rsync is configured to use rsh by
|
||||
default, but you may prefer to use ssh because of its high security.
|
||||
|
||||
If this option is used with bf([user@]host::module/path), then the
|
||||
remote shell em(COMMMAND) will be used to run an rsync server on the
|
||||
remote host, and all data will be transmitted through that remote
|
||||
shell connection, rather than through a direct socket connection to a
|
||||
running rsync server on the remote host. See the section "CONNECTING
|
||||
TO AN RSYNC SERVER OVER A REMOTE SHELL PROGRAM" above.
|
||||
|
||||
Command-line arguments are permitted in COMMAND provided that COMMAND is
|
||||
presented to rsync as a single argument. For example:
|
||||
|
||||
quote(-e "ssh -p 2234")
|
||||
|
||||
(Note that ssh users can alternately customize site-specific connect
|
||||
options in their .ssh/config file.)
|
||||
|
||||
You can also choose the remote shell program using the RSYNC_RSH
|
||||
environment variable.
|
||||
environment variable, which accepts the same range of values as -e.
|
||||
|
||||
See also the --blocking-io option which is affected by this option.
|
||||
|
||||
@@ -531,6 +621,8 @@ dit(bf(--exclude-from=FILE)) This option is similar to the --exclude
|
||||
option, but instead it adds all exclude patterns listed in the file
|
||||
FILE to the exclude list. Blank lines in FILE and lines starting with
|
||||
';' or '#' are ignored.
|
||||
If em(FILE) is bf(-) the list will be read from standard input.
|
||||
|
||||
|
||||
dit(bf(--include=PATTERN)) This option tells rsync to not exclude the
|
||||
specified pattern of filenames. This is useful as it allows you to
|
||||
@@ -541,6 +633,8 @@ this option.
|
||||
|
||||
dit(bf(--include-from=FILE)) This specifies a list of include patterns
|
||||
from a file.
|
||||
If em(FILE) is bf(-) the list will be read from standard input.
|
||||
|
||||
|
||||
dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a
|
||||
broad range of files that you often don't want to transfer between
|
||||
@@ -549,7 +643,7 @@ a file should be ignored.
|
||||
|
||||
The exclude list is initialized to:
|
||||
|
||||
quote(RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state
|
||||
quote(RCS/ SCCS/ CVS/ .svn/ CVS.adm RCSLOG cvslog.* tags TAGS .make.state
|
||||
.nse_depinfo *~ #* .#* ,* *.old *.bak *.BAK *.orig *.rej .del-*
|
||||
*.a *.o *.obj *.so *.Z *.elc *.ln core)
|
||||
|
||||
@@ -586,15 +680,21 @@ the temporary files in the receiving directory.
|
||||
|
||||
dit(bf(--compare-dest=DIR)) This option instructs rsync to use DIR on
|
||||
the destination machine as an additional directory to compare destination
|
||||
files against when doing transfers. This is useful for doing transfers to
|
||||
a new destination while leaving existing files intact, and then doing a
|
||||
files against when doing transfers if the files are missing in the
|
||||
destination directory. This is useful for doing transfers to a new
|
||||
destination while leaving existing files intact, and then doing a
|
||||
flash-cutover when all files have been successfully transferred (for
|
||||
example by moving directories around and removing the old directory,
|
||||
although this requires also doing the transfer with -I to avoid skipping
|
||||
files that haven't changed). This option increases the usefulness of
|
||||
--partial because partially transferred files will remain in the new
|
||||
temporary destination until they have a chance to be completed. If DIR is
|
||||
a relative path, it is relative to the destination directory.
|
||||
although this skips files that haven't changed; see also --link-dest).
|
||||
This option increases the usefulness of --partial because partially
|
||||
transferred files will remain in the new temporary destination until they
|
||||
have a chance to be completed. If DIR is a relative path, it is relative
|
||||
to the destination directory.
|
||||
|
||||
dit(bf(--link-dest=DIR)) This option behaves like bf(--compare-dest) but
|
||||
also will create hard links from em(DIR) to the destination directory for
|
||||
unchanged files. Files with changed ownership or permissions will not be
|
||||
linked.
|
||||
|
||||
dit(bf(-z, --compress)) With this option, rsync compresses any data from
|
||||
the files that it sends to the destination machine. This
|
||||
@@ -630,7 +730,7 @@ bf(rsync://host/module/) syntax.
|
||||
If standard input is a socket then rsync will assume that it is being
|
||||
run via inetd, otherwise it will detach from the current terminal and
|
||||
become a background daemon. The daemon will read the config file
|
||||
(/etc/rsyncd.conf) on each connect made by a client and respond to
|
||||
(rsyncd.conf) on each connect made by a client and respond to
|
||||
requests accordingly. See the rsyncd.conf(5) man page for more
|
||||
details.
|
||||
|
||||
@@ -650,8 +750,10 @@ address (or hostname) to bind to. This makes virtual hosting possible
|
||||
in conjunction with the --config option.
|
||||
|
||||
dit(bf(--config=FILE)) This specifies an alternate config file than
|
||||
the default /etc/rsyncd.conf. This is only relevant when --daemon is
|
||||
specified.
|
||||
the default. This is only relevant when --daemon is specified.
|
||||
The default is /etc/rsyncd.conf unless the daemon is running over
|
||||
a remote shell program and the remote user is not root; in that case
|
||||
the default is rsyncd.conf in the current directory (typically $HOME).
|
||||
|
||||
dit(bf(--port=PORT)) This specifies an alternate TCP port number to use
|
||||
rather than the default port 873.
|
||||
@@ -660,7 +762,8 @@ dit(bf(--blocking-io)) This tells rsync to use blocking IO when launching
|
||||
a remote shell transport. If -e or --rsh are not specified or are set to
|
||||
the default "rsh", this defaults to blocking IO, otherwise it defaults to
|
||||
non-blocking IO. You may find the --blocking-io option is needed for some
|
||||
remote shells that can't handle non-blocking IO. Ssh prefers blocking IO.
|
||||
remote shells that can't handle non-blocking IO. (Note that ssh prefers
|
||||
non-blocking IO.)
|
||||
|
||||
dit(bf(--no-blocking-io)) Turn off --blocking-io, for use when it is the
|
||||
default.
|
||||
@@ -910,6 +1013,10 @@ bf(--copy-unsafe-links) will cause any links to be copied as the file
|
||||
they point to on the destination. Using bf(--safe-links) will cause
|
||||
unsafe links to be ommitted altogether.
|
||||
|
||||
Symbolic links are considered unsafe if they are absolute symlinks
|
||||
(start with bf(/)), empty, or if they contain enough bf("..")
|
||||
components to ascend from the directory being copied.
|
||||
|
||||
manpagesection(DIAGNOSTICS)
|
||||
|
||||
rsync occasionally produces error messages that may seem a little
|
||||
@@ -969,8 +1076,8 @@ ignore patterns in .cvsignore files. See the --cvs-exclude option for
|
||||
more details.
|
||||
|
||||
dit(bf(RSYNC_RSH)) The RSYNC_RSH environment variable allows you to
|
||||
override the default shell used as the transport for rsync. This can
|
||||
be used instead of the -e option.
|
||||
override the default shell used as the transport for rsync. Command line
|
||||
options are permitted after the command name, just as in the -e option.
|
||||
|
||||
dit(bf(RSYNC_PROXY)) The RSYNC_PROXY environment variable allows you to
|
||||
redirect your rsync client to use a web proxy when connecting to a
|
||||
@@ -991,7 +1098,7 @@ enddit()
|
||||
|
||||
manpagefiles()
|
||||
|
||||
/etc/rsyncd.conf
|
||||
/etc/rsyncd.conf or rsyncd.conf
|
||||
|
||||
manpageseealso()
|
||||
|
||||
@@ -1003,16 +1110,17 @@ manpagebugs()
|
||||
|
||||
times are transferred as unix time_t values
|
||||
|
||||
When transferring to FAT filesystmes rsync may resync
|
||||
unmodified files.
|
||||
See the comments on the --modify-window option.
|
||||
|
||||
file permissions, devices etc are transferred as native numerical
|
||||
values
|
||||
|
||||
see also the comments on the --delete option
|
||||
|
||||
Please report bugs! The rsync bug tracking system is online at
|
||||
url(http://rsync.samba.org/rsync/)(http://rsync.samba.org/rsync/)
|
||||
|
||||
manpagesection(VERSION)
|
||||
This man page is current for version 2.0 of rsync
|
||||
Please report bugs! See the website at
|
||||
url(http://rsync.samba.org/)(http://rsync.samba.org/)
|
||||
|
||||
manpagesection(CREDITS)
|
||||
|
||||
|
||||
105
rsyncd.conf.yo
105
rsyncd.conf.yo
@@ -1,5 +1,5 @@
|
||||
mailto(rsync-bugs@samba.org)
|
||||
manpage(rsyncd.conf)(5)(12 Feb 1999)()()
|
||||
manpage(rsyncd.conf)(5)(26 Jan 2003)()()
|
||||
manpagename(rsyncd.conf)(configuration file for rsync server)
|
||||
manpagesynopsis()
|
||||
|
||||
@@ -8,9 +8,7 @@ rsyncd.conf
|
||||
manpagedescription()
|
||||
|
||||
The rsyncd.conf file is the runtime configuration file for rsync when
|
||||
run with the --daemon option. When run in this way rsync becomes a
|
||||
rsync server listening on TCP port 873. Connections from rsync clients
|
||||
are accepted for either anonymous or authenticated rsync sessions.
|
||||
run as an rsync server.
|
||||
|
||||
The rsyncd.conf file controls authentication, access, logging and
|
||||
available modules.
|
||||
@@ -51,9 +49,12 @@ bind to a port numbered under 1024 (as is the default 873), or to set
|
||||
file ownership. Otherwise, it must just have permission to read and
|
||||
write the appropriate data, log, and lock files.
|
||||
|
||||
You can launch it either via inetd or as a stand-alone daemon. If run
|
||||
as a daemon then just run the command "rsync --daemon" from a suitable
|
||||
startup script.
|
||||
You can launch it either via inetd, as a stand-alone daemon, or from
|
||||
an rsync client via a remote shell. If run as a stand-alone daemon then
|
||||
just run the command "rsync --daemon" from a suitable startup script.
|
||||
If run from an rsync client via a remote shell (by specifying both the
|
||||
"-e/--rsh" option and server mode with "::" or "rsync://"), the --daemon
|
||||
option is automatically passed to the remote side.
|
||||
|
||||
When run via inetd you should add a line like this to /etc/services:
|
||||
|
||||
@@ -68,7 +69,7 @@ your system. You will then need to send inetd a HUP signal to tell it to
|
||||
reread its config file.
|
||||
|
||||
Note that you should not send the rsync server a HUP signal to force
|
||||
it to reread the tt(/etc/rsyncd.conf). The file is re-read on each client
|
||||
it to reread the tt(rsyncd.conf) file. The file is re-read on each client
|
||||
connection.
|
||||
|
||||
manpagesection(GLOBAL OPTIONS)
|
||||
@@ -127,28 +128,30 @@ of available modules. The default is no comment.
|
||||
|
||||
dit(bf(path)) The "path" option specifies the directory in the servers
|
||||
filesystem to make available in this module. You must specify this option
|
||||
for each module in tt(/etc/rsyncd.conf).
|
||||
for each module in tt(rsyncd.conf).
|
||||
|
||||
dit(bf(use chroot)) If "use chroot" is true, the rsync server will chroot
|
||||
to the "path" before starting the file transfer with the client. This has
|
||||
the advantage of extra protection against possible implementation security
|
||||
holes, but it has the disadvantages of requiring super-user privileges and
|
||||
holes, but it has the disadvantages of requiring super-user privileges,
|
||||
of not being able to follow symbolic links outside of the new root path
|
||||
when reading. When "use chroot" is false, for security reasons
|
||||
symlinks may only be relative paths pointing to other files within the
|
||||
root path, and leading slashes are removed from absolute paths. The
|
||||
default for "use chroot" is true.
|
||||
when reading, and of implying the --numeric-ids option because /etc/passwd
|
||||
becomes inaccessible. When "use chroot" is false, for security reasons
|
||||
symlinks may only be relative paths pointing to other files within the root
|
||||
path, and leading slashes are removed from absolute paths. The default for
|
||||
"use chroot" is true.
|
||||
|
||||
dit(bf(max connections)) The "max connections" option allows you to
|
||||
specify the maximum number of simultaneous connections you will allow
|
||||
to this module of your rsync server. Any clients connecting when the
|
||||
maximum has been reached will receive a message telling them to try
|
||||
later. The default is 0 which means no limit.
|
||||
specify the maximum number of simultaneous connections you will allow.
|
||||
Any clients connecting when the maximum has been reached will receive a
|
||||
message telling them to try later. The default is 0 which means no limit.
|
||||
See also the "lock file" option.
|
||||
|
||||
dit(bf(lock file)) The "lock file" option specifies the file to use to
|
||||
support the "max connections" option. The rsync server uses record
|
||||
locking on this file to ensure that the max connections limit is not
|
||||
exceeded. The default is tt(/var/run/rsyncd.lock).
|
||||
exceeded for the modules sharing the lock file.
|
||||
The default is tt(/var/run/rsyncd.lock).
|
||||
|
||||
dit(bf(read only)) The "read only" option determines whether clients
|
||||
will be able to upload files or not. If "read only" is true then any
|
||||
@@ -173,12 +176,15 @@ was run as root. This complements the "uid" option. The default is gid -2,
|
||||
which is normally the group "nobody".
|
||||
|
||||
dit(bf(exclude)) The "exclude" option allows you to specify a space
|
||||
separated list of patterns to add to the exclude list. This is
|
||||
equivalent to the client specifying these patterns with the --exclude
|
||||
option except that the exclude list is not passed to the client and
|
||||
thus only apply on the server. Only one "exclude" option may be
|
||||
specified, but you can use "-" and "+" before patterns to specify
|
||||
exclude/include.
|
||||
separated list of patterns to add to the exclude list. This is equivalent
|
||||
to the client specifying these patterns with the --exclude option, except
|
||||
that the exclude list is not passed to the client and thus only applies on
|
||||
the server: that is, it excludes files received by a client when receiving
|
||||
from a server and files deleted on a server when sending to a server, but
|
||||
it doesn't exclude files sent from a client when sending to a server or
|
||||
files deleted on a client when receiving from a server.
|
||||
Only one "exclude" option may be specified, but
|
||||
you can use "-" and "+" before patterns to specify exclude/include.
|
||||
|
||||
Note that this option is not designed with strong security in
|
||||
mind, it is quite possible that a client may find a way to bypass this
|
||||
@@ -189,24 +195,22 @@ file permissions.
|
||||
dit(bf(exclude from)) The "exclude from" option specifies a filename
|
||||
on the server that contains exclude patterns, one per line. This is
|
||||
equivalent to the client specifying the --exclude-from option with a
|
||||
equivalent file except that the resulting exclude patterns are not
|
||||
passed to the client and thus only apply on the server. See also the
|
||||
note about security for the exclude option above.
|
||||
equivalent file except that it applies only on the server. See also
|
||||
the "exclude" option above.
|
||||
|
||||
dit(bf(include)) The "include" option allows you to specify a space
|
||||
separated list of patterns which rsync should not exclude. This is
|
||||
equivalent to the client specifying these patterns with the --include
|
||||
option. This is useful as it allows you to build up quite complex
|
||||
exclude/include rules. Only one "include" option may be specified, but you
|
||||
can use "+" and "-" before patterns to switch include/exclude.
|
||||
|
||||
See the section of exclude patterns in the rsync man page for information
|
||||
on the syntax of this option.
|
||||
option except that it applies only on the server. This is useful as it
|
||||
allows you to build up quite complex exclude/include rules. Only one
|
||||
"include" option may be specified, but you can use "+" and "-" before
|
||||
patterns to switch include/exclude. See also the "exclude" option above.
|
||||
|
||||
dit(bf(include from)) The "include from" option specifies a filename
|
||||
on the server that contains include patterns, one per line. This is
|
||||
equivalent to the client specifying the --include-from option with a
|
||||
equivalent file.
|
||||
equivalent file except that it applies only on the server. See also
|
||||
the "exclude" option above.
|
||||
|
||||
dit(bf(auth users)) The "auth users" option specifies a comma and
|
||||
space separated list of usernames that will be allowed to connect to
|
||||
@@ -219,6 +223,11 @@ usernames are passwords are stored in the file specified by the
|
||||
"secrets file" option. The default is for all users to be able to
|
||||
connect without a password (this is called "anonymous rsync").
|
||||
|
||||
See also the bf(CONNECTING TO AN RSYNC SERVER OVER A REMOTE SHELL
|
||||
PROGRAM) section in rsync(1) for information on how handle an
|
||||
rsyncd.conf-level username that differs from the remote-shell-level
|
||||
username when using a remote shell to connect to a rsync server.
|
||||
|
||||
dit(bf(secrets file)) The "secrets file" option specifies the name of
|
||||
a file that contains the username:password pairs used for
|
||||
authenticating this module. This file is only consulted if the "auth
|
||||
@@ -248,16 +257,18 @@ connection is rejected.
|
||||
Each pattern can be in one of five forms:
|
||||
|
||||
itemize(
|
||||
it() a dotted decimal IP address. In this case the incoming machines
|
||||
IP address must match exactly.
|
||||
it() a dotted decimal IPv4 address of the form a.b.c.d, or an IPv6 address
|
||||
of the form a:b:c::d:e:f. In this case the incoming machine's IP address
|
||||
must match exactly.
|
||||
|
||||
it() a address/mask in the form a.b.c.d/n were n is the number of
|
||||
one bits in in the netmask. All IP addresses which match the masked
|
||||
IP address will be allowed in.
|
||||
it() an address/mask in the form ipaddr/n where ipaddr is the IP address
|
||||
and n is the number of one bits in the netmask. All IP addresses which
|
||||
match the masked IP address will be allowed in.
|
||||
|
||||
it() a address/mask in the form a.b.c.d/e.f.g.h where e.f.g.h is a
|
||||
netmask in dotted decimal notation. All IP addresses which match the masked
|
||||
IP address will be allowed in.
|
||||
it() an address/mask in the form ipaddr/maskaddr where ipaddr is the
|
||||
IP address and maskaddr is the netmask in dotted decimal notation for IPv4,
|
||||
or similar for IPv6, e.g. ffff:ffff:ffff:ffff:: instead of /64. All IP
|
||||
addresses which match the masked IP address will be allowed in.
|
||||
|
||||
it() a hostname. The hostname as determined by a reverse lookup will
|
||||
be matched (case insensitive) against the pattern. Only an exact
|
||||
@@ -268,6 +279,12 @@ itemize(
|
||||
then the client is allowed in.
|
||||
)
|
||||
|
||||
Note IPv6 link-local addresses can have a scope in the address specification:
|
||||
|
||||
quote(fe80::1%link1)
|
||||
quote(fe80::%link1/64)
|
||||
quote(fe80::%link1/ffff:ffff:ffff:ffff::)
|
||||
|
||||
You can also combine "hosts allow" with a separate "hosts deny"
|
||||
option. If both options are specified then the "hosts allow" option s
|
||||
checked first and a match results in the client being able to
|
||||
@@ -430,7 +447,7 @@ susan:herpass
|
||||
|
||||
manpagefiles()
|
||||
|
||||
/etc/rsyncd.conf
|
||||
/etc/rsyncd.conf or rsyncd.conf
|
||||
|
||||
manpageseealso()
|
||||
|
||||
|
||||
21
runtests.sh
21
runtests.sh
@@ -125,6 +125,9 @@ set -e
|
||||
|
||||
RUNSHFLAGS='-e'
|
||||
|
||||
# for Solaris
|
||||
PATH="/usr/xpg4/bin/:$PATH"
|
||||
|
||||
if [ -n "$loglevel" ] && [ "$loglevel" -gt 8 ]
|
||||
then
|
||||
if set -x
|
||||
@@ -139,6 +142,20 @@ echo "$0 running in `pwd`"
|
||||
echo " rsync_bin=$rsync_bin"
|
||||
echo " srcdir=$srcdir"
|
||||
|
||||
testuser=`whoami || echo UNKNOWN`
|
||||
|
||||
echo " testuser=$testuser"
|
||||
echo " os=`uname -a`"
|
||||
|
||||
# It must be "yes", not just nonnull
|
||||
if test "x$preserve_scratch" = xyes
|
||||
then
|
||||
echo " preserve_scratch=yes"
|
||||
else
|
||||
echo " preserve_scratch=no"
|
||||
fi
|
||||
|
||||
|
||||
if test ! -f $rsync_bin
|
||||
then
|
||||
echo "rsync_bin $rsync_bin is not a file" >&2
|
||||
@@ -212,7 +229,9 @@ do
|
||||
maybe_discard_scratch
|
||||
;;
|
||||
77)
|
||||
echo "SKIP $testbase"
|
||||
# backticks will fill the whole file onto one line, which is a feature
|
||||
whyskipped=`cat "$scratchdir/whyskipped"`
|
||||
echo "SKIP $testbase ($whyskipped)"
|
||||
skipped=`expr $skipped + 1`
|
||||
maybe_discard_scratch
|
||||
;;
|
||||
|
||||
19
sender.c
19
sender.c
@@ -28,9 +28,18 @@ extern int dry_run;
|
||||
extern int am_server;
|
||||
|
||||
|
||||
/*
|
||||
receive the checksums for a buffer
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The sender gets checksums from the generator, calculates deltas,
|
||||
* and transmits them to the receiver. The sender process runs on the
|
||||
* machine holding the source files.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* Receive the checksums for a buffer
|
||||
**/
|
||||
static struct sum_struct *receive_sums(int f)
|
||||
{
|
||||
struct sum_struct *s;
|
||||
@@ -46,8 +55,8 @@ static struct sum_struct *receive_sums(int f)
|
||||
s->sums = NULL;
|
||||
|
||||
if (verbose > 3)
|
||||
rprintf(FINFO,"count=%d n=%d rem=%d\n",
|
||||
s->count,s->n,s->remainder);
|
||||
rprintf(FINFO,"count=%ld n=%ld rem=%ld\n",
|
||||
(long) s->count, (long) s->n, (long) s->remainder);
|
||||
|
||||
if (s->count == 0)
|
||||
return(s);
|
||||
|
||||
49
socket.c
49
socket.c
@@ -34,8 +34,10 @@
|
||||
#include "rsync.h"
|
||||
|
||||
|
||||
/* Establish a proxy connection on an open socket to a web roxy by
|
||||
* using the CONNECT method. */
|
||||
/**
|
||||
* Establish a proxy connection on an open socket to a web proxy by
|
||||
* using the HTTP CONNECT method.
|
||||
**/
|
||||
static int establish_proxy_connection(int fd, char *host, int port)
|
||||
{
|
||||
char buffer[1024];
|
||||
@@ -68,7 +70,7 @@ static int establish_proxy_connection(int fd, char *host, int port)
|
||||
buffer);
|
||||
return -1;
|
||||
}
|
||||
for (cp = &buffer[5]; isdigit(*cp) || (*cp == '.'); cp++)
|
||||
for (cp = &buffer[5]; isdigit(* (unsigned char *) cp) || (*cp == '.'); cp++)
|
||||
;
|
||||
while (*cp == ' ')
|
||||
cp++;
|
||||
@@ -122,12 +124,14 @@ int try_bind_local(int s,
|
||||
for (r = bres_all; r; r = r->ai_next) {
|
||||
if (bind(s, r->ai_addr, r->ai_addrlen) == -1)
|
||||
continue;
|
||||
freeaddrinfo(bres_all);
|
||||
return s;
|
||||
}
|
||||
|
||||
/* no error message; there might be some problem that allows
|
||||
* creation of the socket but not binding, perhaps if the
|
||||
* machine has no ipv6 address of this name. */
|
||||
freeaddrinfo(bres_all);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -329,7 +333,8 @@ static int open_socket_in(int type, int port, const char *bind_address,
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
freeaddrinfo(all_ai);
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -369,7 +374,7 @@ int is_a_socket(int fd)
|
||||
}
|
||||
|
||||
|
||||
void start_accept_loop(int port, int (*fn)(int ))
|
||||
void start_accept_loop(int port, int (*fn)(int, int))
|
||||
{
|
||||
int s;
|
||||
extern char *bind_address;
|
||||
@@ -424,11 +429,14 @@ void start_accept_loop(int port, int (*fn)(int ))
|
||||
#endif
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
int ret;
|
||||
close(s);
|
||||
/* open log file in child before possibly giving
|
||||
up privileges */
|
||||
log_open();
|
||||
_exit(fn(fd));
|
||||
ret = fn(fd, fd);
|
||||
close_all();
|
||||
_exit(ret);
|
||||
} else if (pid < 0) {
|
||||
rprintf(FERROR,
|
||||
RSYNC_NAME
|
||||
@@ -491,9 +499,9 @@ struct
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
set user socket options
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Set user socket options
|
||||
**/
|
||||
void set_socket_options(int fd, char *options)
|
||||
{
|
||||
char *tok;
|
||||
@@ -551,9 +559,9 @@ void set_socket_options(int fd, char *options)
|
||||
free(options);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
become a daemon, discarding the controlling terminal
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Become a daemon, discarding the controlling terminal
|
||||
**/
|
||||
void become_daemon(void)
|
||||
{
|
||||
int i;
|
||||
@@ -583,14 +591,15 @@ void become_daemon(void)
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
this is like socketpair but uses tcp. It is used by the Samba
|
||||
regression test code
|
||||
The function guarantees that nobody else can attach to the socket,
|
||||
or if they do that this function fails and the socket gets closed
|
||||
returns 0 on success, -1 on failure
|
||||
the resulting file descriptors are symmetrical
|
||||
******************************************************************/
|
||||
/**
|
||||
* This is like socketpair but uses tcp. It is used by the Samba
|
||||
* regression test code.
|
||||
*
|
||||
* The function guarantees that nobody else can attach to the socket,
|
||||
* or if they do that this function fails and the socket gets closed
|
||||
* returns 0 on success, -1 on failure the resulting file descriptors
|
||||
* are symmetrical.
|
||||
**/
|
||||
static int socketpair_tcp(int fd[2])
|
||||
{
|
||||
int listener;
|
||||
|
||||
35
syscall.c
35
syscall.c
@@ -29,6 +29,7 @@
|
||||
extern int dry_run;
|
||||
extern int read_only;
|
||||
extern int list_only;
|
||||
extern int preserve_perms;
|
||||
|
||||
#define CHECK_RO if (read_only || list_only) {errno = EROFS; return -1;}
|
||||
|
||||
@@ -97,9 +98,13 @@ int do_open(char *pathname, int flags, mode_t mode)
|
||||
#if HAVE_CHMOD
|
||||
int do_chmod(const char *path, mode_t mode)
|
||||
{
|
||||
int code;
|
||||
if (dry_run) return 0;
|
||||
CHECK_RO
|
||||
return chmod(path, mode);
|
||||
code = chmod(path, mode);
|
||||
if ((code != 0) && preserve_perms)
|
||||
return code;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -111,19 +116,31 @@ int do_rename(char *fname1, char *fname2)
|
||||
}
|
||||
|
||||
|
||||
int do_mkdir(char *fname, mode_t mode)
|
||||
void trim_trailing_slashes(char *name)
|
||||
{
|
||||
int l;
|
||||
if (dry_run)
|
||||
return 0;
|
||||
CHECK_RO;
|
||||
|
||||
/* Some BSD systems cannot make a directory if the name
|
||||
* contains a trailing slash.
|
||||
* <http://www.opensource.apple.com/bugs/X/BSD%20Kernel/2734739.html> */
|
||||
if ((l = strlen(fname)) && (fname[l-1] == '/'))
|
||||
fname[l-1] = '/';
|
||||
|
||||
/* Don't change empty string; and also we can't improve on
|
||||
* "/" */
|
||||
|
||||
l = strlen(name);
|
||||
while (l > 1) {
|
||||
if (name[--l] != '/')
|
||||
break;
|
||||
name[l] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int do_mkdir(char *fname, mode_t mode)
|
||||
{
|
||||
if (dry_run)
|
||||
return 0;
|
||||
CHECK_RO;
|
||||
trim_trailing_slashes(fname);
|
||||
return mkdir(fname, mode);
|
||||
}
|
||||
|
||||
@@ -138,7 +155,7 @@ int do_mkstemp(char *template, mode_t perms)
|
||||
{
|
||||
int fd = mkstemp(template);
|
||||
if (fd == -1) return -1;
|
||||
if (fchmod(fd, perms) != 0) {
|
||||
if ((fchmod(fd, perms) != 0) && preserve_perms) {
|
||||
close(fd);
|
||||
unlink(template);
|
||||
return -1;
|
||||
|
||||
44
t_stub.c
Normal file
44
t_stub.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
*
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/**
|
||||
* @file t_stub.c
|
||||
*
|
||||
* This file contains really simple implementations for rsync global
|
||||
* functions, so that module test harnesses can run standalone.
|
||||
**/
|
||||
|
||||
int modify_window = 0;
|
||||
|
||||
void rprintf(enum logcode UNUSED(code), const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void _exit_cleanup(int code, const char *file, int line)
|
||||
{
|
||||
fprintf(stderr, "exit(%d): %s(%d)\n",
|
||||
code, file, line);
|
||||
exit(code);
|
||||
}
|
||||
45
t_unsafe.c
Normal file
45
t_unsafe.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Test harness for unsafe_symlink(). Not linked into @c rsync itself.
|
||||
*
|
||||
* Prints either "safe" or "unsafe" depending on the two arguments.
|
||||
* Always returns 0 unless something extraordinary happens.
|
||||
**/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
int dry_run, read_only, list_only, verbose;
|
||||
int preserve_perms = 0;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "usage: t_unsafe LINKDEST SRCDIR\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("%s\n",
|
||||
unsafe_symlink(argv[1], argv[2]) ? "unsafe" : "safe");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
echo $0 running
|
||||
|
||||
"$rsync_bin" --version || exit 1
|
||||
$RSYNC --version || exit 1
|
||||
|
||||
@@ -18,7 +18,9 @@ set -x
|
||||
fromdir="$scratchdir/from"
|
||||
todir="$scratchdir/to"
|
||||
|
||||
mygrps="`groups`" || fail "Can't get groups"
|
||||
# TODO: I guess some systems will not have 'id', and therefore we have
|
||||
# to ship or emulate it.
|
||||
mygrps="`rsync_getgroups`" || fail "Can't get groups"
|
||||
mkdir "$fromdir"
|
||||
|
||||
for g in $mygrps
|
||||
@@ -29,7 +31,7 @@ do
|
||||
done
|
||||
sleep 2
|
||||
|
||||
checkit "rsync -rtgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -rtgvvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -26,12 +26,12 @@ name2="$fromdir/name2"
|
||||
echo "This is the file" > "$name1"
|
||||
echo "This is the other file" > "$name2"
|
||||
|
||||
chown 5000 "$name1" || test_skipped "Can't chown"
|
||||
chown 5001 "$name2" || test_skipped "Can't chown"
|
||||
chgrp 5002 "$name1" || test_skipped "Can't chgrp"
|
||||
chgrp 5003 "$name2" || test_skipped "Can't chgrp"
|
||||
chown 5000 "$name1" || test_skipped "Can't chown (probably need root)"
|
||||
chown 5001 "$name2" || test_skipped "Can't chown (probably need root)"
|
||||
chgrp 5002 "$name1" || test_skipped "Can't chgrp (probably need root)"
|
||||
chgrp 5003 "$name2" || test_skipped "Can't chgrp (probably need root)"
|
||||
|
||||
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
RSYNC_CONNECT_PROG="$rsync_bin --config=$conf --daemon"
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
hands_setup
|
||||
checkit "$rsync_bin -avvz localhost::test-from/ \"$TO/\"" "$FROM" "$TO"
|
||||
checkit "$RSYNC -avvz localhost::test-from/ \"$TO/\"" "$FROM" "$TO"
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
RSYNC_CONNECT_PROG="$rsync_bin --config=$conf --daemon"
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
hands_setup
|
||||
checkit "$rsync_bin -avvz \"$FROM/\" localhost::test-to/" "$FROM" "$TO"
|
||||
checkit "$RSYNC -avvz \"$FROM/\" localhost::test-to/" "$FROM" "$TO"
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
build_rsyncd_conf
|
||||
|
||||
RSYNC_CONNECT_PROG="$rsync_bin --config=$conf --daemon"
|
||||
RSYNC_CONNECT_PROG="$RSYNC --config=$conf --daemon"
|
||||
export RSYNC_CONNECT_PROG
|
||||
|
||||
$rsync_bin -v localhost::
|
||||
$RSYNC -v localhost::
|
||||
|
||||
@@ -19,10 +19,10 @@ todir="$scratchdir/to"
|
||||
# TODO: Need to test whether hardlinks are possible on this OS/filesystem
|
||||
|
||||
mkdir "$fromdir"
|
||||
mknod "$fromdir/char" c 42 69 || test_skipped "Can't create char device node?"
|
||||
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node?"
|
||||
mknod "$fromdir/char" c 42 69 || test_skipped "Can't create char device node unless root"
|
||||
mknod "$fromdir/block" b 42 69 || test_skipped "Can't create block device node unless root"
|
||||
|
||||
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
echo "SKIP THIS FOR NOW; It's a known bug"
|
||||
exit 77
|
||||
test_skipped "Known minor bug in this code"
|
||||
|
||||
set -x
|
||||
|
||||
@@ -39,7 +38,7 @@ ln -s "$name1" "$name2" || fail "can't create symlink"
|
||||
|
||||
outfile="$scratchdir/rsync.out"
|
||||
|
||||
checkit "rsync -avv \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
|
||||
checkit "$RSYNC -avv \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir" \
|
||||
| tee "$outfile"
|
||||
|
||||
# Make sure each file was only copied once...
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (C) 1998,1999 Philip Hands <phil@hands.com>
|
||||
# Copyright (C) 2001 by Martin Pool <mbp@samba.org>
|
||||
# Copyright (C) 1998, 1999 by Philip Hands <phil@hands.com>
|
||||
# Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
#
|
||||
# This program is distributable under the terms of the GNU GPL (see COPYING)
|
||||
|
||||
@@ -25,6 +25,4 @@ runtest "extra data" 'checkit "$RSYNC -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
|
||||
cp ${FROM}/text ${TO}/ThisShouldGo
|
||||
runtest " --delete" 'checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}'
|
||||
|
||||
checkforlogs ${LOG}.?
|
||||
|
||||
hands_cleanup
|
||||
exit 0
|
||||
|
||||
@@ -31,7 +31,7 @@ ln "$name1" "$name2" || fail "Can't create hardlink"
|
||||
ln "$name2" "$name3" || fail "Can't create hardlink"
|
||||
cp "$name2" "$name4" || fail "Can't copy file"
|
||||
|
||||
checkit "rsync -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
checkit "$RSYNC -aHvv \"$fromdir/\" \"$todir/\"" "$fromdir" "$todir"
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
@@ -11,9 +11,11 @@
|
||||
|
||||
hands_setup
|
||||
|
||||
LONGDIR=${FROM}/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job/This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
LONGNAME=This-is-a-directory-with-a-stupidly-long-name-created-in-an-attempt-to-provoke-an-error-found-in-2.0.11-that-should-hopefully-never-appear-again-if-this-test-does-its-job
|
||||
LONGDIR=$FROM/$LONGNAME/$LONGNAME/$LONGNAME
|
||||
|
||||
makepath ${LONGDIR}
|
||||
makepath $LONGDIR || test_skipped "unable to create long directory"
|
||||
touch $LONGDIR/1 || test_skipped "unable to create files in long directory"
|
||||
date > ${LONGDIR}/1
|
||||
ls -la / > ${LONGDIR}/2
|
||||
checkit "$RSYNC --delete -avH ${FROM}/ ${TO}" ${FROM}/ ${TO}
|
||||
|
||||
@@ -24,6 +24,9 @@ TO=${TMP}/to
|
||||
LOG=${TMP}/log
|
||||
RSYNC="$rsync_bin"
|
||||
|
||||
# Berkley's nice.
|
||||
PATH="$PATH:/usr/ucb"
|
||||
|
||||
runtest() {
|
||||
echo $ECHO_N "Test $1: $ECHO_C"
|
||||
if eval "$2"
|
||||
@@ -42,7 +45,11 @@ printmsg() {
|
||||
|
||||
|
||||
rsync_ls_lR() {
|
||||
find "$@" -print | sort | xargs $TLS
|
||||
find "$@" -print | sort | xargs "$TOOLDIR/tls"
|
||||
}
|
||||
|
||||
rsync_getgroups() {
|
||||
"$TOOLDIR/getgroups"
|
||||
}
|
||||
|
||||
|
||||
@@ -95,13 +102,6 @@ hands_setup() {
|
||||
}
|
||||
|
||||
|
||||
hands_cleanup() {
|
||||
rm -r "$TMP"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
####################
|
||||
# Many machines do not have "mkdir -p", so we have to build up long paths.
|
||||
# How boring.
|
||||
@@ -134,6 +134,11 @@ makepath () {
|
||||
# Run a test (in '$1') then compare directories $2 and $3 to see if
|
||||
# there are any difference. If there are, explain them.
|
||||
|
||||
# So normally basically $1 should be an rsync command, and $2 and $3
|
||||
# the source and destination directories. This is only good when you
|
||||
# expect to transfer the whole directory exactly as is. If some files
|
||||
# should be excluded, you might need to use something else.
|
||||
|
||||
checkit() {
|
||||
failed=
|
||||
|
||||
@@ -169,21 +174,6 @@ checkit() {
|
||||
}
|
||||
|
||||
|
||||
# In fact, we need a more general feature of capturing all stderr/log files,
|
||||
# and dumping them if something goes wrong.
|
||||
|
||||
checkforlogs() {
|
||||
# skip it if we're under debian-test
|
||||
if test -n "${Debian}" ; then return 0 ; fi
|
||||
|
||||
if [ -f $1 -a -s $1 ] ; then
|
||||
echo "Failures have occurred. $1 follows:" >&2
|
||||
cat $1 >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
build_rsyncd_conf() {
|
||||
# Build an appropriate configuration file
|
||||
conf="$scratchdir/test-rsyncd.conf"
|
||||
@@ -201,6 +191,9 @@ use chroot = no
|
||||
hosts allow = localhost, 127.0.0.1
|
||||
log file = $logfile
|
||||
|
||||
uid = 0
|
||||
gid = 0
|
||||
|
||||
[test-from]
|
||||
path = $FROM
|
||||
read only = yes
|
||||
@@ -230,6 +223,7 @@ test_fail() {
|
||||
|
||||
test_skipped() {
|
||||
echo "$@" >&2
|
||||
echo "$@" > "$TMP/whyskipped"
|
||||
exit 77
|
||||
}
|
||||
|
||||
@@ -241,5 +235,44 @@ test_xfail() {
|
||||
exit 78
|
||||
}
|
||||
|
||||
# be reproducible
|
||||
umask 077
|
||||
# Determine what shell command will appropriately test for links.
|
||||
ln -s foo "$scratchdir/testlink"
|
||||
for cmd in test /bin/test /usr/bin/test /usr/ucb/bin/test /usr/ucb/test
|
||||
do
|
||||
for switch in -h -L
|
||||
do
|
||||
if $cmd $switch "$scratchdir/testlink" 2>/dev/null
|
||||
then
|
||||
# how nice
|
||||
TEST_SYMLINK_CMD="$cmd $switch"
|
||||
# i wonder if break 2 is portable?
|
||||
break 2
|
||||
fi
|
||||
done
|
||||
done
|
||||
# ok, now get rid of it
|
||||
rm "$scratchdir/testlink"
|
||||
|
||||
|
||||
if [ "x$TEST_SYMLINK_CMD" = 'x' ]
|
||||
then
|
||||
test_fail "Couldn't determine how to test for symlinks"
|
||||
else
|
||||
echo "Testing for symlinks using '$TEST_SYMLINK_CMD'"
|
||||
fi
|
||||
|
||||
|
||||
# Test whether something is a link, allowing for shell peculiarities
|
||||
is_a_link() {
|
||||
# note the variable contains the first option and therefore is not quoted
|
||||
$TEST_SYMLINK_CMD "$1"
|
||||
}
|
||||
|
||||
|
||||
# We need to set the umask to be reproducible. Note also that when we
|
||||
# do some daemon tests as root, we will setuid() and therefore the
|
||||
# directory has to be writable by the nobody user in some cases. The
|
||||
# best thing is probably to explicitly chmod those directories after
|
||||
# creation.
|
||||
|
||||
umask 022
|
||||
|
||||
@@ -12,18 +12,15 @@
|
||||
|
||||
if [ "x$rsync_enable_ssh_tests" != xyes ]
|
||||
then
|
||||
echo "Skipping SSH tests because \$rsync_enable_ssh_tests is not set"
|
||||
exit 77
|
||||
test_skipped "Skipping SSH tests because \$rsync_enable_ssh_tests is not set"
|
||||
fi
|
||||
|
||||
if ! type ssh >/dev/null ; then
|
||||
echo "Skipping SSH tests because ssh is not in the path"
|
||||
exit 77
|
||||
test_skipped "Skipping SSH tests because ssh is not in the path"
|
||||
fi
|
||||
|
||||
if ! [ "`ssh -o'BatchMode yes' localhost echo yes`" = "yes" ]; then
|
||||
echo "Skipping SSH tests because ssh conection to localhost not authorised"
|
||||
exit 77
|
||||
test_skipped "Skipping SSH tests because ssh conection to localhost not authorised"
|
||||
fi
|
||||
|
||||
runtest "ssh: basic test" 'checkit "$RSYNC -avH -e ssh --rsync-path=$RSYNC ${FROM}/ localhost:${TO}" ${FROM}/ ${TO}'
|
||||
|
||||
@@ -16,21 +16,21 @@ build_symlinks || test_fail "failed to build symlinks"
|
||||
|
||||
# Copy recursively, but without -l or -L or -a, and all the symlinks
|
||||
# should be missing.
|
||||
"$rsync_bin" -r "$fromdir/" "$todir" || test_fail "rsync returned $?"
|
||||
$RSYNC -r "$fromdir/" "$todir" || test_fail "$RSYNC returned $?"
|
||||
|
||||
[ -f "${todir}/referent" ] || test_fail "referent was not copied"
|
||||
[ -d "${todir}/from" ] && test_fail "extra level of directories"
|
||||
if [ -L "${todir}/dangling" ]
|
||||
if is_a_link "${todir}/dangling"
|
||||
then
|
||||
test_fail "dangling symlink was copied"
|
||||
fi
|
||||
|
||||
if [ -L "${todir}/relative" ]
|
||||
if is_a_link "${todir}/relative"
|
||||
then
|
||||
test_fail "relative symlink was copied"
|
||||
fi
|
||||
|
||||
if [ -L "${todir}/absolute" ]
|
||||
if is_a_link "${todir}/absolute"
|
||||
then
|
||||
test_fail "absolute symlink was copied"
|
||||
fi
|
||||
|
||||
29
testsuite/trimslash.test
Normal file
29
testsuite/trimslash.test
Normal file
@@ -0,0 +1,29 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
# This program is distributable under the terms of the GNU GPL (see
|
||||
# COPYING).
|
||||
|
||||
# Test tiny function to trim trailing slashes.
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
set -x
|
||||
|
||||
"$TOOLDIR/trimslash" "/usr/local/bin" "/usr/local/bin/" "/usr/local/bin///" \
|
||||
"//a//" "////" \
|
||||
"/Users/Wierd Macintosh Name/// Ooh, translucent plastic/" \
|
||||
> "$scratchdir/slash.out"
|
||||
diff -c "$scratchdir/slash.out" - <<EOF
|
||||
/usr/local/bin
|
||||
/usr/local/bin
|
||||
/usr/local/bin
|
||||
//a
|
||||
/
|
||||
/Users/Wierd Macintosh Name/// Ooh, translucent plastic
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
# last [] may have failed but if we get here then we've won
|
||||
|
||||
51
testsuite/unsafe-byname.test
Normal file
51
testsuite/unsafe-byname.test
Normal file
@@ -0,0 +1,51 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Copyright (C) 2002 by Martin Pool
|
||||
|
||||
# Call directly into unsafe_symlink and test its handling of various filenames
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
test_unsafe() {
|
||||
# $1 is the target of a symlink
|
||||
# $2 is the directory we're copying
|
||||
# $3 is the expected outcome: "safe" if the link lies within $2,
|
||||
# or "unsafe" otherwise
|
||||
|
||||
result=`"$TOOLDIR/t_unsafe" "$1" "$2"` || test_fail "Failed to check $1 $2"
|
||||
if [ "$result" != "$3" ]
|
||||
then
|
||||
test_fail "t_unsafe $1 $2 returned \"$result\", expected \"$3\""
|
||||
fi
|
||||
}
|
||||
|
||||
test_unsafe file from safe
|
||||
test_unsafe dir/file from safe
|
||||
test_unsafe dir/./file from safe
|
||||
test_unsafe dir/. from safe
|
||||
test_unsafe dir/ from safe
|
||||
|
||||
test_unsafe /etc/passwd from unsafe
|
||||
test_unsafe //../etc/passwd from unsafe
|
||||
test_unsafe //./etc/passwd from unsafe
|
||||
|
||||
test_unsafe ./foo from safe
|
||||
test_unsafe ../foo from unsafe
|
||||
test_unsafe ../dest from/dir safe
|
||||
|
||||
test_unsafe .. from/file safe
|
||||
test_unsafe ../.. from/file unsafe
|
||||
test_unsafe dir/.. from safe
|
||||
test_unsafe dir/../.. from unsafe
|
||||
|
||||
test_unsafe '' from unsafe
|
||||
|
||||
# Based on tests from unsafe-links by Vladim<69>r Michl
|
||||
test_unsafe ../../unsafe/unsafefile from/safe unsafe
|
||||
test_unsafe ../files/file1 from/safe safe
|
||||
|
||||
test_unsafe ../../unsafe/unsafefile safe unsafe
|
||||
test_unsafe ../files/file1 safe unsafe
|
||||
|
||||
test_unsafe ../../unsafe/unsafefile `pwd`/from/safe safe
|
||||
test_unsafe ../files/file1 `pwd`/from/safe safe
|
||||
68
testsuite/unsafe-links.test
Normal file
68
testsuite/unsafe-links.test
Normal file
@@ -0,0 +1,68 @@
|
||||
#! /bin/sh
|
||||
|
||||
# Originally by Vladim<69>r Michl <Vladimir.Michl@hlubocky.del.cz>
|
||||
|
||||
. $srcdir/testsuite/rsync.fns
|
||||
|
||||
test_symlink() {
|
||||
is_a_link "$1" || test_fail "File $1 is not a symlink"
|
||||
};
|
||||
|
||||
test_regular() {
|
||||
if [ ! -f "$1" ]; then
|
||||
test_fail "File $1 is not regular file or not exists";
|
||||
fi;
|
||||
};
|
||||
|
||||
cd "$TMP"
|
||||
|
||||
mkdir from
|
||||
|
||||
mkdir "from/safe"
|
||||
mkdir "from/unsafe"
|
||||
|
||||
mkdir "from/safe/files"
|
||||
mkdir "from/safe/links"
|
||||
|
||||
touch "from/safe/files/file1"
|
||||
touch "from/safe/files/file2"
|
||||
touch "from/unsafe/unsafefile"
|
||||
|
||||
ln -s ../files/file1 "from/safe/links/"
|
||||
ln -s ../files/file2 "from/safe/links/"
|
||||
ln -s ../../unsafe/unsafefile "from/safe/links/"
|
||||
|
||||
set -x
|
||||
|
||||
echo "rsync with relative path and just -a";
|
||||
$RSYNC -avv from/safe/ to
|
||||
test_symlink to/links/file1
|
||||
test_symlink to/links/file2
|
||||
test_symlink to/links/unsafefile
|
||||
|
||||
echo "rsync with relative path and -a --copy-links"
|
||||
$RSYNC -avv --copy-links from/safe/ to
|
||||
test_regular to/links/file1
|
||||
test_regular to/links/file2
|
||||
test_regular to/links/unsafefile
|
||||
|
||||
echo "rsync with relative path and --copy-unsafe-links";
|
||||
$RSYNC -avv --copy-unsafe-links from/safe/ to
|
||||
test_symlink to/links/file1
|
||||
test_symlink to/links/file2
|
||||
test_regular to/links/unsafefile
|
||||
|
||||
rm -rf to
|
||||
echo "rsync with relative2 path";
|
||||
(cd from; $RSYNC -avv --copy-unsafe-links safe/ ../to)
|
||||
test_symlink to/links/file1
|
||||
test_symlink to/links/file2
|
||||
test_regular to/links/unsafefile
|
||||
|
||||
rm -rf to
|
||||
echo "rsync with absolute path";
|
||||
$RSYNC -avv --copy-unsafe-links `pwd`/from/safe/ to
|
||||
test_symlink to/links/file1
|
||||
test_symlink to/links/file2
|
||||
test_regular to/links/unsafefile
|
||||
|
||||
11
tls.c
11
tls.c
@@ -17,10 +17,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* \section tls
|
||||
* @file tls.c
|
||||
*
|
||||
* tls -- Trivial recursive ls, for comparing two directories after
|
||||
* running an rsync.
|
||||
* Trivial @c ls for comparing two directories after running an rsync.
|
||||
*
|
||||
* The problem with using the system's own ls is that some features
|
||||
* have little quirks that make directories look different when for
|
||||
@@ -39,7 +38,6 @@
|
||||
**/
|
||||
|
||||
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
#define PROGRAM "tls"
|
||||
@@ -48,6 +46,7 @@
|
||||
int dry_run = 0;
|
||||
int read_only = 1;
|
||||
int list_only = 0;
|
||||
int preserve_perms = 0;
|
||||
|
||||
|
||||
static void failed (char const *what,
|
||||
@@ -117,9 +116,9 @@ static void list_file (const char *fname)
|
||||
|
||||
/* NB: need to pass size as a double because it might be be
|
||||
* too large for a long. */
|
||||
printf("%s %12.0f %6d.%-6d %6d %s %s%s\n",
|
||||
printf("%s %12.0f %6ld.%-6ld %6d %s %s%s\n",
|
||||
permbuf, (double) buf.st_size,
|
||||
buf.st_uid, buf.st_gid,
|
||||
(long) buf.st_uid, (long) buf.st_gid,
|
||||
buf.st_nlink,
|
||||
datebuf, fname, linkbuf);
|
||||
}
|
||||
|
||||
4
token.c
4
token.c
@@ -474,8 +474,8 @@ static void see_deflate_token(char *buf, int len)
|
||||
} while (len || rx_strm.avail_out == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* transmit a verbatim buffer of length n followed by a token
|
||||
/**
|
||||
* Transmit a verbatim buffer of length @p n followed by a token.
|
||||
* If token == -1 then we have reached EOF
|
||||
* If n == 0 then don't send a buffer
|
||||
*/
|
||||
|
||||
46
trimslash.c
Normal file
46
trimslash.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2002 by Martin Pool
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "rsync.h"
|
||||
|
||||
/* These are to make syscall.o shut up. */
|
||||
int dry_run = 0;
|
||||
int read_only = 1;
|
||||
int list_only = 0;
|
||||
int preserve_perms = 0;
|
||||
|
||||
/**
|
||||
* @file trimslash.c
|
||||
*
|
||||
* Test harness; not linked into release.
|
||||
**/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "trimslash: needs at least one argument\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
trim_trailing_slashes(argv[i]); /* modify in place */
|
||||
printf("%s\n", argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
526
util.c
526
util.c
@@ -1,42 +1,46 @@
|
||||
/* -*- c-file-style: "linux" -*-
|
||||
|
||||
Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
Copyright (C) Paul Mackerras 1996
|
||||
Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
*
|
||||
* Copyright (C) 1996-2000 by Andrew Tridgell
|
||||
* Copyright (C) Paul Mackerras 1996
|
||||
* Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Utilities used in rsync
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Utilities used in rsync
|
||||
**/
|
||||
|
||||
tridge, June 1996
|
||||
*/
|
||||
#include "rsync.h"
|
||||
|
||||
extern int verbose;
|
||||
|
||||
int sanitize_paths = 0;
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into nonblocking mode
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Set a fd into nonblocking mode
|
||||
**/
|
||||
void set_nonblocking(int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
if ((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
return;
|
||||
if (!(val & NONBLOCK_FLAG)) {
|
||||
val |= NONBLOCK_FLAG;
|
||||
@@ -44,14 +48,14 @@ void set_nonblocking(int fd)
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Set a fd into blocking mode
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Set a fd into blocking mode
|
||||
**/
|
||||
void set_blocking(int fd)
|
||||
{
|
||||
int val;
|
||||
|
||||
if((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
if ((val = fcntl(fd, F_GETFL, 0)) == -1)
|
||||
return;
|
||||
if (val & NONBLOCK_FLAG) {
|
||||
val &= ~NONBLOCK_FLAG;
|
||||
@@ -60,10 +64,11 @@ void set_blocking(int fd)
|
||||
}
|
||||
|
||||
|
||||
/* create a file descriptor pair - like pipe() but use socketpair if
|
||||
possible (because of blocking issues on pipes)
|
||||
|
||||
always set non-blocking
|
||||
/**
|
||||
* Create a file descriptor pair - like pipe() but use socketpair if
|
||||
* possible (because of blocking issues on pipes).
|
||||
*
|
||||
* Always set non-blocking.
|
||||
*/
|
||||
int fd_pair(int fd[2])
|
||||
{
|
||||
@@ -79,12 +84,12 @@ int fd_pair(int fd[2])
|
||||
set_nonblocking(fd[0]);
|
||||
set_nonblocking(fd[1]);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void print_child_argv(char **cmd)
|
||||
void print_child_argv(char **cmd)
|
||||
{
|
||||
rprintf(FINFO, "opening connection using ");
|
||||
for (; *cmd; cmd++) {
|
||||
@@ -104,128 +109,6 @@ static void print_child_argv(char **cmd)
|
||||
}
|
||||
|
||||
|
||||
/* this is derived from CVS code
|
||||
|
||||
note that in the child STDIN is set to blocking and STDOUT
|
||||
is set to non-blocking. This is necessary as rsh relies on stdin being blocking
|
||||
and ssh relies on stdout being non-blocking
|
||||
|
||||
if blocking_io is set then use blocking io on both fds. That can be
|
||||
used to cope with badly broken rsh implementations like the one on
|
||||
solaris.
|
||||
*/
|
||||
pid_t piped_child(char **command, int *f_in, int *f_out)
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int blocking_io;
|
||||
|
||||
if (verbose >= 2) {
|
||||
print_child_argv(command);
|
||||
}
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR, "pipe: %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR, "fork: %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int orig_umask;
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR, "Failed to dup/close : %s\n",
|
||||
strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO)
|
||||
close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO)
|
||||
close(from_child_pipe[1]);
|
||||
umask(orig_umask);
|
||||
set_blocking(STDIN_FILENO);
|
||||
if (blocking_io) {
|
||||
set_blocking(STDOUT_FILENO);
|
||||
}
|
||||
execvp(command[0], command);
|
||||
rprintf(FERROR, "Failed to exec %s : %s\n",
|
||||
command[0], strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR, "Failed to close : %s\n", strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
pid_t local_child(int argc, char **argv,int *f_in,int *f_out)
|
||||
{
|
||||
pid_t pid;
|
||||
int to_child_pipe[2];
|
||||
int from_child_pipe[2];
|
||||
extern int read_batch; /* dw */
|
||||
|
||||
if (fd_pair(to_child_pipe) < 0 ||
|
||||
fd_pair(from_child_pipe) < 0) {
|
||||
rprintf(FERROR,"pipe: %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
|
||||
pid = do_fork();
|
||||
if (pid == -1) {
|
||||
rprintf(FERROR,"fork: %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
extern int am_sender;
|
||||
extern int am_server;
|
||||
|
||||
am_sender = read_batch ? 0 : !am_sender;
|
||||
am_server = 1;
|
||||
|
||||
if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
|
||||
close(to_child_pipe[1]) < 0 ||
|
||||
close(from_child_pipe[0]) < 0 ||
|
||||
dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
|
||||
rprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
|
||||
if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
|
||||
start_server(STDIN_FILENO, STDOUT_FILENO, argc, argv);
|
||||
}
|
||||
|
||||
if (close(from_child_pipe[1]) < 0 ||
|
||||
close(to_child_pipe[0]) < 0) {
|
||||
rprintf(FERROR,"Failed to close : %s\n",strerror(errno));
|
||||
exit_cleanup(RERR_IPC);
|
||||
}
|
||||
|
||||
*f_in = from_child_pipe[0];
|
||||
*f_out = to_child_pipe[1];
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void out_of_memory(char *str)
|
||||
{
|
||||
rprintf(FERROR,"ERROR: out of memory in %s\n",str);
|
||||
@@ -275,14 +158,13 @@ int set_modtime(char *fname, time_t modtime)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
create any necessary directories in fname. Unfortunately we don't know
|
||||
what perms to give the directory when this is called so we need to rely
|
||||
on the umask
|
||||
****************************************************************************/
|
||||
int create_directory_path(char *fname)
|
||||
/**
|
||||
Create any necessary directories in fname. Unfortunately we don't know
|
||||
what perms to give the directory when this is called so we need to rely
|
||||
on the umask
|
||||
**/
|
||||
int create_directory_path(char *fname, int base_umask)
|
||||
{
|
||||
extern int orig_umask;
|
||||
char *p;
|
||||
|
||||
while (*fname == '/') fname++;
|
||||
@@ -291,7 +173,7 @@ int create_directory_path(char *fname)
|
||||
p = fname;
|
||||
while ((p=strchr(p,'/'))) {
|
||||
*p = 0;
|
||||
do_mkdir(fname,0777 & ~orig_umask);
|
||||
do_mkdir(fname, 0777 & ~base_umask);
|
||||
*p = '/';
|
||||
p++;
|
||||
}
|
||||
@@ -299,11 +181,16 @@ int create_directory_path(char *fname)
|
||||
}
|
||||
|
||||
|
||||
/* Write LEN bytes at PTR to descriptor DESC, retrying if interrupted.
|
||||
Return LEN upon success, write's (negative) error code otherwise.
|
||||
|
||||
derived from GNU C's cccp.c.
|
||||
*/
|
||||
/**
|
||||
* Write @p len bytes at @p ptr to descriptor @p desc, retrying if
|
||||
* interrupted.
|
||||
*
|
||||
* @retval len upon success
|
||||
*
|
||||
* @retval <0 write's (negative) error code
|
||||
*
|
||||
* Derived from GNU C's cccp.c.
|
||||
*/
|
||||
static int full_write(int desc, char *ptr, size_t len)
|
||||
{
|
||||
int total_written;
|
||||
@@ -325,11 +212,18 @@ static int full_write(int desc, char *ptr, size_t len)
|
||||
return total_written;
|
||||
}
|
||||
|
||||
/* Read LEN bytes at PTR from descriptor DESC, retrying if interrupted.
|
||||
Return the actual number of bytes read, zero for EOF, or negative
|
||||
for an error.
|
||||
|
||||
derived from GNU C's cccp.c. */
|
||||
/**
|
||||
* Read @p len bytes at @p ptr from descriptor @p desc, retrying if
|
||||
* interrupted.
|
||||
*
|
||||
* @retval >0 the actual number of bytes read
|
||||
*
|
||||
* @retval 0 for EOF
|
||||
*
|
||||
* @retval <0 for an error.
|
||||
*
|
||||
* Derived from GNU C's cccp.c. */
|
||||
static int safe_read(int desc, char *ptr, size_t len)
|
||||
{
|
||||
int n_chars;
|
||||
@@ -349,7 +243,9 @@ static int safe_read(int desc, char *ptr, size_t len)
|
||||
}
|
||||
|
||||
|
||||
/* copy a file - this is used in conjunction with the --temp-dir option */
|
||||
/** Copy a file.
|
||||
*
|
||||
* This is used in conjunction with the --temp-dir option */
|
||||
int copy_file(char *source, char *dest, mode_t mode)
|
||||
{
|
||||
int ifd;
|
||||
@@ -400,18 +296,20 @@ int copy_file(char *source, char *dest, mode_t mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
|
||||
rename to <path>/.rsyncNNN instead. Note that successive rsync runs
|
||||
will shuffle the filenames around a bit as long as the file is still
|
||||
busy; this is because this function does not know if the unlink call
|
||||
is due to a new file coming in, or --delete trying to remove old
|
||||
.rsyncNNN files, hence it renames it each time.
|
||||
*/
|
||||
/* MAX_RENAMES should be 10**MAX_RENAMES_DIGITS */
|
||||
#define MAX_RENAMES_DIGITS 3
|
||||
#define MAX_RENAMES 1000
|
||||
|
||||
/**
|
||||
* Robust unlink: some OS'es (HPUX) refuse to unlink busy files, so
|
||||
* rename to <path>/.rsyncNNN instead.
|
||||
*
|
||||
* Note that successive rsync runs will shuffle the filenames around a
|
||||
* bit as long as the file is still busy; this is because this function
|
||||
* does not know if the unlink call is due to a new file coming in, or
|
||||
* --delete trying to remove old .rsyncNNN files, hence it renames it
|
||||
* each time.
|
||||
**/
|
||||
int robust_unlink(char *fname)
|
||||
{
|
||||
#ifndef ETXTBSY
|
||||
@@ -478,28 +376,48 @@ int robust_rename(char *from, char *to)
|
||||
static pid_t all_pids[10];
|
||||
static int num_pids;
|
||||
|
||||
/* fork and record the pid of the child */
|
||||
/** Fork and record the pid of the child. **/
|
||||
pid_t do_fork(void)
|
||||
{
|
||||
pid_t newpid = fork();
|
||||
|
||||
if (newpid) {
|
||||
if (newpid != 0 && newpid != -1) {
|
||||
all_pids[num_pids++] = newpid;
|
||||
}
|
||||
return newpid;
|
||||
}
|
||||
|
||||
/* kill all children */
|
||||
/**
|
||||
* Kill all children.
|
||||
*
|
||||
* @todo It would be kind of nice to make sure that they are actually
|
||||
* all our children before we kill them, because their pids may have
|
||||
* been recycled by some other process. Perhaps when we wait for a
|
||||
* child, we should remove it from this array. Alternatively we could
|
||||
* perhaps use process groups, but I think that would not work on
|
||||
* ancient Unix versions that don't support them.
|
||||
**/
|
||||
void kill_all(int sig)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<num_pids;i++) {
|
||||
if (all_pids[i] != getpid())
|
||||
kill(all_pids[i], sig);
|
||||
|
||||
for (i = 0; i < num_pids; i++) {
|
||||
/* Let's just be a little careful where we
|
||||
* point that gun, hey? See kill(2) for the
|
||||
* magic caused by negative values. */
|
||||
pid_t p = all_pids[i];
|
||||
|
||||
if (p == getpid())
|
||||
continue;
|
||||
if (p <= 0)
|
||||
continue;
|
||||
|
||||
kill(p, sig);
|
||||
}
|
||||
}
|
||||
|
||||
/* turn a user name into a uid */
|
||||
|
||||
/** Turn a user name into a uid */
|
||||
int name_to_uid(char *name, uid_t *uid)
|
||||
{
|
||||
struct passwd *pass;
|
||||
@@ -512,7 +430,7 @@ int name_to_uid(char *name, uid_t *uid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* turn a group name into a gid */
|
||||
/** Turn a group name into a gid */
|
||||
int name_to_gid(char *name, gid_t *gid)
|
||||
{
|
||||
struct group *grp;
|
||||
@@ -526,7 +444,7 @@ int name_to_gid(char *name, gid_t *gid)
|
||||
}
|
||||
|
||||
|
||||
/* lock a byte range in a open file */
|
||||
/** Lock a byte range in a open file */
|
||||
int lock_range(int fd, int offset, int len)
|
||||
{
|
||||
struct flock lock;
|
||||
@@ -608,13 +526,14 @@ void glob_expand(char *base1, char **argv, int *argc, int maxargs)
|
||||
free(base);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
convert a string to lower case
|
||||
********************************************************************/
|
||||
/**
|
||||
* Convert a string to lower case
|
||||
**/
|
||||
void strlower(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (isupper(*s)) *s = tolower(*s);
|
||||
if (isupper(* (unsigned char *) s))
|
||||
*s = tolower(* (unsigned char *) s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
@@ -668,16 +587,22 @@ void clean_fname(char *name)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* Make path appear as if a chroot had occurred:
|
||||
* 1. remove leading "/" (or replace with "." if at end)
|
||||
* 2. remove leading ".." components (except those allowed by "reldir")
|
||||
* 3. delete any other "<dir>/.." (recursively)
|
||||
*
|
||||
* @li 1. remove leading "/" (or replace with "." if at end)
|
||||
*
|
||||
* @li 2. remove leading ".." components (except those allowed by @p reldir)
|
||||
*
|
||||
* @li 3. delete any other "<dir>/.." (recursively)
|
||||
*
|
||||
* Can only shrink paths, so sanitizes in place.
|
||||
*
|
||||
* While we're at it, remove double slashes and "." components like
|
||||
* clean_fname does(), but DON'T remove a trailing slash because that
|
||||
* clean_fname() does, but DON'T remove a trailing slash because that
|
||||
* is sometimes significant on command line arguments.
|
||||
* If "reldir" is non-null, it is a sanitized directory that the path will be
|
||||
*
|
||||
* If @p reldir is non-null, it is a sanitized directory that the path will be
|
||||
* relative to, so allow as many ".." at the beginning of the path as
|
||||
* there are components in reldir. This is used for symbolic link targets.
|
||||
* If reldir is non-null and the path began with "/", to be completely like
|
||||
@@ -685,9 +610,9 @@ void clean_fname(char *name)
|
||||
* path, but that would blow the assumption that the path doesn't grow and
|
||||
* it is not likely to end up being a valid symlink anyway, so just do
|
||||
* the normal removal of the leading "/" instead.
|
||||
*
|
||||
* Contributed by Dave Dykstra <dwd@bell-labs.com>
|
||||
*/
|
||||
|
||||
void sanitize_path(char *p, char *reldir)
|
||||
{
|
||||
char *start, *sanp;
|
||||
@@ -776,8 +701,10 @@ void sanitize_path(char *p, char *reldir)
|
||||
|
||||
static char curr_dir[MAXPATHLEN];
|
||||
|
||||
/* like chdir() but can be reversed with pop_dir() if save is set. It
|
||||
is also much faster as it remembers where we have been */
|
||||
/**
|
||||
* Like chdir() but can be reversed with pop_dir() if @p save is set.
|
||||
* It is also much faster as it remembers where we have been.
|
||||
**/
|
||||
char *push_dir(char *dir, int save)
|
||||
{
|
||||
char *ret = curr_dir;
|
||||
@@ -808,7 +735,7 @@ char *push_dir(char *dir, int save)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* reverse a push_dir call */
|
||||
/** Reverse a push_dir() call */
|
||||
int pop_dir(char *dir)
|
||||
{
|
||||
int ret;
|
||||
@@ -826,7 +753,7 @@ int pop_dir(char *dir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* we need to supply our own strcmp function for file list comparisons
|
||||
/** We need to supply our own strcmp function for file list comparisons
|
||||
to ensure that signed/unsigned usage is consistent between machines. */
|
||||
int u_strcmp(const char *cs1, const char *cs2)
|
||||
{
|
||||
@@ -840,145 +767,75 @@ int u_strcmp(const char *cs1, const char *cs2)
|
||||
return (int)*s1 - (int)*s2;
|
||||
}
|
||||
|
||||
static OFF_T last_ofs;
|
||||
static struct timeval print_time;
|
||||
static struct timeval start_time;
|
||||
static OFF_T start_ofs;
|
||||
|
||||
static unsigned long msdiff(struct timeval *t1, struct timeval *t2)
|
||||
{
|
||||
return (t2->tv_sec - t1->tv_sec) * 1000
|
||||
+ (t2->tv_usec - t1->tv_usec) / 1000;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param ofs Current position in file
|
||||
* @param size Total size of file
|
||||
* @param is_last True if this is the last time progress will be
|
||||
* printed for this file, so we should output a newline. (Not
|
||||
* necessarily the same as all bytes being received.)
|
||||
* Determine if a symlink points outside the current directory tree.
|
||||
* This is considered "unsafe" because e.g. when mirroring somebody
|
||||
* else's machine it might allow them to establish a symlink to
|
||||
* /etc/passwd, and then read it through a web server.
|
||||
*
|
||||
* Null symlinks and absolute symlinks are always unsafe.
|
||||
*
|
||||
* Basically here we are concerned with symlinks whose target contains
|
||||
* "..", because this might cause us to walk back up out of the
|
||||
* transferred directory. We are not allowed to go back up and
|
||||
* reenter.
|
||||
*
|
||||
* @param dest Target of the symlink in question.
|
||||
*
|
||||
* @param src Top source directory currently applicable. Basically this
|
||||
* is the first parameter to rsync in a simple invocation, but it's
|
||||
* modified by flist.c in slightly complex ways.
|
||||
*
|
||||
* @retval True if unsafe
|
||||
* @retval False is unsafe
|
||||
*
|
||||
* @sa t_unsafe.c
|
||||
**/
|
||||
static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
|
||||
int is_last)
|
||||
int unsafe_symlink(const char *dest, const char *src)
|
||||
{
|
||||
int pct = (ofs == size) ? 100 : (int)((100.0*ofs)/size);
|
||||
unsigned long diff = msdiff(&start_time, now);
|
||||
double rate = diff ? (double) (ofs-start_ofs) * 1000.0 / diff / 1024.0 : 0;
|
||||
const char *units;
|
||||
double remain = rate ? (double) (size-ofs) / rate / 1000.0: 0.0;
|
||||
int remain_h, remain_m, remain_s;
|
||||
|
||||
if (rate > 1024*1024) {
|
||||
rate /= 1024.0 * 1024.0;
|
||||
units = "GB/s";
|
||||
} else if (rate > 1024) {
|
||||
rate /= 1024.0;
|
||||
units = "MB/s";
|
||||
} else {
|
||||
units = "kB/s";
|
||||
}
|
||||
|
||||
remain_s = (int) remain % 60;
|
||||
remain_m = (int) (remain / 60.0) % 60;
|
||||
remain_h = (int) (remain / 3600.0);
|
||||
|
||||
rprintf(FINFO, "%12.0f %3d%% %7.2f%s %4d:%02d:%02d%s",
|
||||
(double) ofs, pct, rate, units,
|
||||
remain_h, remain_m, remain_s,
|
||||
is_last ? "\n" : "\r");
|
||||
}
|
||||
|
||||
void end_progress(OFF_T size)
|
||||
{
|
||||
extern int do_progress, am_server;
|
||||
|
||||
if (do_progress && !am_server) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
rprint_progress(size, size, &now, True);
|
||||
}
|
||||
last_ofs = 0;
|
||||
start_ofs = 0;
|
||||
print_time.tv_sec = print_time.tv_usec = 0;
|
||||
start_time.tv_sec = start_time.tv_usec = 0;
|
||||
}
|
||||
|
||||
void show_progress(OFF_T ofs, OFF_T size)
|
||||
{
|
||||
extern int do_progress, am_server;
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
if (!start_time.tv_sec && !start_time.tv_usec) {
|
||||
start_time.tv_sec = now.tv_sec;
|
||||
start_time.tv_usec = now.tv_usec;
|
||||
start_ofs = ofs;
|
||||
}
|
||||
|
||||
if (do_progress
|
||||
&& !am_server
|
||||
&& ofs > last_ofs + 1000
|
||||
&& msdiff(&print_time, &now) > 250) {
|
||||
rprint_progress(ofs, size, &now, False);
|
||||
last_ofs = ofs;
|
||||
print_time.tv_sec = now.tv_sec;
|
||||
print_time.tv_usec = now.tv_usec;
|
||||
}
|
||||
}
|
||||
|
||||
/* determine if a symlink points outside the current directory tree */
|
||||
int unsafe_symlink(char *dest, char *src)
|
||||
{
|
||||
char *tok;
|
||||
const char *name, *slash;
|
||||
int depth = 0;
|
||||
|
||||
/* all absolute and null symlinks are unsafe */
|
||||
if (!dest || !(*dest) || (*dest == '/')) return 1;
|
||||
|
||||
src = strdup(src);
|
||||
if (!src) out_of_memory("unsafe_symlink");
|
||||
if (!dest || !*dest || *dest == '/') return 1;
|
||||
|
||||
/* find out what our safety margin is */
|
||||
for (tok=strtok(src,"/"); tok; tok=strtok(NULL,"/")) {
|
||||
if (strcmp(tok,"..") == 0) {
|
||||
for (name = src; (slash = strchr(name, '/')) != 0; name = slash+1) {
|
||||
if (strncmp(name, "../", 3) == 0) {
|
||||
depth=0;
|
||||
} else if (strcmp(tok,".") == 0) {
|
||||
} else if (strncmp(name, "./", 2) == 0) {
|
||||
/* nothing */
|
||||
} else {
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
free(src);
|
||||
if (strcmp(name, "..") == 0)
|
||||
depth = 0;
|
||||
|
||||
/* drop by one to account for the filename portion */
|
||||
depth--;
|
||||
|
||||
dest = strdup(dest);
|
||||
if (!dest) out_of_memory("unsafe_symlink");
|
||||
|
||||
for (tok=strtok(dest,"/"); tok; tok=strtok(NULL,"/")) {
|
||||
if (strcmp(tok,"..") == 0) {
|
||||
depth--;
|
||||
} else if (strcmp(tok,".") == 0) {
|
||||
for (name = dest; (slash = strchr(name, '/')) != 0; name = slash+1) {
|
||||
if (strncmp(name, "../", 3) == 0) {
|
||||
/* if at any point we go outside the current directory
|
||||
then stop - it is unsafe */
|
||||
if (--depth < 0)
|
||||
return 1;
|
||||
} else if (strncmp(name, "./", 2) == 0) {
|
||||
/* nothing */
|
||||
} else {
|
||||
depth++;
|
||||
}
|
||||
/* if at any point we go outside the current directory then
|
||||
stop - it is unsafe */
|
||||
if (depth < 0) break;
|
||||
}
|
||||
if (strcmp(name, "..") == 0)
|
||||
depth--;
|
||||
|
||||
free(dest);
|
||||
return (depth < 0);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
return the date and time as a string
|
||||
****************************************************************************/
|
||||
/**
|
||||
* Return the date and time as a string
|
||||
**/
|
||||
char *timestring(time_t t)
|
||||
{
|
||||
static char TimeBuf[200];
|
||||
@@ -1028,12 +885,17 @@ int msleep(int t)
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Determine if two file modification times are equivalent (either exact
|
||||
or in the modification timestamp window established by --modify-window)
|
||||
Returns 0 if the times should be treated as the same, 1 if the
|
||||
first is later and -1 if the 2nd is later
|
||||
*******************************************************************/
|
||||
/**
|
||||
* Determine if two file modification times are equivalent (either
|
||||
* exact or in the modification timestamp window established by
|
||||
* --modify-window).
|
||||
*
|
||||
* @retval 0 if the times should be treated as the same
|
||||
*
|
||||
* @retval +1 if the first is later
|
||||
*
|
||||
* @retval -1 if the 2nd is later
|
||||
**/
|
||||
int cmp_modtime(time_t file1, time_t file2)
|
||||
{
|
||||
extern int modify_window;
|
||||
@@ -1050,11 +912,11 @@ int cmp_modtime(time_t file1, time_t file2)
|
||||
#ifdef __INSURE__XX
|
||||
#include <dlfcn.h>
|
||||
|
||||
/*******************************************************************
|
||||
This routine is a trick to immediately catch errors when debugging
|
||||
with insure. A xterm with a gdb is popped up when insure catches
|
||||
a error. It is Linux specific.
|
||||
********************************************************************/
|
||||
/**
|
||||
This routine is a trick to immediately catch errors when debugging
|
||||
with insure. A xterm with a gdb is popped up when insure catches
|
||||
a error. It is Linux specific.
|
||||
**/
|
||||
int _Insure_trap_error(int a1, int a2, int a3, int a4, int a5, int a6)
|
||||
{
|
||||
static int (*fn)();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
READ THIS BEFORE TRYING TO DYNAMICALLY LINK RSYNC AND ZLIB!
|
||||
|
||||
zlib has been adapted slightly for use in rsync. Please don't bother
|
||||
the zlib authors with problems related to the use of zlib in rsync as
|
||||
any bugs are likely to be our fault and not theirs.
|
||||
@@ -15,5 +17,15 @@ Specific changes that have been made to zlib for rsync include:
|
||||
- include rsync.h to ensure that we get a consistent set of includes
|
||||
for all C code in rsync and to take advantage of autoconf
|
||||
|
||||
--
|
||||
Paul Mackerras and Andrew Tridgell
|
||||
As a result of the first item, the streams from rsync's version of
|
||||
zlib are *not compatible* with those produced by the upstream version
|
||||
of rsync. In other words, if you link rsync against your system's
|
||||
copy, it will not be able to interoperate with any other version if
|
||||
the -z option is used. (Sorry. Sometimes standard is better than
|
||||
better.)
|
||||
|
||||
The rsync maintainers hope to fix this problem in the future by either
|
||||
merging our changes into the upstream version, or backing them out of
|
||||
rsync in a way that preserves wire compatibility. But in the meantime
|
||||
this version must be maintained in parallel.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user