Compare commits

..

3 Commits

Author SHA1 Message Date
Martin Pool
461c6de1a8 Bump version to 2.3.3. 2002-01-25 23:31:06 +00:00
Martin Pool
9c380e07ef Bump version to 2.3.3pre1. 2002-01-25 07:06:33 +00:00
Martin Pool
61ea0c9d9b Merge signedness security patch from Sebastian Krahmer
<krahmer@suse.de> -- in some cases we were not sufficiently careful
about reading integers from the network.

Possibly some other changes are required.
2002-01-25 03:13:35 +00:00
216 changed files with 15929 additions and 51399 deletions

18
.cvsignore Normal file
View File

@@ -0,0 +1,18 @@
ID
Makefile
config.cache
config.h
config.log
config.status
gmon.out
rsync
shconfig
testdir
tests-dont-exist
testtmp
testtmp.*
tls
zlib/dummy
confdefs.h
conftest.c
conftest.log

37
.gitignore vendored
View File

@@ -1,37 +0,0 @@
*.[oa]
*~
dummy
ID
Makefile
configure.sh
config.cache
config.h
config.h.in
config.log
config.status
/proto.h
/proto.h-tstamp
/rsync.1
/rsyncd.conf.5
/autom4te*.cache
/confdefs.h
/conftest*
/dox
/getgroups
/gmon.out
/rsync
/shconfig
/testdir
/tests-dont-exist
/testtmp
/tls
/trimslash
/t_unsafe
/wildtest
/getfsdev
/rounding.h
/doc/rsync.pdf
/doc/rsync.ps
/testsuite/chown-fake.test
/testsuite/devices-fake.test
/patches

19
.ignore Normal file
View File

@@ -0,0 +1,19 @@
.#*
*.log
Makefile
config.h
*.o
CVS
.ignore
.cvsignore
*~
rsync
config.status
config.cache
TAGS
config.log
test
*.gz
rsync-*
*.dvi
*.aux

885
COPYING
View File

@@ -1,626 +1,285 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
13. Use with the GNU Affero General Public License.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
14. Revised Versions of this License.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
NO WARRANTY
15. Disclaimer of Warranty.
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -628,15 +287,15 @@ free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
Copyright (C) 19yy <name of author>
This program is free software: you can redistribute it and/or modify
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 3 of the License, or
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,
@@ -645,30 +304,36 @@ the "copyright" line and a pointer to where the full notice is found.
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, see <http://www.gnu.org/licenses/>.
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

187
Doxyfile
View File

@@ -1,187 +0,0 @@
# 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 =

41
INSTALL
View File

@@ -1,4 +1,4 @@
To build and install rsync:
To build and install rsync
$ ./configure
$ make
@@ -9,28 +9,12 @@ to ./configure. To see them, use:
$ ./configure --help
Configure tries to figure out if the local system uses group "nobody" or
"nogroup" by looking in the /etc/group file. (This is only used for the
default group of an rsync daemon, which attempts to run with "nobody"
user and group permissions.) You can change the default user and group
for the daemon by editing the NOBODY_USER and NOBODY_GROUP defines in
config.h, or just override them in your /etc/rsyncd.conf file.
As of 2.4.7, rsync uses Eric Troan's popt option-parsing library. A
cut-down copy of release 1.6.4 is included in the rsync distribution,
and will be used if there is no popt library on your build host, or if
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.
RPM NOTES
---------
Under packaging you will find .spec files for several distributions.
The .spec file in packaging/lsb can be used for Linux systems that
adhere to the Linux Standards Base (e.g., RedHat and others).
HP-UX NOTES
-----------
@@ -43,21 +27,16 @@ fails:
Install gcc or HP's "ANSI/C Compiler".
MAC OSX NOTES
-------------
Some versions of Mac OS X (Darwin) seem to have an IPv6 stack, but do
not completely implement the "New Sockets" API.
Mac OS X (Darwin) seems to have an IPv6 stack, but it does not
completely implement the "New Sockets" API.
<http://www.ipv6.org/impl/mac.html> says that Apple do not support
IPv6 yet. If your build fails, try again with --disable-ipv6.
<http://www.ipv6.org/impl/mac.html> says that Apple started to support
IPv6 in 10.2 (Jaguar). If your build fails, try again after running
configure with --disable-ipv6.
IBM AIX NOTES
-------------
IBM AIX has a largefile problem with mkstemp. See IBM PR-51921.
The workaround is to append the below to config.h
#ifdef _LARGE_FILES
#undef HAVE_SECURE_MKSTEMP
#endif

View File

@@ -2,7 +2,6 @@
# Makefile
prefix=@prefix@
datarootdir=@datarootdir@
exec_prefix=@exec_prefix@
bindir=@bindir@
mandir=@mandir@
@@ -10,12 +9,9 @@ mandir=@mandir@
LIBS=@LIBS@
CC=@CC@
CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
EXEEXT=@EXEEXT@
LDFLAGS=@LDFLAGS@
INSTALLCMD=@INSTALL@
INSTALLMAN=@INSTALL@
srcdir=@srcdir@
VPATH=$(srcdir)
@@ -26,161 +22,78 @@ VERSION=@VERSION@
.SUFFIXES:
.SUFFIXES: .c .o
GENFILES=configure.sh config.h.in proto.h proto.h-tstamp rsync.1 rsyncd.conf.5
HEADERS=byteorder.h config.h errcode.h proto.h rsync.h ifuncs.h lib/pool_alloc.h
LIBOBJ=lib/wildmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o lib/md5.o \
lib/permstring.o lib/pool_alloc.o lib/sysacls.o lib/sysxattrs.o @LIBOBJS@
ZLIBOBJ=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \
zlib/trees.o zlib/zutil.o zlib/adler32.o zlib/compress.o zlib/crc32.o
OBJS1=flist.o 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 io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \
fileio.o batch.o clientname.o chmod.o acls.o xattrs.o
OBJS3=progress.o pipe.o
LIBOBJ=lib/fnmatch.o lib/compat.o lib/snprintf.o lib/mdfour.o \
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
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) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
OBJS=$(OBJS1) $(OBJS2) $(DAEMON_OBJ) $(LIBOBJ) $(ZLIBOBJ) @BUILD_POPT@
TLS_OBJ = tls.o syscall.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@
tls_OBJ = tls.o syscall.o lib/permstring.o
# Programs we must have to run the test cases
CHECK_PROGS = rsync$(EXEEXT) tls$(EXEEXT) getgroups$(EXEEXT) getfsdev$(EXEEXT) \
trimslash$(EXEEXT) t_unsafe$(EXEEXT) wildtest$(EXEEXT)
CHECK_SYMLINKS = testsuite/chown-fake.test testsuite/devices-fake.test
# Objects for CHECK_PROGS to clean
CHECK_OBJS=tls.o getgroups.o getfsdev.o t_stub.o t_unsafe.o trimslash.o wildtest.o
CHECK_PROGS = rsync tls
# note that the -I. is needed to handle config.h when using VPATH
.c.o:
@OBJ_SAVE@
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -c $< @CC_SHOBJ_FLAG@
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< @CC_SHOBJ_FLAG@
@OBJ_RESTORE@
all: conf_stop make_stop rsync$(EXEEXT) @MAKE_MAN@
install: all
-mkdir -p ${DESTDIR}${bindir}
${INSTALLCMD} ${INSTALL_STRIP} -m 755 rsync$(EXEEXT) ${DESTDIR}${bindir}
-mkdir -p ${DESTDIR}${mandir}/man1
-mkdir -p ${DESTDIR}${mandir}/man5
if test -f $(srcdir)/rsync.1; then ${INSTALLMAN} -m 644 $(srcdir)/rsync.1 ${DESTDIR}${mandir}/man1; fi
if test -f $(srcdir)/rsyncd.conf.5; then ${INSTALLMAN} -m 644 $(srcdir)/rsyncd.conf.5 ${DESTDIR}${mandir}/man5; fi
install-strip:
$(MAKE) INSTALL_STRIP='-s' install
rsync$(EXEEXT): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
$(OBJS): $(HEADERS)
$(CHECK_OBJS): $(HEADERS)
flist.o: rounding.h
rounding.h: rounding.c rsync.h
@for r in 0 1 3; do \
if $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o rounding -DEXTRA_ROUNDING=$$r -I. $(srcdir)/rounding.c >rounding.out 2>&1; then \
echo "#define EXTRA_ROUNDING $$r" >rounding.h; \
if test -f "$$HOME/build_farm/build_test.fns"; then \
echo "EXTRA_ROUNDING is $$r" >&2; \
fi; \
break; \
fi; \
done
@rm -f rounding
@if test -f rounding.h; then : ; else \
cat rounding.out 1>&2; \
echo "Failed to create rounding.h!" 1>&2; \
exit 1; \
fi
@rm -f rounding.out
tls$(EXEEXT): $(TLS_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(TLS_OBJ) $(LIBS)
getgroups$(EXEEXT): getgroups.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getgroups.o $(LIBS)
getfsdev$(EXEEXT): getfsdev.o
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ getfsdev.o $(LIBS)
TRIMSLASH_OBJ = trimslash.o syscall.o lib/compat.o lib/snprintf.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 lib/wildmatch.o
t_unsafe$(EXEEXT): $(T_UNSAFE_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_UNSAFE_OBJ) $(LIBS)
gen: conf proto.h man
gensend: gen
rsync -aivzc $(GENFILES) samba.org:/home/ftp/pub/rsync/generated-files/
conf:
cd $(srcdir) && $(MAKE) -f prepare-source.mak conf
conf_stop: configure.sh config.h.in
configure.sh config.h.in: configure.in aclocal.m4
autoconf -o configure.sh
autoheader && touch config.h.in
@echo 'Configure files changed -- perhaps run:'
@echo ' make reconfigure'
@exit 1
reconfigure: configure.sh
./config.status --recheck
./config.status
make_stop: Makefile
Makefile: Makefile.in config.status
@./config.status
@echo "Makefile updated -- rerun your make command."
@exit 1
proto: proto.h-tstamp
proto.h: proto.h-tstamp
@echo ' ' >/dev/null
proto.h-tstamp: $(srcdir)/*.c $(srcdir)/lib/compat.c
perl $(srcdir)/mkproto.pl $(srcdir)/*.c $(srcdir)/lib/compat.c
all: rsync
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
install-strip:
$(MAKE) INSTALLCMD='$(INSTALLCMD) -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)
$(OBJS): config.h
tls: $(tls_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(tls_OBJ) $(LIBS)
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"
rsync.1: rsync.yo
yodl2man -o rsync.1 $(srcdir)/rsync.yo
-$(srcdir)/tweak_manpage rsync.1
yodl2man -o rsync.1 rsync.yo
rsyncd.conf.5: rsyncd.conf.yo
yodl2man -o rsyncd.conf.5 $(srcdir)/rsyncd.conf.yo
-$(srcdir)/tweak_manpage rsyncd.conf.5
yodl2man -o rsyncd.conf.5 rsyncd.conf.yo
clean: cleantests
rm -f *~ $(OBJS) $(CHECK_PROGS) $(CHECK_OBJS) $(CHECK_SYMLINKS) \
rounding rounding.h
proto:
cat *.c lib/compat.c | awk -f mkproto.awk > proto.h
cleantests:
rm -rf ./testtmp*
clean:
rm -f *~ $(OBJS) rsync $(TLS_OBJ) tls
rm -rf ./testtmp
rm -f config.cache
# 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 lib/dummy popt/dummy zlib/dummy
rm -f $(srcdir)/Makefile $(srcdir)/config.h $(srcdir)/config.status
rm -f $(srcdir)/lib/dummy $(srcdir)/popt/dummy $(srcdir)/zlib/dummy
rm -f config.cache config.log
rm -f $(srcdir)/config.cache $(srcdir)/config.log
rm -f shconfig $(srcdir)/shconfig
rm -f $(GENFILES)
rm -rf autom4te.cache
# 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
@@ -188,16 +101,20 @@ 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
test: check
# There seems to be no standard way to specify some variables as
# exported from a Makefile apart from listing them like this.
# TODO: Tests that depend on built test aide programs like tls need to
# know where the build directory is.
# This depends on building rsync; if we need any helper programs it
# should depend on them too.
@@ -205,51 +122,14 @@ test: check
# catch Bash-isms earlier even if we're running on GNU. Of course, we
# might lose in the future where POSIX diverges from old sh.
check: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh
check29: all $(CHECK_PROGS) $(CHECK_SYMLINKS)
rsync_bin=`pwd`/rsync$(EXEEXT) $(srcdir)/runtests.sh --protocol=29
wildtest.o: wildtest.c lib/wildmatch.c rsync.h config.h
wildtest$(EXEEXT): wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ wildtest.o lib/compat.o lib/snprintf.o @BUILD_POPT@ $(LIBS)
testsuite/chown-fake.test:
ln -s chown.test $(srcdir)/testsuite/chown-fake.test
testsuite/devices-fake.test:
ln -s devices.test $(srcdir)/testsuite/devices-fake.test
check: all $(CHECK_PROGS)
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin=`pwd`/rsync 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) $(CHECK_SYMLINKS)
POSIXLY_CORRECT=1 TOOLDIR=`pwd` rsync_bin="$(bindir)/rsync$(EXEEXT)" srcdir="$(srcdir)" $(srcdir)/runtests.sh
installcheck: $(CHECK_PROGS)
POSIXLY_CORRECT=1 TLS=`pwd`/tls rsync_bin="$(bindir)/rsync" 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
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/

21
NEWS
View File

@@ -1,18 +1,7 @@
NEWS for rsync 3.0.2 (8 Apr 2008)
Protocol: 30 (unchanged)
Changes since 3.0.1:
rsync 2.3.3 (26 Jan 2002)
BUG FIXES:
SECURITY FIXES:
- Fixed a potential buffer overflow in the xattr code.
ENHANCEMENTS:
- None.
DEVELOPER RELATED:
- The RPM spec file was improved to install more useful files.
- A few developer-oriented scripts were moved from the support dir
to the packaging dir.
* Signedness security patch from Sebastian Krahmer
<krahmer@suse.de> -- in some cases we were not sufficiently
careful about reading integers from the network.

2655
OLDNEWS
View File

File diff suppressed because it is too large Load Diff

106
README
View File

@@ -1,7 +1,7 @@
WHAT IS RSYNC?
--------------
rsync is a replacement for scp/rcp that has many more features.
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
@@ -18,20 +18,81 @@ this package.
USAGE
-----
Basically you use rsync just like rcp, but rsync has many additional
options. To get a complete list of supported options type
Basically you use rsync just like rcp, but rsync has many additional options.
rsync --help
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
and see the manual for more information.
SETUP
-----
Rsync normally uses ssh or rsh for communication. It does not need to
Rsync normally uses rsh or ssh for communication. It does not need to
be setuid and requires no special privileges for installation. You
must, however, have a working ssh or rsh system. Using ssh is
must, however, have a working rsh or ssh system. Using ssh is
recommended for its security features.
Alternatively, rsync can run in `daemon' mode, listening on a socket.
@@ -51,13 +112,13 @@ case.
Once built put a copy of rsync in your search path on the local and
remote systems (or use "make install"). That's it!
RSYNC DAEMONS
RSYNC SERVERS
-------------
rsync can also talk to "rsync daemons" which can provide anonymous or
rsync can also talk to "rsync servers" which can provide anonymous or
authenticated rsync. See the rsyncd.conf(5) man page for details on how
to setup an rsync daemon. See the rsync(1) man page for info on how to
connect to an rsync daemon.
to setup a rsync server. See the rsync(1) man page for info on how to
connect to a rsync server.
MAILING LIST
@@ -69,28 +130,20 @@ versions on this list.
To join the mailing list see the web page at http://lists.samba.org/
To send mail to everyone on the list send it to rsync@lists.samba.org
To send mail to everyone on the list send it to rsync@samba.org
BUG REPORTS
-----------
If you have web access then please look at
http://rsync.samba.org/rsync/
http://rsync.samba.org/
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.
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/
To send a bug report, follow the instructions on the bug-tracking
page of the web site.
If you don't have web access, email your bug report to
rsync@lists.samba.org.
If you don't have web access then mail bug reports to rsync@samba.org.
CVS TREE
@@ -105,7 +158,8 @@ recent version of cvs then use the following commands:
cvs -d :pserver:cvs@pserver.samba.org:/cvsroot co rsync
Look at the cvs documentation for more details.
Look at the cvs documentation, or http://samba.org/cvs.html, for more
details.
COPYRIGHT

665
TODO
View File

@@ -1,65 +1,22 @@
-*- indented-text -*-
FEATURES ------------------------------------------------------------
Use chroot only if supported
Allow supplementary groups in rsyncd.conf 2002/04/09
Handling IPv6 on old machines
Other IPv6 stuff
Add ACL support 2001/12/02
proxy authentication 2002/01/23
SOCKS 2002/01/23
FAT support
--diff david.e.sewell 2002/03/15
Add daemon --no-fork option
Create more granular verbosity 2003/05/15
DOCUMENTATION --------------------------------------------------------
Keep list of open issues and todos on the web site
Perhaps redo manual as SGML
LOGGING --------------------------------------------------------------
Memory accounting
Improve error messages
Better statistics Rasmus 2002/03/08
Perhaps flush stdout like syslog
Log child death on signal
verbose output David Stein 2001/12/20
internationalization
DEVELOPMENT --------------------------------------------------------
Handling duplicate names
Use generic zlib 2002/02/25
TDB 2002/03/12
Splint 2002/03/12
PERFORMANCE ----------------------------------------------------------
Traverse just one directory at a time
Allow skipping MD4 file_sum 2002/04/08
Accelerate MD4
TESTING --------------------------------------------------------------
Torture test
Cross-test versions 2001/08/22
Test on kernel source
Test large files
Create mutator program for testing
Create configure option to enable dangerous tests
Create pipe program for testing
Create test makefile target for some tests
RELATED PROJECTS -----------------------------------------------------
rsyncsh
http://rsync.samba.org/rsync-and-debian/
rsyncable gzip patch
rsyncsplit as alternative to real integration with gzip?
reverse rsync over HTTP Range
URGENT ---------------------------------------------------------------
IMPORTANT ------------------------------------------------------------
FEATURES ------------------------------------------------------------
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.
Use chroot only if supported
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.
use chroot
If the platform doesn't support it, then don't even try.
@@ -69,51 +26,147 @@ Use chroot only if supported
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.
Allow supplementary groups in rsyncd.conf 2002/04/09
Performance
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.
Traverse just one directory at a time. Tridge says it's possible.
-- --
At the moment rsync reads the whole file list into memory at the
start, which makes us use a lot of memory and also not pipeline
network access as much as we could.
Handling IPv6 on old machines
Handling duplicate names
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.
We need to be careful of duplicate names getting into the file list.
See clean_flist(). This could happen if multiple arguments include
the same file. Bad.
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.
I think duplicates are only a problem if they're both flowing
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.
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.
Possibly if we did one directory at a time that would be sufficient.
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.
Alternatively we could pre-process the arguments to make sure no
duplicates will ever be inserted. There could be some bad cases
when we're collapsing symlinks.
We could drop the rather large lib/getaddrinfo files.
We could have a hash table.
-- --
The root of the problem is that we do not want more than one file
list entry referring to the same file. At first glance there are
several ways this could happen: symlinks, hardlinks, and repeated
names on the command line.
If names are repeated on the command line, they may be present in
different forms, perhaps by traversing directory paths in different
ways, traversing paths including symlinks. Also we need to allow
for expansion of globs by rsync.
At the moment, clean_flist() requires having the entire file list in
memory. Duplicate names are detected just by a string comparison.
We don't need to worry about hard links causing duplicates because
files are never updated in place. Similarly for symlinks.
I think even if we're using a different symlink mode we don't need
to worry.
Unless we're really clever this will introduce a protocol
incompatibility, so we need to be able to accept the old format as
well.
Other IPv6 stuff
Memory accounting
At exit, show how much memory was used for the file list, etc.
Also we do a wierd exponential-growth allocation in flist.c. I'm
not sure this makes sense with modern mallocs. At any rate it will
make us allocate a huge amount of memory for large file lists.
We can try using the GNU/SVID/XPG mallinfo() function to get some
heap statistics.
Hard-link handling
At the moment hardlink handling is very expensive, so it's off by
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
hardlinks is possibly simpler.
We can rule out hardlinked directories since they will probably
screw us up in all kinds of ways. They simply should not be used.
At the moment rsync only cares about hardlinks to regular files. I
guess you could also use them for sockets, devices and other beasts,
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).
The basic point of this is to discover alternate names that refer to
the same file. All operations, including creating the file and
writing modifications to it need only to be done for the first name.
For all later names, we just create the link and then leave it
alone.
If hard links are to be preserved:
Before the generator/receiver fork, the list of files is received
from the sender (recv_file_list), and a table for detecting hard
links is built.
The generator looks for hard links within the file list and does
not send checksums for them, though it does send other metadata.
The sender sends the device number and inode with file entries, so
that files are uniquely identified.
The receiver goes through and creates hard links (do_hard_links)
after all data has been written, but before directory permissions
are set.
At the moment device and inum are sent as 4-byte integers, which
will probably cause problems on large filesystems. On Linux the
kernel uses 64-bit ino_t's internally, and people will soon have
filesystems big enough to use them. We ought to follow NFS4 in
using 64-bit device and inode identification, perhaps with a
protocol version bump.
Once we've seen all the names for a particular file, we no longer
need to think about it and we can deallocate the memory.
We can also have the case where there are links to a file that are
not in the tree being transferred. There's nothing we can do about
that. Because we rename the destination into place after writing,
any hardlinks to the old file are always going to be orphaned. In
fact that is almost necessary because otherwise we'd get really
confused if we were generating checksums for one name of a file and
modifying another.
At the moment the code seems to make a whole second copy of the file
list, which seems unnecessary.
We should have a test case that exercises hard links. Since it
might be hard to compare ./tls output where the inodes change we
might need a little program to check whether several names refer to
the same file.
IPv6
Implement suggestions from http://www.kame.net/newsletter/19980604/
and ftp://ftp.iij.ad.jp/pub/RFC/rfc2553.txt
@@ -125,125 +178,16 @@ Other IPv6 stuff
multiple passive addresses. This might be a bit harder, because we
may need to select on all of them. Hm.
-- --
Define a syntax for IPv6 literal addresses. Since they include
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
which should just take a small change to the parser code.
Add ACL support 2001/12/02
Transfer ACLs. Need to think of a standard representation.
Probably better not to even try to convert between NT and POSIX.
Possibly can share some code with Samba.
NOTE: there is a patch that implements this in the "patches" subdir.
-- --
proxy authentication 2002/01/23
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
HTTP Basic Proxy-Authentication.
Multiple schemes are possible, up to and including the insanity that
is NTLM, but Basic probably covers most cases.
-- --
SOCKS 2002/01/23
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.
-- --
--diff david.e.sewell 2002/03/15
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?
-- --
Add daemon --no-fork option
Very useful for debugging. Also good when running under a
daemon-monitoring process that tries to restart the service when the
parent exits.
-- --
Create more granular verbosity 2003/05/15
Control output with the --report option.
The option takes as a single argument (no whitespace) a
comma delimited lists of keywords.
This would separate debugging from "logging" as well as
fine grained selection of statistical reporting and what
actions are logged.
http://lists.samba.org/archive/rsync/2003-May/006059.html
-- --
DOCUMENTATION --------------------------------------------------------
Keep list of open issues and todos on the web site
-- --
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.
-- --
LOGGING --------------------------------------------------------------
Memory accounting
At exit, show how much memory was used for the file list, etc.
Also we do a wierd exponential-growth allocation in flist.c. I'm
not sure this makes sense with modern mallocs. At any rate it will
make us allocate a huge amount of memory for large file lists.
-- --
Improve error messages
Errors
If we hang or get SIGINT, then explain where we were up to. Perhaps
have a static buffer that contains the current function name, or
@@ -252,239 +196,109 @@ Improve error messages
"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.
File attributes
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.
Device major/minor numbers should be at least 32 bits each. See
http://lists.samba.org/pipermail/rsync/2001-November/005357.html
-- --
Transfer ACLs. Need to think of a standard representation.
Probably better not to even try to convert between NT and POSIX.
Possibly can share some code with Samba.
Empty directories
Better statistics Rasmus 2002/03/08
With the current common --include '*/' --exclude '*' pattern, people
can end up with many empty directories. We might avoid this by
lazily creating such directories.
<Rasmus>
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. ?
zlib
<mbp>
nice idea there is --stats but at the moment it's very
tridge-oriented rather than user-friendly it would be
nice to improve it that would also work well with
--dryrun
Perhaps don't use our own zlib. Will we actually be incompatible,
or just be slightly less efficient?
-- --
Perhaps flush stdout like syslog
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.
rsyncd over ssh
Log child death on signal
There are already some patches to do this.
If a child of the rsync daemon dies with a signal, we should notice
that when we reap it and log a message.
proxy authentication
-- --
Allow RSYNC_PROXY to be http://user:pass@proxy.foo:3128/, and do
HTTP Basic Proxy-Authentication.
Multiple schemes are possible, up to and including the insanity that
is NTLM, but Basic probably covers most cases.
verbose output David Stein 2001/12/20
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.
PLATFORMS ------------------------------------------------------------
Win32
Don't detach, because this messes up --srvany.
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.
DOCUMENTATION --------------------------------------------------------
Update README
BUILD FARM -----------------------------------------------------------
Add machines
AMDAHL UTS (Dave Dykstra)
Cygwin (on different versions of Win32?)
HP-UX variants (via HP?)
SCO
NICE -----------------------------------------------------------------
--no-detach and --no-fork options
Very useful for debugging. Also good when running under a
daemon-monitoring process that tries to restart the service when the
parent exits.
hang/timeout friendliness
verbose output
At end of transfer, show how many files were or were not transferred
correctly.
-- --
Indicate whether files are new, updated, or deleted
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? 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.
Does anyone care?
-- --
DEVELOPMENT --------------------------------------------------------
Handling duplicate names
Some folks would like rsync to be deterministic in how it handles
duplicate names that come from mering multiple source directories
into a single destination directory; e.g. the last name wins. We
could do this by switching our sort algorithm to one that will
guarantee that the names won't be reordered. Alternately, we could
assign an ever-increasing number to each item as we insert it into
the list and then make sure that we leave the largest number when
cleaning the file list (see clean_flist()). Another solution would
be to add a hash table, and thus never put any duplicate names into
the file list (and bump the protocol to handle this).
-- --
Use generic zlib 2002/02/25
Perhaps don't use our own zlib.
Advantages:
- will automatically be up to date with bugfixes in zlib
- can leave it out for small rsync on e.g. recovery disks
- can use a shared library
- avoids people breaking rsync by trying to do this themselves and
messing up
Should we ship zlib for systems that don't have it, or require
people to install it separately?
Apparently this will make us incompatible with versions of rsync
that use the patched version of rsync. Probably the simplest way to
do this is to just disable gzip (with a warning) when talking to old
versions.
-- --
Splint 2002/03/12
Build rsync with SPLINT to try to find security holes. Add
annotations as necessary. Keep track of the number of warnings
found initially, and see how many of them are real bugs, or real
security bugs. Knowing the percentage of likely hits would be
really interesting for other projects.
-- --
PERFORMANCE ----------------------------------------------------------
Allow skipping MD4 file_sum 2002/04/08
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.
We should not allow it to be disabled separately from -W, though
as it is the only thing that lets us know when the rsync algorithm
got out of sync and messed the file up (i.e. if the basis file
changed between checksum generation and reception).
-- --
Accelerate 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?
-- --
TESTING --------------------------------------------------------------
Torture test
Something that just keeps running rsync continuously over a data set
likely to generate problems.
-- --
Cross-test versions 2001/08/22
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.
Run current rsync versions against significant past releases.
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.
The new --protocol option may help in this.
-- --
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
-- --
Create mutator program for testing
Insert bytes, delete bytes, swap blocks, ...
-- --
Create configure option to enable dangerous tests
-- --
Create pipe program for testing
Create pipe program that makes slow/jerky connections for
testing Versions of read() and write() that corrupt the
stream, or abruptly fail
-- --
Create test makefile target for some tests
Separate makefile target to run rough tests -- or perhaps
just run them every time?
-- --
RELATED PROJECTS -----------------------------------------------------
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
@@ -492,37 +306,4 @@ rsyncsh
current host, directory and so on. We can probably even do
completion of remote filenames.
-- --
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.
Addendum: It looks like someone is working on a version of this:
http://zsync.moria.org.uk/
-- --
%K%

280
access.c
View File

@@ -1,213 +1,83 @@
/*
Copyright (C) Andrew Tridgell 1998
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.
*/
/*
* Routines to authenticate access to a daemon (hosts allow/deny).
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
hosts allow/deny code for rsync
*/
#include "rsync.h"
static int match_hostname(char *host, char *tok)
{
if (!host || !*host)
return 0;
return wildmatch(tok, host);
if (!host || !*host) return 0;
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;
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;
unsigned int len;
unsigned long a, t, mask = (unsigned long)~0;
if (!addr || !*addr)
return 0;
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);
if (p) {
*p = '\0';
len = p - tok;
} else
len = strlen(tok);
*p = '/';
}
/* Fail quietly if tok is a hostname (not an address) */
if (strspn(tok, ".0123456789") != len
#ifdef INET6
&& strchr(tok, ':') == NULL
#endif
) {
if (p)
*p = '/';
if (t == INADDR_NONE) {
rprintf(FERROR,"malformed address %s\n", tok);
return 0;
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
#ifdef AI_NUMERICHOST
hints.ai_flags = AI_NUMERICHOST;
#endif
a = ntohl(a);
t = ntohl(t);
if (getaddrinfo(addr, NULL, &hints, &resa) != 0) {
if (p)
*p = '/';
return 0;
}
gai = getaddrinfo(tok, NULL, &hints, &rest);
if (p)
*p++ = '/';
if (gai != 0) {
rprintf(FLOG, "error matching address %s: %s\n",
tok, gai_strerror(gai));
freeaddrinfo(resa);
return 0;
}
if (rest->ai_family != resa->ai_family) {
ret = 0;
goto out;
}
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(FLOG, "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(FLOG, "malformed mask in %s\n", tok);
ret = 0;
goto out;
if (strchr(p+1,'.')) {
mask = inet_addr(p+1);
if (mask == INADDR_NONE) {
rprintf(FERROR,"malformed mask in %s\n", tok);
return 0;
}
#else
for (pp = (unsigned char *)p; *pp; pp++) {
if (!isascii(*pp) || !isdigit(*pp)) {
rprintf(FLOG, "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(FLOG, "malformed mask in %s\n", tok);
ret = 0;
goto out;
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));
}
} 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;
return ((a&mask) == (t&mask));
}
static int access_match(char *list, char *addr, char *host)
@@ -215,14 +85,12 @@ static int access_match(char *list, char *addr, char *host)
char *tok;
char *list2 = strdup(list);
if (!list2)
out_of_memory("access_match");
if (!list2) out_of_memory("access_match");
strlower(list2);
if (host)
strlower(host);
if (host) strlower(host);
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
for (tok=strtok(list2," ,\t"); tok; tok=strtok(NULL," ,\t")) {
if (match_hostname(host, tok) || match_address(addr, tok)) {
free(list2);
return 1;
@@ -235,25 +103,29 @@ static int access_match(char *list, char *addr, char *host)
int allow_access(char *addr, char *host, char *allow_list, char *deny_list)
{
if (allow_list && !*allow_list)
allow_list = NULL;
if (deny_list && !*deny_list)
deny_list = NULL;
/* if theres no deny list and no allow list then allow access */
if ((!deny_list || !*deny_list) && (!allow_list || !*allow_list))
return 1;
/* If we match an allow-list item, we always allow access. */
if (allow_list) {
if (access_match(allow_list, addr, host))
return 1;
/* For an allow-list w/o a deny-list, disallow non-matches. */
if (!deny_list)
return 0;
}
/* if there is an allow list but no deny list then allow only hosts
on the allow list */
if (!deny_list || !*deny_list)
return(access_match(allow_list, addr, host));
/* If we match a deny-list item (and got past any allow-list
* items), we always disallow access. */
if (deny_list && access_match(deny_list, addr, host))
/* if theres a deny list but no allow list then allow
all hosts not on the deny list */
if (!allow_list || !*allow_list)
return(!access_match(deny_list,addr,host));
/* if there are both type of list then allow all hosts on the
allow list */
if (access_match(allow_list,addr,host))
return 1;
/* if there are both type of list and it's not on the allow then
allow it if its not on the deny */
if (access_match(deny_list,addr,host))
return 0;
/* Allow all other access. */
return 1;
}

10
acconfig.h Normal file
View File

@@ -0,0 +1,10 @@
#undef ino_t
#undef HAVE_CONNECT
#undef HAVE_SHORT_INO_T
#undef HAVE_GETOPT_LONG
#undef REPLACE_INET_NTOA
#undef REPLACE_INET_ATON
#undef HAVE_GETTIMEOFDAY_TZ
#undef ENABLE_IPV6
#undef HAVE_SOCKADDR_LEN
#undef HAVE_SOCKETPAIR

23
aclocal.m4 vendored
View File

@@ -68,25 +68,4 @@ AC_DEFUN([TYPE_SOCKLEN_T],
#include <sys/socket.h>])
])
dnl AC_HAVE_TYPE(TYPE,INCLUDES)
AC_DEFUN([AC_HAVE_TYPE], [
AC_REQUIRE([AC_HEADER_STDC])
cv=`echo "$1" | sed 'y%./+- %__p__%'`
AC_MSG_CHECKING(for $1)
AC_CACHE_VAL([ac_cv_type_$cv],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
AC_INCLUDES_DEFAULT
$2]],
[[$1 foo;]])],
[eval "ac_cv_type_$cv=yes"],
[eval "ac_cv_type_$cv=no"]))dnl
ac_foo=`eval echo \\$ac_cv_type_$cv`
AC_MSG_RESULT($ac_foo)
if test "$ac_foo" = yes; then
ac_tr_hdr=HAVE_`echo $1 | sed 'y%abcdefghijklmnopqrstuvwxyz./- %ABCDEFGHIJKLMNOPQRSTUVWXYZ____%'`
if false; then
AC_CHECK_TYPES($1)
fi
AC_DEFINE_UNQUOTED($ac_tr_hdr, 1, [Define if you have type `$1'])
fi
])

1092
acls.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,39 +1,39 @@
/*
* Support rsync daemon authentication.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2002-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/* -*- c-file-style: "linux"; -*-
Copyright (C) 1998-2000 by Andrew Tridgell
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.
*/
/* support rsync authentication */
#include "rsync.h"
extern char *password_file;
/***************************************************************************
encode a buffer using base64 - simple and slow algorithm. null terminates
the result.
***************************************************************************/
void base64_encode(const char *buf, int len, char *out, int pad)
static void base64_encode(char *buf, int len, char *out)
{
char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int bit_offset, byte_offset, idx, i;
const uchar *d = (const uchar *)buf;
unsigned char *d = (unsigned char *)buf;
int bytes = (len*8 + 5)/6;
for (i = 0; i < bytes; i++) {
memset(out, 0, bytes+1);
for (i=0;i<bytes;i++) {
byte_offset = (i*6)/8;
bit_offset = (i*6)%8;
if (bit_offset < 3) {
@@ -46,270 +46,244 @@ void base64_encode(const char *buf, int len, char *out, int pad)
}
out[i] = b64[idx];
}
while (pad && (i % 4))
out[i++] = '=';
out[i] = '\0';
}
/* Generate a challenge buffer and return it base64-encoded. */
static void gen_challenge(const char *addr, char *challenge)
/* create a 16 byte challenge buffer */
static void gen_challenge(char *addr, char *challenge)
{
char input[32];
char digest[MAX_DIGEST_LEN];
struct timeval tv;
int len;
memset(input, 0, sizeof input);
memset(input, 0, sizeof(input));
strlcpy(input, addr, 17);
strlcpy((char *)input, addr, 17);
sys_gettimeofday(&tv);
SIVAL(input, 16, tv.tv_sec);
SIVAL(input, 20, tv.tv_usec);
SIVAL(input, 24, getpid());
sum_init(0);
sum_update(input, sizeof input);
len = sum_end(digest);
base64_encode(digest, len, challenge, 0);
sum_init();
sum_update(input, sizeof(input));
sum_end(challenge);
}
/* Return the secret for a user from the secret file, null terminated.
* Maximum length is len (not counting the null). */
static int get_secret(int module, const char *user, char *secret, int len)
/* return the secret for a user from the sercret file. maximum length
is len. null terminate it */
static int get_secret(int module, char *user, char *secret, int len)
{
const char *fname = lp_secrets_file(module);
char *fname = lp_secrets_file(module);
int fd, found=0;
char line[MAXPATHLEN];
char *p, *pass=NULL;
STRUCT_STAT st;
int fd, ok = 1;
const char *p;
char ch, *s;
int ok = 1;
extern int am_root;
if (!fname || !*fname)
return 0;
if (!fname || !*fname) return 0;
if ((fd = open(fname, O_RDONLY)) < 0)
return 0;
fd = open(fname,O_RDONLY);
if (fd == -1) return 0;
if (do_stat(fname, &st) == -1) {
rsyserr(FLOG, errno, "stat(%s)", fname);
rsyserr(FERROR, errno, "stat(%s)", fname);
ok = 0;
} else if (lp_strict_modes(module)) {
if ((st.st_mode & 06) != 0) {
rprintf(FLOG, "secrets file must not be other-accessible (see strict modes option)\n");
rprintf(FERROR,"secrets file must not be other-accessible (see strict modes option)\n");
ok = 0;
} else if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FLOG, "secrets file must be owned by root when running as root (see strict modes)\n");
} else if (am_root && (st.st_uid != 0)) {
rprintf(FERROR,"secrets file must be owned by root when running as root (see strict modes)\n");
ok = 0;
}
}
if (!ok) {
rprintf(FLOG, "continuing without secrets file\n");
rprintf(FERROR,"continuing without secrets file\n");
close(fd);
return 0;
}
if (*user == '#') {
/* Reject attempt to match a comment. */
close(fd);
return 0;
while (!found) {
int i = 0;
memset(line, 0, sizeof line);
while ((size_t) i < (sizeof(line)-1)) {
if (read(fd, &line[i], 1) != 1) {
memset(line, 0, sizeof(line));
close(fd);
return 0;
}
if (line[i] == '\r') continue;
if (line[i] == '\n') break;
i++;
}
line[i] = 0;
if (line[0] == '#') continue;
p = strchr(line,':');
if (!p) continue;
*p = 0;
if (strcmp(user, line)) continue;
pass = p+1;
found = 1;
}
/* Try to find a line that starts with the user name and a ':'. */
p = user;
while (1) {
if (read(fd, &ch, 1) != 1) {
close(fd);
return 0;
}
if (ch == '\n')
p = user;
else if (p) {
if (*p == ch)
p++;
else if (!*p && ch == ':')
break;
else
p = NULL;
}
}
/* Slurp the secret into the "secret" buffer. */
s = secret;
while (len > 0) {
if (read(fd, s, 1) != 1 || *s == '\n')
break;
if (*s == '\r')
continue;
s++;
len--;
}
*s = '\0';
close(fd);
if (!found) return 0;
strlcpy(secret, pass, len);
return 1;
}
static const char *getpassf(const char *filename)
static char *getpassf(char *filename)
{
char buffer[100];
int fd=0;
STRUCT_STAT st;
char buffer[512], *p;
int fd, n, ok = 1;
const char *envpw = getenv("RSYNC_PASSWORD");
int ok = 1;
extern int am_root;
char *envpw=getenv("RSYNC_PASSWORD");
if (!filename)
return NULL;
if (!filename) return NULL;
if ((fd = open(filename,O_RDONLY)) < 0) {
rsyserr(FWARNING, errno, "could not open password file \"%s\"",
filename);
if (envpw)
rprintf(FINFO, "falling back to RSYNC_PASSWORD environment variable.\n");
if ( (fd=open(filename,O_RDONLY)) == -1) {
rsyserr(FERROR, errno, "could not open password file \"%s\"",filename);
if (envpw) rprintf(FERROR,"falling back to RSYNC_PASSWORD environment variable.\n");
return NULL;
}
if (do_stat(filename, &st) == -1) {
rsyserr(FWARNING, errno, "stat(%s)", filename);
rsyserr(FERROR, errno, "stat(%s)", filename);
ok = 0;
} else if ((st.st_mode & 06) != 0) {
rprintf(FWARNING, "password file must not be other-accessible\n");
rprintf(FERROR,"password file must not be other-accessible\n");
ok = 0;
} else if (MY_UID() == 0 && st.st_uid != 0) {
rprintf(FWARNING, "password file must be owned by root when running as root\n");
} else if (am_root && (st.st_uid != 0)) {
rprintf(FERROR,"password file must be owned by root when running as root\n");
ok = 0;
}
if (!ok) {
rprintf(FERROR,"continuing without password file\n");
if (envpw) rprintf(FERROR,"using RSYNC_PASSWORD environment variable.\n");
close(fd);
rprintf(FWARNING, "continuing without password file\n");
if (envpw)
rprintf(FINFO, "falling back to RSYNC_PASSWORD environment variable.\n");
return NULL;
}
n = read(fd, buffer, sizeof buffer - 1);
close(fd);
if (n > 0) {
buffer[n] = '\0';
if ((p = strtok(buffer, "\n\r")) != NULL)
return strdup(p);
}
if (envpw) rprintf(FERROR,"RSYNC_PASSWORD environment variable ignored\n");
buffer[sizeof(buffer)-1]='\0';
if (read(fd,buffer,sizeof(buffer)-1) > 0)
{
char *p = strtok(buffer,"\n\r");
close(fd);
if (p) p = strdup(p);
return p;
}
return NULL;
}
/* Generate an MD4 hash created from the combination of the password
* and the challenge string and return it base64-encoded. */
static void generate_hash(const char *in, const char *challenge, char *out)
/* generate a 16 byte hash from a password and challenge */
static void generate_hash(char *in, char *challenge, char *out)
{
char buf[MAX_DIGEST_LEN];
int len;
char buf[16];
sum_init(0);
sum_init();
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
len = sum_end(buf);
sum_end(buf);
base64_encode(buf, len, out, 0);
base64_encode(buf, 16, out);
}
/* Possibly negotiate authentication with the client. Use "leader" to
* start off the auth if necessary.
*
* Return NULL if authentication failed. Return "" if anonymous access.
* Otherwise return username.
*/
char *auth_server(int f_in, int f_out, int module, const char *host,
const char *addr, const char *leader)
/* possible negotiate authentication with the client. Use "leader" to
start off the auth if necessary
return NULL if authentication failed
return "" if anonymous access
otherwise return username
*/
char *auth_server(int fd, int module, char *addr, char *leader)
{
char *users = lp_auth_users(module);
char challenge[MAX_DIGEST_LEN*2];
char line[BIGPATHBUFLEN];
char secret[512];
char pass2[MAX_DIGEST_LEN*2];
char *tok, *pass;
char challenge[16];
char b64_challenge[30];
char line[MAXPATHLEN];
static char user[100];
char secret[100];
char pass[30];
char pass2[30];
char *tok;
/* if no auth list then allow anyone in! */
if (!users || !*users)
return "";
if (!users || !*users) return "";
gen_challenge(addr, challenge);
base64_encode(challenge, 16, b64_challenge);
io_printf(f_out, "%s%s\n", leader, challenge);
io_printf(fd,"%s%s\n", leader, b64_challenge);
if (!read_line_old(f_in, line, sizeof line)
|| (pass = strchr(line, ' ')) == NULL) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"invalid challenge response\n",
lp_name(module), host, addr);
if (!read_line(fd, line, sizeof(line)-1)) {
return NULL;
}
*pass++ = '\0';
if (!(users = strdup(users)))
out_of_memory("auth_server");
memset(user, 0, sizeof(user));
memset(pass, 0, sizeof(pass));
for (tok = strtok(users, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
if (wildmatch(tok, line))
break;
if (sscanf(line,"%99s %29s", user, pass) != 2) {
return NULL;
}
users = strdup(users);
if (!users) return NULL;
for (tok=strtok(users," ,\t"); tok; tok = strtok(NULL," ,\t")) {
if (fnmatch(tok, user, 0) == 0) break;
}
free(users);
if (!tok) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"unauthorized user\n",
lp_name(module), host, addr);
return NULL;
}
memset(secret, 0, sizeof(secret));
if (!get_secret(module, user, secret, sizeof(secret)-1)) {
memset(secret, 0, sizeof(secret));
return NULL;
}
memset(secret, 0, sizeof secret);
if (!get_secret(module, line, secret, sizeof secret - 1)) {
memset(secret, 0, sizeof secret);
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"missing secret for user \"%s\"\n",
lp_name(module), host, addr, line);
return NULL;
}
generate_hash(secret, b64_challenge, pass2);
memset(secret, 0, sizeof(secret));
if (strcmp(pass, pass2) == 0)
return user;
generate_hash(secret, challenge, pass2);
memset(secret, 0, sizeof secret);
if (strcmp(pass, pass2) != 0) {
rprintf(FLOG, "auth failed on module %s from %s (%s): "
"password mismatch\n",
lp_name(module), host, addr);
return NULL;
}
return strdup(line);
return NULL;
}
void auth_client(int fd, const char *user, const char *challenge)
void auth_client(int fd, char *user, char *challenge)
{
const char *pass;
char pass2[MAX_DIGEST_LEN*2];
char *pass;
char pass2[30];
extern char *password_file;
if (!user || !*user)
user = "nobody";
if (!user || !*user) return;
if (!(pass = getpassf(password_file))
&& !(pass = getenv("RSYNC_PASSWORD"))) {
if (!(pass=getpassf(password_file)) && !(pass=getenv("RSYNC_PASSWORD"))) {
/* XXX: cyeoh says that getpass is deprecated, because
* it may return a truncated password on some systems,
* and it is not in the LSB.
*
* Andrew Klein says that getpassphrase() is present
* on Solaris and reads up to 256 characters.
*
* OpenBSD has a readpassphrase() that might be more suitable.
*/
it may return a truncated password on some systems,
and it is not in the LSB. */
pass = getpass("Password: ");
}
if (!pass)
if (!pass || !*pass) {
pass = "";
}
generate_hash(pass, challenge, pass2);
io_printf(fd, "%s %s\n", user, pass2);
}

509
backup.c
View File

@@ -1,328 +1,291 @@
/*
* Backup handling code.
*
* Copyright (C) 1999 Andrew Tridgell
* Copyright (C) 2003-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1999
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.
*/
/* backup handling code */
#include "rsync.h"
extern int verbose;
extern int am_root;
extern int preserve_acls;
extern int preserve_xattrs;
extern int preserve_devices;
extern int preserve_specials;
extern int preserve_links;
extern int safe_symlinks;
extern int backup_dir_len;
extern unsigned int backup_dir_remainder;
extern char backup_dir_buf[MAXPATHLEN];
extern char *backup_suffix;
extern char *backup_dir;
/* make a complete pathname for backup file */
char *get_backup_name(const char *fname)
{
if (backup_dir) {
if (stringjoin(backup_dir_buf + backup_dir_len, backup_dir_remainder,
fname, backup_suffix, NULL) < backup_dir_remainder)
return backup_dir_buf;
} else {
if (stringjoin(backup_dir_buf, MAXPATHLEN,
fname, backup_suffix, NULL) < MAXPATHLEN)
return backup_dir_buf;
}
rprintf(FERROR, "backup filename too long\n");
return NULL;
}
extern int am_root;
extern int preserve_devices;
extern int preserve_links;
extern int preserve_hard_links;
/* simple backup creates a backup with a suffix in the same directory */
static int make_simple_backup(const char *fname)
static int make_simple_backup(char *fname)
{
int rename_errno;
const char *fnamebak = get_backup_name(fname);
if (!fnamebak)
return 0;
while (1) {
if (do_rename(fname, fnamebak) == 0) {
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
fname, fnamebak);
}
break;
}
/* cygwin (at least version b19) reports EINVAL */
if (errno == ENOENT || errno == EINVAL)
break;
rename_errno = errno;
if (errno == EISDIR && do_rmdir(fnamebak) == 0)
continue;
if (errno == ENOTDIR && do_unlink(fnamebak) == 0)
continue;
rsyserr(FERROR, rename_errno, "rename %s to backup %s",
fname, fnamebak);
errno = rename_errno;
char fnamebak[MAXPATHLEN];
if (strlen(fname) + strlen(backup_suffix) > (MAXPATHLEN-1)) {
rprintf(FERROR,"backup filename too long\n");
return 0;
}
snprintf(fnamebak,sizeof(fnamebak),"%s%s",fname,backup_suffix);
if (do_rename(fname,fnamebak) != 0) {
/* cygwin (at least version b19) reports EINVAL */
if (errno != ENOENT && errno != EINVAL) {
rsyserr(FERROR, errno, "rename %s to backup %s", fname, fnamebak);
return 0;
}
} else if (verbose > 1) {
rprintf(FINFO,"backed up %s to %s\n",fname,fnamebak);
}
return 1;
}
/* recursively make a directory path */
static int make_dir(char *name, int mask)
{
char newdir [MAXPATHLEN];
char *p, *d;
/* copy pathname over, look for last '/' */
for (p = d = newdir; *name; *d++ = *name++)
if (*name == '/')
p = d;
if (p == newdir)
return 0;
*p = 0;
/* make the new directory, if that fails then make its parent */
while (do_mkdir (newdir, mask) != 0)
if ((errno != ENOENT) || !make_dir (newdir, mask))
return 0;
return 1;
} /* make_dir */
/****************************************************************************
Create a directory given an absolute path, perms based upon another directory
path
****************************************************************************/
int make_bak_dir(const char *fullpath)
static int make_bak_dir(char *fname,char *bak_path)
{
char fbuf[MAXPATHLEN], *rel, *end, *p;
struct file_struct *file;
int len = backup_dir_len;
stat_x sx;
STRUCT_STAT st;
STRUCT_STAT *st2;
char fullpath[MAXPATHLEN];
extern int orig_umask;
char *p;
char *q;
while (*fullpath == '.' && fullpath[1] == '/') {
fullpath += 2;
len -= 2;
}
while(strncmp(bak_path,"./",2)==0) bak_path += 2;
if (strlcpy(fbuf, fullpath, sizeof fbuf) >= sizeof fbuf)
return -1;
if(bak_path[strlen(bak_path)-1]!='/') {
snprintf(fullpath,sizeof(fullpath),"%s/",bak_path);
} else {
snprintf(fullpath,sizeof(fullpath),"%s",bak_path);
}
p=fullpath;
q=&fullpath[strlen(fullpath)]; /* End of bak_path string */
strcat(fullpath,fname);
rel = fbuf + len;
end = p = rel + strlen(rel);
/* Try to find an existing dir, starting from the deepest dir. */
while (1) {
if (--p == fbuf)
return -1;
if (*p == '/') {
*p = '\0';
if (mkdir_defmode(fbuf) == 0)
break;
if (errno != ENOENT) {
rsyserr(FERROR, errno,
"make_bak_dir mkdir %s failed",
full_fname(fbuf));
return -1;
}
}
}
/* Make all the dirs that we didn't find on the way here. */
while (1) {
if (p >= rel) {
/* Try to transfer the directory settings of the
* actual dir that the files are coming from. */
if (x_stat(rel, &sx.st, NULL) < 0) {
rsyserr(FERROR, errno,
"make_bak_dir stat %s failed",
full_fname(rel));
} else {
#ifdef SUPPORT_ACLS
sx.acc_acl = sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx.xattr = NULL;
#endif
if (!(file = make_file(rel, NULL, NULL, 0, NO_FILTERS)))
continue;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(rel, &sx);
cache_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(rel, &sx);
cache_xattr(file, &sx);
free_xattr(&sx);
}
#endif
set_file_attrs(fbuf, file, NULL, NULL, 0);
unmake_file(file);
}
}
*p = '/';
p += strlen(p);
if (p == end)
break;
if (mkdir_defmode(fbuf) < 0) {
rsyserr(FERROR, errno, "make_bak_dir mkdir %s failed",
full_fname(fbuf));
return -1;
}
}
return 0;
/* Make the directories */
while ((p=strchr(p,'/'))) {
*p = 0;
if(do_lstat(fullpath,&st)!=0) {
do_mkdir(fullpath,0777 & ~orig_umask);
if(p>q) {
if(do_lstat(q,&st)!=0) {
rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno));
} else {
st2=&st;
set_modtime(fullpath,st2->st_mtime);
if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) {
rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno));
};
if(do_chmod(fullpath,st2->st_mode)!=0) {
rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno));
};
};
}
};
*p = '/';
p++;
}
return 0;
}
/* robustly move a file, creating new directory structures if necessary */
static int robust_move(const char *src, char *dst)
static int robust_move(char *src, char *dst)
{
if (robust_rename(src, dst, NULL, 0755) < 0
&& (errno != ENOENT || make_bak_dir(dst) < 0
|| robust_rename(src, dst, NULL, 0755) < 0))
return -1;
return 0;
}
int keep_trying = 4;
int keep_path_extfs = 0;
int failed;
while (keep_trying) {
if (keep_path_extfs) {
failed = copy_file(src, dst, 0755);
if (!failed) {
do_unlink(src);
}
} else {
failed = robust_rename (src, dst);
}
if (failed) {
if (verbose > 2)
rprintf (FERROR, "robust_move failed: %s(%d)\n",
strerror (errno), errno);
switch (errno) {
/* external filesystem */
case EXDEV:
keep_path_extfs = 1;
keep_trying--;
break;
/* no directory to write to */
case ENOENT:
make_dir (dst, 0755);
keep_trying--;
break;
default:
keep_trying = 0;
} /* switch */
} else
keep_trying = 0;
} /* while */
return (!failed);
} /* robust_move */
/* If we have a --backup-dir, then we get here from make_backup().
* We will move the file to be deleted into a parallel directory tree. */
static int keep_backup(const char *fname)
/* if we have a backup_dir, then we get here from make_backup().
We will move the file to be deleted into a parallel directory tree */
static int keep_backup(char *fname)
{
stat_x sx;
static int initialised;
char keep_name [MAXPATHLEN];
STRUCT_STAT st;
struct file_struct *file;
char *buf;
int kept = 0;
int kept=0;
int ret_code;
if (!initialised) {
if (backup_dir[strlen(backup_dir) - 1] == '/')
backup_dir[strlen(backup_dir) - 1] = 0;
if (verbose > 0)
rprintf (FINFO, "backup_dir is %s\n", backup_dir);
initialised = 1;
}
/* return if no file to keep */
if (x_lstat(fname, &sx.st, NULL) < 0)
return 1;
#ifdef SUPPORT_ACLS
sx.acc_acl = sx.def_acl = NULL;
#endif
#ifdef SUPPORT_XATTRS
sx.xattr = NULL;
#if SUPPORT_LINKS
if (do_lstat (fname, &st)) return 1;
#else
if (do_stat (fname, &st)) return 1;
#endif
if (!(file = make_file(fname, NULL, NULL, 0, NO_FILTERS)))
return 1; /* the file could have disappeared */
file = make_file(-1, fname, NULL, 1);
if (!(buf = get_backup_name(fname))) {
unmake_file(file);
return 0;
}
/* the file could have disappeared */
if (!file) return 1;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
get_acl(fname, &sx);
cache_acl(file, &sx);
free_acl(&sx);
}
#endif
#ifdef SUPPORT_XATTRS
if (preserve_xattrs) {
get_xattr(fname, &sx);
cache_xattr(file, &sx);
free_xattr(&sx);
}
#endif
/* make a complete pathname for backup file */
if (strlen(backup_dir) + strlen(fname) > (MAXPATHLEN - 1)) {
rprintf (FERROR, "keep_backup filename too long\n");
return 0;
}
snprintf(keep_name, sizeof (keep_name), "%s/%s", backup_dir, fname);
#ifdef HAVE_MKNOD
/* Check to see if this is a device file, or link */
if ((am_root && preserve_devices && IS_DEVICE(file->mode))
|| (preserve_specials && IS_SPECIAL(file->mode))) {
uint32 *devp = F_RDEV_P(file);
dev_t rdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
do_unlink(buf);
if (do_mknod(buf, file->mode, rdev) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_mknod(buf, file->mode, rdev) < 0)) {
rsyserr(FERROR, errno, "mknod %s failed",
full_fname(buf));
} else if (verbose > 2) {
rprintf(FINFO, "make_backup: DEVICE %s successful.\n",
fname);
}
kept = 1;
do_unlink(fname);
}
if (!kept && S_ISDIR(file->mode)) {
/* make an empty directory */
if (do_mkdir(buf, file->mode) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_mkdir(buf, file->mode) < 0)) {
rsyserr(FINFO, errno, "mkdir %s failed",
full_fname(buf));
}
ret_code = do_rmdir(fname);
if (verbose > 2) {
rprintf(FINFO, "make_backup: RMDIR %s returns %i\n",
full_fname(fname), ret_code);
}
kept = 1;
}
#ifdef SUPPORT_LINKS
if (!kept && preserve_links && S_ISLNK(file->mode)) {
const char *sl = F_SYMLINK(file);
if (safe_symlinks && unsafe_symlink(sl, buf)) {
if (verbose) {
rprintf(FINFO, "ignoring unsafe symlink %s -> %s\n",
full_fname(buf), sl);
}
kept = 1;
} else {
do_unlink(buf);
if (do_symlink(sl, buf) < 0
&& (errno != ENOENT || make_bak_dir(buf) < 0
|| do_symlink(sl, buf) < 0)) {
rsyserr(FERROR, errno, "link %s -> \"%s\"",
full_fname(buf), sl);
}
do_unlink(fname);
kept = 1;
}
}
if(IS_DEVICE(file->mode)) {
if(am_root && preserve_devices) {
make_bak_dir(fname,backup_dir);
if(do_mknod(keep_name,file->mode,file->rdev)!=0) {
rprintf(FERROR,"mknod %s : %s\n",keep_name,strerror(errno));
} else {
if(verbose>2)
rprintf(FINFO,"make_backup : DEVICE %s successful.\n",fname);
};
};
kept=1;
do_unlink(fname);
};
#endif
if (!kept && !S_ISREG(file->mode)) {
rprintf(FINFO, "make_bak: skipping non-regular file %s\n",
fname);
unmake_file(file);
return 1;
}
if(!kept && S_ISDIR(file->mode)) {
/* make an empty directory */
make_bak_dir(fname,backup_dir);
do_mkdir(keep_name,file->mode);
ret_code=do_rmdir(fname);
if(verbose>2)
rprintf(FINFO,"make_backup : RMDIR %s returns %i\n",fname,ret_code);
kept=1;
};
#if SUPPORT_LINKS
if(!kept && preserve_links && S_ISLNK(file->mode)) {
extern int safe_symlinks;
if (safe_symlinks && unsafe_symlink(file->link, keep_name)) {
if (verbose) {
rprintf(FINFO,"ignoring unsafe symlink %s -> %s\n",
keep_name,file->link);
}
kept=1;
}
make_bak_dir(fname,backup_dir);
if(do_symlink(file->link,keep_name) != 0) {
rprintf(FERROR,"link %s -> %s : %s\n",keep_name,file->link,strerror(errno));
};
do_unlink(fname);
kept=1;
};
#endif
if(!kept && preserve_hard_links && check_hard_link(file)) {
if(verbose > 1) rprintf(FINFO,"%s is a hard link\n",f_name(file));
};
if(!kept && !S_ISREG(file->mode)) {
rprintf(FINFO,"make_bak: skipping non-regular file %s\n",fname);
}
/* move to keep tree if a file */
if (!kept) {
if (robust_move(fname, buf) != 0) {
rsyserr(FERROR, errno, "keep_backup failed: %s -> \"%s\"",
full_fname(fname), buf);
} else if (sx.st.st_nlink > 1) {
/* If someone has hard-linked the file into the backup
* dir, rename() might return success but do nothing! */
robust_unlink(fname); /* Just in case... */
}
}
set_file_attrs(buf, file, NULL, fname, 0);
unmake_file(file);
if(!kept) {
if (!robust_move (fname, keep_name))
rprintf(FERROR, "keep_backup failed %s -> %s : %s\n",
fname, keep_name, strerror(errno));
};
set_perms (keep_name, file, NULL, 0);
free_file (file);
free (file);
if (verbose > 1) {
rprintf(FINFO, "backed up %s to %s\n",
fname, buf);
}
if (verbose > 1)
rprintf (FINFO, "keep_backup %s -> %s\n", fname, keep_name);
return 1;
}
} /* keep_backup */
/* main backup switch routine */
int make_backup(const char *fname)
int make_backup(char *fname)
{
if (backup_dir)
return keep_backup(fname);
return make_simple_backup(fname);
return (keep_backup(fname));
else
return (make_simple_backup(fname));
}

783
batch.c
View File

@@ -1,266 +1,605 @@
/*
* Support for the batch-file options.
*
* Copyright (C) 1999 Weiss
* Copyright (C) 2004 Chris Shoemaker
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/* -*- c-file-style: "linux" -*-
Weiss 1/1999
Batch utilities for rsync.
*/
#include "rsync.h"
#include "zlib/zlib.h"
#include <time.h>
extern int eol_nulls;
extern int recurse;
extern int xfer_dirs;
extern int preserve_links;
extern int preserve_hard_links;
extern int preserve_devices;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_acls;
extern int preserve_xattrs;
extern int always_checksum;
extern int do_compression;
extern int inplace;
extern int append_mode;
extern int protocol_version;
extern char *batch_name;
#ifdef ICONV_OPTION
extern char *iconv_opt;
#endif
char rsync_flist_file[27] = "rsync_flist.";
char rsync_csums_file[27] = "rsync_csums.";
char rsync_delta_file[27] = "rsync_delta.";
char rsync_argvs_file[27] = "rsync_argvs.";
extern struct filter_list_struct filter_list;
char batch_file_ext[15];
int batch_stream_flags;
int fdb;
int fdb_delta;
int fdb_open;
int fdb_close;
static int tweaked_append;
static int tweaked_append_verify;
static int tweaked_iconv;
struct file_list *batch_flist;
static int *flag_ptr[] = {
&recurse, /* 0 */
&preserve_uid, /* 1 */
&preserve_gid, /* 2 */
&preserve_links, /* 3 */
&preserve_devices, /* 4 */
&preserve_hard_links, /* 5 */
&always_checksum, /* 6 */
&xfer_dirs, /* 7 (protocol 29) */
&do_compression, /* 8 (protocol 29) */
&tweaked_iconv, /* 9 (protocol 30) */
&preserve_acls, /* 10 (protocol 30) */
&preserve_xattrs, /* 11 (protocol 30) */
&inplace, /* 12 (protocol 30) */
&tweaked_append, /* 13 (protocol 30) */
&tweaked_append_verify, /* 14 (protocol 30) */
NULL
};
static char *flag_name[] = {
"--recurse (-r)",
"--owner (-o)",
"--group (-g)",
"--links (-l)",
"--devices (-D)",
"--hard-links (-H)",
"--checksum (-c)",
"--dirs (-d)",
"--compress (-z)",
"--iconv",
"--acls (-A)",
"--xattrs (-X)",
"--inplace",
"--append",
"--append-verify",
NULL
};
void write_stream_flags(int fd)
void create_batch_file_ext()
{
int i, flags;
struct tm *timeptr;
time_t elapsed_seconds;
tweaked_append = append_mode == 1;
tweaked_append_verify = append_mode == 2;
#ifdef ICONV_OPTION
tweaked_iconv = iconv_opt != NULL;
#endif
/* Save run date and time to use for batch file extensions */
time(&elapsed_seconds);
timeptr = localtime(&elapsed_seconds);
/* Start the batch file with a bitmap of data-stream-affecting
* flags. */
for (i = 0, flags = 0; flag_ptr[i]; i++) {
if (*flag_ptr[i])
flags |= 1 << i;
sprintf(batch_file_ext, "%4d%02d%02d%02d%02d%02d",
timeptr->tm_year + 1900, timeptr->tm_mon + 1,
timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min,
timeptr->tm_sec);
rprintf(FINFO,"batch file extension: %s\n", batch_file_ext);
}
void set_batch_file_ext(char *ext)
{
strcpy(batch_file_ext, ext);
}
void write_batch_flist_file(char *buff, int bytes_to_write)
{
if (fdb_open) {
/* Set up file extension */
strcat(rsync_flist_file, batch_file_ext);
/* Open batch flist file for writing; create it if it doesn't exist */
fdb =
do_open(rsync_flist_file, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_flist_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
fdb_open = 0;
}
/* Write buffer to batch flist file */
if (write(fdb, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_flist_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
if (fdb_close) {
close(fdb);
}
write_int(fd, flags);
}
void read_stream_flags(int fd)
{
batch_stream_flags = read_int(fd);
}
void check_batch_flags(void)
void write_batch_flist_info(int flist_count, struct file_struct **fptr)
{
int i;
int bytes_to_write;
if (protocol_version < 29)
flag_ptr[7] = NULL;
else if (protocol_version < 30)
flag_ptr[9] = NULL;
tweaked_append = append_mode == 1;
tweaked_append_verify = append_mode == 2;
#ifdef ICONV_OPTION
tweaked_iconv = iconv_opt != NULL;
#endif
for (i = 0; flag_ptr[i]; i++) {
int set = batch_stream_flags & (1 << i) ? 1 : 0;
if (*flag_ptr[i] != set) {
if (i == 9) {
rprintf(FERROR,
"%s specify the --iconv option to use this batch file.\n",
set ? "Please" : "Do not");
exit_cleanup(RERR_SYNTAX);
}
if (verbose) {
rprintf(FINFO,
"%sing the %s option to match the batchfile.\n",
set ? "Sett" : "Clear", flag_name[i]);
}
*flag_ptr[i] = set;
/* Write flist info to batch file */
bytes_to_write =
sizeof(unsigned) +
sizeof(time_t) +
sizeof(OFF_T) +
sizeof(mode_t) +
sizeof(INO64_T) +
sizeof(DEV64_T) +
sizeof(DEV64_T) +
sizeof(uid_t) +
sizeof(gid_t);
fdb_open = 1;
fdb_close = 0;
for (i = 0; i < flist_count; i++) {
write_batch_flist_file((char *) fptr[i], bytes_to_write);
write_char_bufs(fptr[i]->basename);
write_char_bufs(fptr[i]->dirname);
write_char_bufs(fptr[i]->basedir);
write_char_bufs(fptr[i]->link);
if (i == flist_count - 1) {
fdb_close = 1;
}
}
if (protocol_version < 29) {
if (recurse)
xfer_dirs |= 1;
else if (xfer_dirs < 2)
xfer_dirs = 0;
write_char_bufs(fptr[i]->sum);
}
if (tweaked_append)
append_mode = 1;
else if (tweaked_append_verify)
append_mode = 2;
}
static void write_arg(int fd, char *arg)
void write_char_bufs(char *buf)
{
char *x, *s;
/* Write the size of the string which will follow */
if (*arg == '-' && (x = strchr(arg, '=')) != NULL) {
write(fd, arg, x - arg + 1);
arg += x - arg + 1;
char b[4];
if (buf != NULL)
SIVAL(b, 0, strlen(buf));
else {
SIVAL(b, 0, 0);
}
if (strpbrk(arg, " \"'&;|[]()$#!*?^\\") != NULL) {
write(fd, "'", 1);
for (s = arg; (x = strchr(s, '\'')) != NULL; s = x + 1) {
write(fd, s, x - s + 1);
write(fd, "'", 1);
}
write(fd, s, strlen(s));
write(fd, "'", 1);
return;
}
write_batch_flist_file(b, sizeof(int));
write(fd, arg, strlen(arg));
/* Write the string if there is one */
if (buf != NULL) {
write_batch_flist_file(buf, strlen(buf));
}
}
static void write_filter_rules(int fd)
void write_batch_argvs_file(int argc, char *argv[])
{
struct filter_struct *ent;
int fdb;
int i;
char buff[256];
write_sbuf(fd, " <<'#E#'\n");
for (ent = filter_list.head; ent; ent = ent->next) {
unsigned int plen;
char *p = get_rule_prefix(ent->match_flags, "- ", 0, &plen);
write_buf(fd, p, plen);
write_sbuf(fd, ent->pattern);
if (ent->match_flags & MATCHFLG_DIRECTORY)
write_byte(fd, '/');
write_byte(fd, eol_nulls ? 0 : '\n');
strcat(rsync_argvs_file, batch_file_ext);
/* Open batch argvs file for writing; create it if it doesn't exist */
fdb = do_open(rsync_argvs_file, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE | S_IEXEC);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_argvs_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
if (eol_nulls)
write_sbuf(fd, ";\n");
write_sbuf(fd, "#E#");
buff[0] = '\0';
/* Write argvs info to batch file */
for (i = 0; i < argc; ++i) {
if (i == argc - 2)
continue;
/*
* FIXME:
* I think directly manipulating argv[] is probably bogus
*/
if (!strcmp(argv[i], "--write-batch")) {
/* Safer to change it here than script */
/* Change to --read-batch + ext * to get ready for remote */
strlcat(buff, "--read-batch ", sizeof(buff));
strlcat(buff, batch_file_ext, sizeof(buff));
} else {
strlcat(buff, argv[i], sizeof(buff));
}
if (i < (argc - 1)) {
strlcat(buff, " ", sizeof(buff));
}
}
strlcat(buff, "\n", sizeof(buff));
if (!write(fdb, buff, strlen(buff))) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_argvs_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
close(fdb);
}
/* This routine tries to write out an equivalent --read-batch command
* given the user's --write-batch args. However, it doesn't really
* understand most of the options, so it uses some overly simple
* heuristics to munge the command line into something that will
* (hopefully) work. */
void write_batch_shell_file(int argc, char *argv[], int file_arg_cnt)
struct file_list *create_flist_from_batch()
{
int fd, i, len;
char *p, filename[MAXPATHLEN];
unsigned char flags;
stringjoin(filename, sizeof filename,
batch_name, ".sh", NULL);
fd = do_open(filename, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IEXEC);
if (fd < 0) {
rsyserr(FERROR, errno, "Batch file %s open error",
filename);
exit_cleanup(RERR_FILESELECT);
fdb_open = 1;
fdb_close = 0;
batch_flist = (struct file_list *) malloc(sizeof(batch_flist[0]));
if (!batch_flist) {
out_of_memory("create_flist_from_batch");
}
batch_flist->count = 0;
batch_flist->malloced = 1000;
batch_flist->files =
(struct file_struct **) malloc(sizeof(batch_flist->files[0]) *
batch_flist->malloced);
if (!batch_flist->files) {
out_of_memory("create_flist_from_batch"); /* dw -- will exit */
}
/* Write argvs info to BATCH.sh file */
write_arg(fd, argv[0]);
if (filter_list.head) {
if (protocol_version >= 29)
write_sbuf(fd, " --filter=._-");
else
write_sbuf(fd, " --exclude-from=-");
for (flags = read_batch_flags(); flags; flags = read_batch_flags()) {
int i = batch_flist->count;
if (i >= batch_flist->malloced) {
if (batch_flist->malloced < 1000)
batch_flist->malloced += 1000;
else
batch_flist->malloced *= 2;
batch_flist->files =
(struct file_struct **) realloc(batch_flist->
files,
sizeof
(batch_flist->
files[0]) *
batch_flist->
malloced);
if (!batch_flist->files)
out_of_memory("create_flist_from_batch");
}
read_batch_flist_info(&batch_flist->files[i]);
batch_flist->files[i]->flags = flags;
batch_flist->count++;
}
for (i = 1; i < argc - file_arg_cnt; i++) {
p = argv[i];
if (strncmp(p, "--files-from", 12) == 0
|| strncmp(p, "--filter", 8) == 0
|| strncmp(p, "--include", 9) == 0
|| strncmp(p, "--exclude", 9) == 0) {
if (strchr(p, '=') == NULL)
i++;
continue;
return batch_flist;
}
int read_batch_flist_file(char *buff, int len)
{
int bytes_read;
if (fdb_open) {
/* Set up file extension */
strcat(rsync_flist_file, batch_file_ext);
/* Open batch flist file for reading */
fdb = do_open(rsync_flist_file, O_RDONLY, 0);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_flist_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
if (strcmp(p, "-f") == 0) {
i++;
continue;
fdb_open = 0;
}
/* Read flist batch file */
bytes_read = read(fdb, buff, len);
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
rsync_flist_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
if (bytes_read == 0) { /* EOF */
close(fdb);
}
return bytes_read;
}
unsigned char read_batch_flags()
{
int flags;
if (read_batch_flist_file((char *) &flags, 4)) {
return 1;
} else {
return 0;
}
}
void read_batch_flist_info(struct file_struct **fptr)
{
int int_str_len;
char char_str_len[4];
char buff[256];
struct file_struct *file;
file = (struct file_struct *) malloc(sizeof(*file));
if (!file)
out_of_memory("read_batch_flist_info");
memset((char *) file, 0, sizeof(*file));
(*fptr) = file;
read_batch_flist_file((char *) &file->modtime, sizeof(time_t));
read_batch_flist_file((char *) &file->length, sizeof(OFF_T));
read_batch_flist_file((char *) &file->mode, sizeof(mode_t));
read_batch_flist_file((char *) &file->inode, sizeof(INO64_T));
read_batch_flist_file((char *) &file->dev, sizeof(DEV64_T));
read_batch_flist_file((char *) &file->rdev, sizeof(DEV64_T));
read_batch_flist_file((char *) &file->uid, sizeof(uid_t));
read_batch_flist_file((char *) &file->gid, sizeof(gid_t));
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file->basename = strdup(buff);
} else {
file->basename = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].dirname = strdup(buff);
} else {
file[0].dirname = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].basedir = strdup(buff);
} else {
file[0].basedir = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].link = strdup(buff);
} else {
file[0].link = NULL;
}
read_batch_flist_file(char_str_len, sizeof(char_str_len));
int_str_len = IVAL(char_str_len, 0);
if (int_str_len > 0) {
read_batch_flist_file(buff, int_str_len);
buff[int_str_len] = '\0';
file[0].sum = strdup(buff);
} else {
file[0].sum = NULL;
}
}
void write_batch_csums_file(void *buff, int bytes_to_write)
{
static int fdb_open = 1;
if (fdb_open) {
/* Set up file extension */
strcat(rsync_csums_file, batch_file_ext);
/* Open batch csums file for writing; create it if it doesn't exist */
fdb =
do_open(rsync_csums_file, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_csums_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
write(fd, " ", 1);
if (strncmp(p, "--write-batch", len = 13) == 0
|| strncmp(p, "--only-write-batch", len = 18) == 0) {
write(fd, "--read-batch", 12);
if (p[len] == '=') {
write(fd, "=", 1);
write_arg(fd, p + len + 1);
fdb_open = 0;
}
/* Write buffer to batch csums file */
if (write(fdb, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_csums_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
}
void close_batch_csums_file()
{
close(fdb);
}
void write_batch_csum_info(int *flist_entry, int flist_count,
struct sum_struct *s)
{
size_t i;
unsigned int int_zero = 0;
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));
if (s)
write_batch_csums_file(&s->count, sizeof(int));
else
write_batch_csums_file(&int_zero, sizeof (int));
if (s) {
for (i = 0; i < s->count; i++) {
write_batch_csums_file(&s->sums[i].sum1, sizeof(uint32));
if ((*flist_entry == flist_count - 1)
&& (i == s->count - 1)) {
fdb_close = 1;
}
} else
write_arg(fd, p);
}
if (!(p = check_for_hostspec(argv[argc - 1], &p, &i)))
p = argv[argc - 1];
write(fd, " ${1:-", 6);
write_arg(fd, p);
write_byte(fd, '}');
if (filter_list.head)
write_filter_rules(fd);
if (write(fd, "\n", 1) != 1 || close(fd) < 0) {
rsyserr(FERROR, errno, "Batch file %s write error",
filename);
exit_cleanup(RERR_FILEIO);
write_batch_csums_file(s->sums[i].sum2,
csum_length);
}
}
}
int read_batch_csums_file(char *buff, int len)
{
static int fdb_open = 1;
int bytes_read;
if (fdb_open) {
/* Set up file extension */
strcat(rsync_csums_file, batch_file_ext);
/* Open batch flist file for reading */
fdb = do_open(rsync_csums_file, O_RDONLY, 0);
if (fdb == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_csums_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
fdb_open = 0;
}
/* Read csums batch file */
bytes_read = read(fdb, buff, len);
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
rsync_csums_file, strerror(errno));
close(fdb);
exit_cleanup(1);
}
return bytes_read;
}
void read_batch_csum_info(int flist_entry, struct sum_struct *s,
int *checksums_match)
{
int i;
int file_flist_entry;
int file_chunk_ct;
uint32 file_sum1;
char file_sum2[SUM_LENGTH];
extern int csum_length;
read_batch_csums_file((char *) &file_flist_entry, sizeof(int));
if (file_flist_entry != flist_entry) {
rprintf(FINFO, "file_list_entry NE flist_entry\n");
rprintf(FINFO, "file_flist_entry = %d flist_entry = %d\n",
file_flist_entry, flist_entry);
close(fdb);
exit_cleanup(1);
} else {
read_batch_csums_file((char *) &file_chunk_ct,
sizeof(int));
*checksums_match = 1;
for (i = 0; i < file_chunk_ct; i++) {
read_batch_csums_file((char *) &file_sum1,
sizeof(uint32));
read_batch_csums_file(file_sum2, csum_length);
if ((s->sums[i].sum1 != file_sum1) ||
(memcmp
(s->sums[i].sum2, file_sum2,
csum_length) != 0)) {
*checksums_match = 0;
}
} /* end for */
}
}
void write_batch_delta_file(char *buff, int bytes_to_write)
{
static int fdb_delta_open = 1;
if (fdb_delta_open) {
/* Set up file extension */
strcat(rsync_delta_file, batch_file_ext);
/* Open batch delta file for writing; create it if it doesn't exist */
fdb_delta =
do_open(rsync_delta_file, O_WRONLY | O_CREAT | O_TRUNC,
S_IREAD | S_IWRITE);
if (fdb_delta == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_delta_file, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
fdb_delta_open = 0;
}
/* Write buffer to batch delta file */
if (write(fdb_delta, buff, bytes_to_write) == -1) {
rprintf(FERROR, "Batch file %s write error: %s\n",
rsync_delta_file, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
}
void close_batch_delta_file()
{
close(fdb_delta);
}
int read_batch_delta_file(char *buff, int len)
{
static int fdb_delta_open = 1;
int bytes_read;
if (fdb_delta_open) {
/* Set up file extension */
strcat(rsync_delta_file, batch_file_ext);
/* Open batch flist file for reading */
fdb_delta = do_open(rsync_delta_file, O_RDONLY, 0);
if (fdb_delta == -1) {
rprintf(FERROR, "Batch file %s open error: %s\n",
rsync_delta_file, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
fdb_delta_open = 0;
}
/* Read delta batch file */
bytes_read = read(fdb_delta, buff, len);
if (bytes_read == -1) {
rprintf(FERROR, "Batch file %s read error: %s\n",
rsync_delta_file, strerror(errno));
close(fdb_delta);
exit_cleanup(1);
}
return bytes_read;
}
void show_flist(int index, struct file_struct **fptr)
{
/* for debugging show_flist(flist->count, flist->files * */
int i;
for (i = 0; i < index; i++) {
rprintf(FINFO, "flist->flags=%#x\n", fptr[i]->flags);
rprintf(FINFO, "flist->modtime=%#lx\n",
(long unsigned) fptr[i]->modtime);
rprintf(FINFO, "flist->length=%.0f\n",
(double) fptr[i]->length);
rprintf(FINFO, "flist->mode=%#o\n", (int) fptr[i]->mode);
rprintf(FINFO, "flist->basename=%s\n", fptr[i]->basename);
if (fptr[i]->dirname)
rprintf(FINFO, "flist->dirname=%s\n",
fptr[i]->dirname);
if (fptr[i]->basedir)
rprintf(FINFO, "flist->basedir=%s\n",
fptr[i]->basedir);
}
}
void show_argvs(int argc, char *argv[])
{
/* for debugging * */
int i;
rprintf(FINFO, "BATCH.C:show_argvs,argc=%d\n", argc);
for (i = 0; i < argc; i++) {
/* if (argv[i]) */
rprintf(FINFO, "i=%d,argv[i]=%s\n", i, argv[i]);
}
}

View File

@@ -1,27 +1,26 @@
/*
* Simple byteorder handling.
*
* Copyright (C) 1992-1995 Andrew Tridgell
* Copyright (C) 2007-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
simple byteorder handling
Copyright (C) Andrew Tridgell 1992-1995
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.
*/
#undef CAREFUL_ALIGNMENT
/* We know that the x86 can handle misalignment and has the same
* byte order (LSB-first) as the 32-bit numbers we transmit. */
/* we know that the x86 can handle misalignment and has the "right"
byteorder */
#ifdef __i386__
#define CAREFUL_ALIGNMENT 0
#endif
@@ -31,12 +30,13 @@
#endif
#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
#define UVAL(buf,pos) ((uint32)CVAL(buf,pos))
#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
#if CAREFUL_ALIGNMENT
#define PVAL(buf,pos) (UVAL(buf,pos)|UVAL(buf,(pos)+1)<<8)
#define IVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+2)<<16)
#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
@@ -50,3 +50,5 @@
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
#endif

View File

@@ -1,79 +0,0 @@
/*
* End-of-run cleanup helper code used by cleanup.c.
*
* Copyright (C) 2006-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/* This is included by cleanup.c multiple times, once for every segement in
* the _exit_cleanup() code. This produces the next "case N:" statement in
* sequence and increments the cleanup_step variable by 1. This ensures that
* our case statements never get out of whack due to added/removed steps. */
#if !defined EXIT_CLEANUP_CASE_0
#define EXIT_CLEANUP_CASE_0
case 0:
#elif !defined EXIT_CLEANUP_CASE_1
#define EXIT_CLEANUP_CASE_1
case 1:
#elif !defined EXIT_CLEANUP_CASE_2
#define EXIT_CLEANUP_CASE_2
case 2:
#elif !defined EXIT_CLEANUP_CASE_3
#define EXIT_CLEANUP_CASE_3
case 3:
#elif !defined EXIT_CLEANUP_CASE_4
#define EXIT_CLEANUP_CASE_4
case 4:
#elif !defined EXIT_CLEANUP_CASE_5
#define EXIT_CLEANUP_CASE_5
case 5:
#elif !defined EXIT_CLEANUP_CASE_6
#define EXIT_CLEANUP_CASE_6
case 6:
#elif !defined EXIT_CLEANUP_CASE_7
#define EXIT_CLEANUP_CASE_7
case 7:
#elif !defined EXIT_CLEANUP_CASE_8
#define EXIT_CLEANUP_CASE_8
case 8:
#elif !defined EXIT_CLEANUP_CASE_9
#define EXIT_CLEANUP_CASE_9
case 9:
#elif !defined EXIT_CLEANUP_CASE_10
#define EXIT_CLEANUP_CASE_10
case 10:
#elif !defined EXIT_CLEANUP_CASE_11
#define EXIT_CLEANUP_CASE_11
case 11:
#elif !defined EXIT_CLEANUP_CASE_12
#define EXIT_CLEANUP_CASE_12
case 12:
#elif !defined EXIT_CLEANUP_CASE_13
#define EXIT_CLEANUP_CASE_13
case 13:
#elif !defined EXIT_CLEANUP_CASE_14
#define EXIT_CLEANUP_CASE_14
case 14:
#elif !defined EXIT_CLEANUP_CASE_15
#define EXIT_CLEANUP_CASE_15
case 15:
#elif !defined EXIT_CLEANUP_CASE_16
#define EXIT_CLEANUP_CASE_16
case 16:
#else
#error Need to add more case statements!
#endif
cleanup_step++;

View File

@@ -1,46 +1,46 @@
/*
* Routines to support checksumming of bytes.
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
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"
extern int checksum_seed;
extern int protocol_version;
int csum_length=2; /* initial value */
int csum_length = SHORT_SUM_LENGTH; /* initial value */
#define CSUM_CHUNK 64
int checksum_seed = 0;
extern int remote_version;
/*
a simple 32 bit checksum that can be upadted from either end
(inspired by Mark Adler's Adler-32 checksum)
*/
uint32 get_checksum1(char *buf1, int32 len)
uint32 get_checksum1(char *buf1,int len)
{
int32 i;
int i;
uint32 s1, s2;
schar *buf = (schar *)buf1;
s1 = s2 = 0;
for (i = 0; i < (len-4); i+=4) {
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +
10*CHAR_OFFSET;
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);
}
for (; i < len; i++) {
s1 += (buf[i]+CHAR_OFFSET); s2 += s1;
@@ -49,177 +49,132 @@ uint32 get_checksum1(char *buf1, int32 len)
}
void get_checksum2(char *buf, int32 len, char *sum)
void get_checksum2(char *buf,int len,char *sum)
{
md_context m;
int i;
static char *buf1;
static int len1;
struct mdfour m;
if (protocol_version >= 30) {
uchar seedbuf[4];
md5_begin(&m);
md5_update(&m, (uchar *)buf, len);
if (checksum_seed) {
SIVAL(seedbuf, 0, checksum_seed);
md5_update(&m, seedbuf, 4);
}
md5_result(&m, (uchar *)sum);
} else {
int32 i;
static char *buf1;
static int32 len1;
mdfour_begin(&m);
if (len > len1) {
if (buf1)
free(buf1);
buf1 = new_array(char, len+4);
len1 = len;
if (!buf1)
out_of_memory("get_checksum2");
}
memcpy(buf1, buf, len);
if (checksum_seed) {
SIVAL(buf1,len,checksum_seed);
len += 4;
}
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK)
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
/*
* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes.
*/
if (len - i > 0 || protocol_version >= 27)
mdfour_update(&m, (uchar *)(buf1+i), len-i);
mdfour_result(&m, (uchar *)sum);
if (len > len1) {
if (buf1) free(buf1);
buf1 = (char *)malloc(len+4);
len1 = len;
if (!buf1) out_of_memory("get_checksum2");
}
mdfour_begin(&m);
memcpy(buf1,buf,len);
if (checksum_seed) {
SIVAL(buf1,len,checksum_seed);
len += 4;
}
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)(buf1+i), CSUM_CHUNK);
}
if (len - i > 0) {
mdfour_update(&m, (uchar *)(buf1+i), (len-i));
}
mdfour_result(&m, (uchar *)sum);
}
void file_checksum(char *fname, char *sum, OFF_T size)
void file_checksum(char *fname,char *sum,OFF_T size)
{
OFF_T i;
struct map_struct *buf;
OFF_T i, len = size;
md_context m;
int32 remainder;
int fd;
memset(sum, 0, MAX_DIGEST_LEN);
OFF_T len = size;
char tmpchunk[CSUM_CHUNK];
struct mdfour m;
memset(sum,0,MD4_SUM_LENGTH);
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1)
return;
if (fd == -1) return;
buf = map_file(fd,size);
mdfour_begin(&m);
buf = map_file(fd, size, MAX_MAP_SIZE, CSUM_CHUNK);
if (protocol_version >= 30) {
md5_begin(&m);
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
md5_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
remainder = (int32)(len - i);
if (remainder > 0)
md5_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
md5_result(&m, (uchar *)sum);
} else {
mdfour_begin(&m);
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
mdfour_update(&m, (uchar *)map_ptr(buf, i, CSUM_CHUNK),
CSUM_CHUNK);
}
/* Prior to version 27 an incorrect MD4 checksum was computed
* by failing to call mdfour_tail() for block sizes that
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
remainder = (int32)(len - i);
if (remainder > 0 || protocol_version >= 27)
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
mdfour_result(&m, (uchar *)sum);
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
memcpy(tmpchunk, map_ptr(buf,i,CSUM_CHUNK), CSUM_CHUNK);
mdfour_update(&m, (uchar *)tmpchunk, CSUM_CHUNK);
}
if (len - i > 0) {
memcpy(tmpchunk, map_ptr(buf,i,len-i), len-i);
mdfour_update(&m, (uchar *)tmpchunk, (len-i));
}
mdfour_result(&m, (uchar *)sum);
close(fd);
unmap_file(buf);
}
static int32 sumresidue;
static md_context md;
void sum_init(int seed)
void checksum_init(void)
{
char s[4];
if (protocol_version >= 30)
md5_begin(&md);
else {
mdfour_begin(&md);
sumresidue = 0;
SIVAL(s, 0, seed);
sum_update(s, 4);
}
if (remote_version >= 14)
csum_length = 2; /* adaptive */
else
csum_length = SUM_LENGTH;
}
/**
* 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(const char *p, int32 len)
{
if (protocol_version >= 30) {
md5_update(&md, (uchar *)p, len);
return;
}
static int sumresidue;
static char sumrbuf[CSUM_CHUNK];
static struct mdfour md;
void sum_init(void)
{
char s[4];
mdfour_begin(&md);
sumresidue=0;
SIVAL(s,0,checksum_seed);
sum_update(s,4);
}
void sum_update(char *p,int len)
{
int i;
if (len + sumresidue < CSUM_CHUNK) {
memcpy(md.buffer + sumresidue, p, len);
memcpy(sumrbuf+sumresidue, p, len);
sumresidue += len;
return;
}
if (sumresidue) {
int32 i = CSUM_CHUNK - sumresidue;
memcpy(md.buffer + sumresidue, p, i);
mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
i = MIN(CSUM_CHUNK-sumresidue,len);
memcpy(sumrbuf+sumresidue,p,i);
mdfour_update(&md, (uchar *)sumrbuf, (i+sumresidue));
len -= i;
p += i;
}
while (len >= CSUM_CHUNK) {
mdfour_update(&md, (uchar *)p, CSUM_CHUNK);
len -= CSUM_CHUNK;
p += CSUM_CHUNK;
for(i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
memcpy(sumrbuf,p+i,CSUM_CHUNK);
mdfour_update(&md, (uchar *)sumrbuf, CSUM_CHUNK);
}
sumresidue = len;
if (sumresidue)
memcpy(md.buffer, p, sumresidue);
if (len - i > 0) {
sumresidue = len-i;
memcpy(sumrbuf,p+i,sumresidue);
} else {
sumresidue = 0;
}
}
int sum_end(char *sum)
void sum_end(char *sum)
{
if (protocol_version >= 30) {
md5_result(&md, (uchar *)sum);
return MD5_DIGEST_LEN;
if (sumresidue) {
mdfour_update(&md, (uchar *)sumrbuf, sumresidue);
}
if (sumresidue || protocol_version >= 27)
mdfour_update(&md, (uchar *)md.buffer, sumresidue);
mdfour_result(&md, (uchar *)sum);
return MD4_DIGEST_LEN;
}

225
chmod.c
View File

@@ -1,225 +0,0 @@
/*
* Implement the core of the --chmod option.
*
* Copyright (C) 2002 Scott Howard
* Copyright (C) 2005-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
#include "rsync.h"
extern mode_t orig_umask;
#define FLAG_X_KEEP (1<<0)
#define FLAG_DIRS_ONLY (1<<1)
#define FLAG_FILES_ONLY (1<<2)
struct chmod_mode_struct {
struct chmod_mode_struct *next;
int ModeAND, ModeOR;
char flags;
};
#define CHMOD_ADD 1
#define CHMOD_SUB 2
#define CHMOD_EQ 3
#define STATE_ERROR 0
#define STATE_1ST_HALF 1
#define STATE_2ND_HALF 2
/* Parse a chmod-style argument, and break it down into one or more AND/OR
* pairs in a linked list. We return a pointer to new items on succcess
* (appending the items to the specified list), or NULL on error. */
struct chmod_mode_struct *parse_chmod(const char *modestr,
struct chmod_mode_struct **root_mode_ptr)
{
int state = STATE_1ST_HALF;
int where = 0, what = 0, op = 0, topbits = 0, topoct = 0, flags = 0;
struct chmod_mode_struct *first_mode = NULL, *curr_mode = NULL,
*prev_mode = NULL;
while (state != STATE_ERROR) {
if (!*modestr || *modestr == ',') {
int bits;
if (!op) {
state = STATE_ERROR;
break;
}
prev_mode = curr_mode;
curr_mode = new_array(struct chmod_mode_struct, 1);
if (prev_mode)
prev_mode->next = curr_mode;
else
first_mode = curr_mode;
curr_mode->next = NULL;
if (where)
bits = where * what;
else {
where = 0111;
bits = (where * what) & ~orig_umask;
}
switch (op) {
case CHMOD_ADD:
curr_mode->ModeAND = CHMOD_BITS;
curr_mode->ModeOR = bits + topoct;
break;
case CHMOD_SUB:
curr_mode->ModeAND = CHMOD_BITS - bits - topoct;
curr_mode->ModeOR = 0;
break;
case CHMOD_EQ:
curr_mode->ModeAND = CHMOD_BITS - (where * 7) - (topoct ? topbits : 0);
curr_mode->ModeOR = bits + topoct;
break;
}
curr_mode->flags = flags;
if (!*modestr)
break;
modestr++;
state = STATE_1ST_HALF;
where = what = op = topoct = topbits = flags = 0;
}
if (state != STATE_2ND_HALF) {
switch (*modestr) {
case 'D':
if (flags & FLAG_FILES_ONLY)
state = STATE_ERROR;
flags |= FLAG_DIRS_ONLY;
break;
case 'F':
if (flags & FLAG_DIRS_ONLY)
state = STATE_ERROR;
flags |= FLAG_FILES_ONLY;
break;
case 'u':
where |= 0100;
topbits |= 04000;
break;
case 'g':
where |= 0010;
topbits |= 02000;
break;
case 'o':
where |= 0001;
break;
case 'a':
where |= 0111;
break;
case '+':
op = CHMOD_ADD;
state = STATE_2ND_HALF;
break;
case '-':
op = CHMOD_SUB;
state = STATE_2ND_HALF;
break;
case '=':
op = CHMOD_EQ;
state = STATE_2ND_HALF;
break;
default:
state = STATE_ERROR;
break;
}
} else {
switch (*modestr) {
case 'r':
what |= 4;
break;
case 'w':
what |= 2;
break;
case 'X':
flags |= FLAG_X_KEEP;
/* FALL THROUGH */
case 'x':
what |= 1;
break;
case 's':
if (topbits)
topoct |= topbits;
else
topoct = 04000;
break;
case 't':
topoct |= 01000;
break;
default:
state = STATE_ERROR;
break;
}
}
modestr++;
}
if (state == STATE_ERROR) {
free_chmod_mode(first_mode);
return NULL;
}
if (!(curr_mode = *root_mode_ptr))
*root_mode_ptr = first_mode;
else {
while (curr_mode->next)
curr_mode = curr_mode->next;
curr_mode->next = first_mode;
}
return first_mode;
}
/* Takes an existing file permission and a list of AND/OR changes, and
* create a new permissions. */
int tweak_mode(int mode, struct chmod_mode_struct *chmod_modes)
{
int IsX = mode & 0111;
int NonPerm = mode & ~CHMOD_BITS;
for ( ; chmod_modes; chmod_modes = chmod_modes->next) {
if ((chmod_modes->flags & FLAG_DIRS_ONLY) && !S_ISDIR(NonPerm))
continue;
if ((chmod_modes->flags & FLAG_FILES_ONLY) && S_ISDIR(NonPerm))
continue;
mode &= chmod_modes->ModeAND;
if ((chmod_modes->flags & FLAG_X_KEEP) && !IsX && !S_ISDIR(NonPerm))
mode |= chmod_modes->ModeOR & ~0111;
else
mode |= chmod_modes->ModeOR;
}
return mode | NonPerm;
}
/* Free the linked list created by parse_chmod. */
int free_chmod_mode(struct chmod_mode_struct *chmod_modes)
{
struct chmod_mode_struct *next;
while (chmod_modes) {
next = chmod_modes->next;
free(chmod_modes);
chmod_modes = next;
}
return 0;
}

275
cleanup.c
View File

@@ -1,229 +1,108 @@
/*
* End-of-run cleanup routines.
*
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/* -*- c-file-style: "linux" -*-
Copyright (C) 1996-2000 by Andrew Tridgell
Copyright (C) Paul Mackerras 1996
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"
extern int am_server;
extern int am_daemon;
extern int io_error;
extern int keep_partial;
extern int got_xfer_error;
extern char *partial_dir;
extern char *logfile_name;
/* 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;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#endif
/**
* 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(void)
{
#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--) {
if ((ret = do_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 const char *cleanup_fname;
static const char *cleanup_new_fname;
static char *cleanup_fname;
static char *cleanup_new_fname;
static struct file_struct *cleanup_file;
static int cleanup_fd_r, cleanup_fd_w;
static pid_t cleanup_pid = 0;
static int cleanup_fd1, cleanup_fd2;
static struct map_struct *cleanup_buf;
static int cleanup_pid = 0;
extern int io_error;
pid_t cleanup_child_pid = -1;
/**
* Eventually calls exit(), passing @p code, therefore does not return.
*
* @param code one of the RERR_* codes from errcode.h.
**/
NORETURN void _exit_cleanup(int code, const char *file, int line)
/*
* Code is one of the RERR_* codes from errcode.h.
*/
void _exit_cleanup(int code, const char *file, int line)
{
static int cleanup_step = 0;
static int exit_code = 0;
static int unmodified_code = 0;
extern int keep_partial;
extern int log_got_error;
SIGACTION(SIGUSR1, SIG_IGN);
SIGACTION(SIGUSR2, SIG_IGN);
signal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN);
if (exit_code) /* Preserve first error code when recursing. */
code = exit_code;
/* If this is the exit at the end of the run, the server side
* should not attempt to output a message (see log.c). */
if (am_server && code == 0)
am_server = 2;
/* Some of our actions might cause a recursive call back here, so we
* keep track of where we are in the cleanup and never repeat a step. */
switch (cleanup_step) {
#include "case_N.h" /* case 0: cleanup_step++; */
exit_code = unmodified_code = code;
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) {
status = WEXITSTATUS(status);
if (status > code) code = status;
}
/* FALLTHROUGH */
#include "case_N.h"
if (cleanup_child_pid != -1) {
int status;
int pid = wait_process(cleanup_child_pid, &status, WNOHANG);
if (pid == cleanup_child_pid) {
status = WEXITSTATUS(status);
if (status > code)
code = exit_code = status;
}
}
/* FALLTHROUGH */
#include "case_N.h"
if (cleanup_got_literal && cleanup_fname && cleanup_new_fname
&& keep_partial && handle_partial_dir(cleanup_new_fname, PDIR_CREATE)) {
const char *fname = cleanup_fname;
cleanup_fname = NULL;
if (cleanup_fd_r != -1)
close(cleanup_fd_r);
if (cleanup_fd_w != -1) {
flush_write_file(cleanup_fd_w);
close(cleanup_fd_w);
}
finish_transfer(cleanup_new_fname, fname, NULL, NULL,
cleanup_file, 0, !partial_dir);
}
/* FALLTHROUGH */
#include "case_N.h"
io_flush(FULL_FLUSH);
/* FALLTHROUGH */
#include "case_N.h"
if (cleanup_fname)
do_unlink(cleanup_fname);
if (code)
kill_all(SIGUSR1);
if (cleanup_pid && cleanup_pid == getpid()) {
char *pidf = lp_pid_file();
if (pidf && *pidf)
unlink(lp_pid_file());
}
if (code == 0) {
if (io_error & IOERR_DEL_LIMIT)
code = exit_code = RERR_DEL_LIMIT;
if (io_error & IOERR_VANISHED)
code = exit_code = RERR_VANISHED;
if (io_error & IOERR_GENERAL || got_xfer_error)
code = exit_code = RERR_PARTIAL;
}
if (code || am_daemon || (logfile_name && (am_server || !verbose)))
log_exit(code, file, line);
/* FALLTHROUGH */
#include "case_N.h"
if (verbose > 2) {
rprintf(FINFO,
"_exit_cleanup(code=%d, file=%s, line=%d): "
"about to call exit(%d)\n",
unmodified_code, file, line, code);
}
/* FALLTHROUGH */
#include "case_N.h"
if (am_server && code)
msleep(100);
close_all();
/* FALLTHROUGH */
default:
break;
}
if (cleanup_got_literal && cleanup_fname && keep_partial) {
char *fname = cleanup_fname;
cleanup_fname = NULL;
if (cleanup_buf) unmap_file(cleanup_buf);
if (cleanup_fd1 != -1) close(cleanup_fd1);
if (cleanup_fd2 != -1) close(cleanup_fd2);
finish_transfer(cleanup_new_fname, fname, cleanup_file);
}
io_flush();
if (cleanup_fname)
do_unlink(cleanup_fname);
if (code) {
kill_all(SIGUSR1);
}
if ((cleanup_pid != 0) && (cleanup_pid == (int) getpid())) {
char *pidf = lp_pid_file();
if (pidf && *pidf) {
unlink(lp_pid_file());
}
}
if (code == 0 && (io_error || log_got_error)) {
code = RERR_PARTIAL;
}
if (code) log_exit(code, file, line);
exit(code);
}
void cleanup_disable(void)
{
cleanup_fname = cleanup_new_fname = NULL;
cleanup_fname = NULL;
cleanup_got_literal = 0;
}
void cleanup_set(const char *fnametmp, const char *fname, struct file_struct *file,
int fd_r, int fd_w)
void cleanup_set(char *fnametmp, char *fname, struct file_struct *file,
struct map_struct *buf, int fd1, int fd2)
{
cleanup_fname = fnametmp;
cleanup_new_fname = fname; /* can be NULL on a partial-dir failure */
cleanup_new_fname = fname;
cleanup_file = file;
cleanup_fd_r = fd_r;
cleanup_fd_w = fd_w;
cleanup_buf = buf;
cleanup_fd1 = fd1;
cleanup_fd2 = fd2;
}
void cleanup_set_pid(pid_t pid)
void cleanup_set_pid(int pid)
{
cleanup_pid = pid;
}

View File

@@ -1,69 +1,60 @@
/*
/* -*- c-file-style: "linux" -*-
rsync -- fast file replication program
Copyright (C) 1992-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.
*/
/**
* @file clientname.c
*
* Functions for looking up the remote name or addr of a socket.
*
* Copyright (C) 1992-2001 Andrew Tridgell <tridge@samba.org>
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2002-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
* This file is now converted to use the new-style getaddrinfo()
* interface, which supports IPv6 but is also supported on recent
* IPv4-only machines. On systems that don't have that interface, we
* emulate it using the KAME implementation.
*/
**/
#include "rsync.h"
static const char default_name[] = "UNKNOWN";
extern int am_server;
/**
* Return the IP addr of the client as a string
* Return the IP addr of the client as a string
**/
char *client_addr(int fd)
{
static char addr_buf[100];
static int initialised;
struct sockaddr_storage ss;
socklen_t length = sizeof ss;
char *ssh_info, *p;
static char addr_buf[100];
static int initialised;
if (initialised)
return addr_buf;
if (initialised) return addr_buf;
initialised = 1;
if (am_server) { /* daemon over --rsh mode */
strlcpy(addr_buf, "0.0.0.0", sizeof addr_buf);
if ((ssh_info = getenv("SSH_CONNECTION")) != NULL
|| (ssh_info = getenv("SSH_CLIENT")) != NULL
|| (ssh_info = getenv("SSH2_CLIENT")) != NULL) {
strlcpy(addr_buf, ssh_info, sizeof addr_buf);
/* Truncate the value to just the IP address. */
if ((p = strchr(addr_buf, ' ')) != NULL)
*p = '\0';
}
} else {
client_sockaddr(fd, &ss, &length);
getnameinfo((struct sockaddr *)&ss, length,
addr_buf, sizeof addr_buf, NULL, 0, NI_NUMERICHOST);
}
client_sockaddr(fd, &ss, &length);
getnameinfo((struct sockaddr *)&ss, length,
addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST);
return addr_buf;
}
@@ -83,67 +74,24 @@ 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;
socklen_t ss_len;
if (initialised)
return name_buf;
if (initialised) return name_buf;
strlcpy(name_buf, default_name, sizeof name_buf);
strcpy(name_buf, default_name);
initialised = 1;
memset(&ss, 0, sizeof ss);
client_sockaddr(fd, &ss, &ss_len);
if (am_server) { /* daemon over --rsh mode */
char *addr = client_addr(fd);
struct addrinfo hint, *answer;
int err;
memset(&hint, 0, sizeof hint);
#ifdef AI_NUMERICHOST
hint.ai_flags = AI_NUMERICHOST;
#endif
hint.ai_socktype = SOCK_STREAM;
if ((err = getaddrinfo(addr, NULL, &hint, &answer)) != 0) {
rprintf(FLOG, "malformed address %s: %s\n",
addr, gai_strerror(err));
return name_buf;
}
switch (answer->ai_family) {
case AF_INET:
ss_len = sizeof (struct sockaddr_in);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#ifdef INET6
case AF_INET6:
ss_len = sizeof (struct sockaddr_in6);
memcpy(&ss, answer->ai_addr, ss_len);
break;
#endif
default:
exit_cleanup(RERR_SOCKETIO);
}
freeaddrinfo(answer);
} else {
ss_len = sizeof ss;
client_sockaddr(fd, &ss, &ss_len);
}
if (lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf,
port_buf, sizeof port_buf) == 0)
check_name(fd, &ss, name_buf, sizeof name_buf);
if (!lookup_name(fd, &ss, ss_len, name_buf, sizeof name_buf, port_buf, sizeof port_buf))
check_name(fd, &ss, ss_len, name_buf, port_buf);
return name_buf;
}
@@ -160,16 +108,15 @@ 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? */
rsyserr(FLOG, errno, "getpeername on fd%d failed", fd);
rprintf(FERROR, RSYNC_NAME ": getpeername on fd%d failed: %s\n",
fd, strerror(errno));
exit_cleanup(RERR_SOCKETIO);
}
#ifdef INET6
if (get_sockaddr_family(ss) == AF_INET6 &&
if (get_sockaddr_family(ss) == AF_INET6 &&
IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)ss)->sin6_addr)) {
/* OK, so ss is in the IPv6 family, but it is really
* an IPv4 address: something like
@@ -180,12 +127,12 @@ void client_sockaddr(int fd,
struct sockaddr_in6 sin6;
struct sockaddr_in *sin;
memcpy(&sin6, ss, sizeof sin6);
memcpy(&sin6, ss, sizeof(sin6));
sin = (struct sockaddr_in *)ss;
memset(sin, 0, sizeof *sin);
memset(sin, 0, sizeof(*sin));
sin->sin_family = AF_INET;
*ss_len = sizeof (struct sockaddr_in);
#ifdef HAVE_SOCKADDR_IN_LEN
*ss_len = sizeof(struct sockaddr_in);
#ifdef HAVE_SOCKADDR_LEN
sin->sin_len = *ss_len;
#endif
sin->sin_port = sin6.sin6_port;
@@ -194,33 +141,32 @@ void client_sockaddr(int fd,
* (IN6_V4MAPPED_TO_SINADDR ?), but it does not seem
* to be present in the Linux headers. */
memcpy(&sin->sin_addr, &sin6.sin6_addr.s6_addr[12],
sizeof sin->sin_addr);
}
sizeof(sin->sin_addr));
}
#endif
}
/**
* 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,
char *name_buf, size_t name_buf_size,
char *port_buf, size_t port_buf_size)
char *name_buf, size_t name_buf_len,
char *port_buf, size_t port_buf_len)
{
int name_err;
/* reverse lookup */
name_err = getnameinfo((struct sockaddr *) ss, ss_len,
name_buf, name_buf_size,
port_buf, port_buf_size,
name_buf, name_buf_len,
port_buf, port_buf_len,
NI_NAMEREQD | NI_NUMERICSERV);
if (name_err != 0) {
strlcpy(name_buf, default_name, name_buf_size);
rprintf(FLOG, "name lookup failed for %s: %s\n",
client_addr(fd), gai_strerror(name_err));
strcpy(name_buf, default_name);
rprintf(FERROR, RSYNC_NAME ": name lookup failed for %s: %s\n",
client_addr(fd),
gai_strerror(name_err));
return name_err;
}
@@ -239,9 +185,10 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
{
int ss_family = get_sockaddr_family(ss);
const char fn[] = "compare_addrinfo_sockaddr";
if (ai->ai_family != ss_family) {
rprintf(FLOG, "%s: response family %d != %d\n",
rprintf(FERROR,
"%s: response family %d != %d\n",
fn, ai->ai_family, ss_family);
return 1;
}
@@ -252,38 +199,25 @@ int compare_addrinfo_sockaddr(const struct addrinfo *ai,
sin1 = (const struct sockaddr_in *) ss;
sin2 = (const struct sockaddr_in *) ai->ai_addr;
return memcmp(&sin1->sin_addr, &sin2->sin_addr,
sizeof sin1->sin_addr);
}
#ifdef INET6
if (ss_family == AF_INET6) {
else if (ss_family == AF_INET6) {
const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *) ss;
sin2 = (const struct sockaddr_in6 *) ai->ai_addr;
if (ai->ai_addrlen < sizeof (struct sockaddr_in6)) {
rprintf(FLOG, "%s: too short sockaddr_in6; length=%d\n",
fn, (int)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;
return memcmp(&sin1->sin6_addr, &sin2->sin6_addr,
sizeof sin1->sin6_addr);
}
#endif /* INET6 */
/* don't know */
return 1;
else {
/* don't know */
return 1;
}
}
@@ -292,31 +226,31 @@ 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, size_t name_buf_size)
socklen_t ss_len,
char *name_buf,
const char *port_buf)
{
struct addrinfo hints, *res, *res0;
int error;
int ss_family = get_sockaddr_family(ss);
memset(&hints, 0, sizeof hints);
memset(&hints, 0, sizeof(hints));
hints.ai_family = ss_family;
hints.ai_flags = AI_CANONNAME;
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(name_buf, NULL, &hints, &res0);
error = getaddrinfo(name_buf, port_buf, &hints, &res0);
if (error) {
rprintf(FLOG, "forward name lookup for %s failed: %s\n",
rprintf(FERROR,
RSYNC_NAME ": forward name lookup for %s failed: %s\n",
name_buf, gai_strerror(error));
strlcpy(name_buf, default_name, name_buf_size);
strcpy(name_buf, default_name);
return error;
}
/* Given all these results, we expect that one of them will be
* the same as ss. The comparison is a bit complicated. */
for (res = res0; res; res = res->ai_next) {
@@ -327,17 +261,23 @@ int check_name(int fd,
if (!res0) {
/* We hit the end of the list without finding an
* address that was the same as ss. */
rprintf(FLOG, "no known address for \"%s\": "
"spoofed address?\n", name_buf);
strlcpy(name_buf, default_name, name_buf_size);
rprintf(FERROR, RSYNC_NAME
": no known address for \"%s\": "
"spoofed address?\n",
name_buf);
strcpy(name_buf, default_name);
} else if (res == NULL) {
/* We hit the end of the list without finding an
* address that was the same as ss. */
rprintf(FLOG, "%s is not a known address for \"%s\": "
"spoofed address?\n", client_addr(fd), name_buf);
strlcpy(name_buf, default_name, name_buf_size);
rprintf(FERROR, RSYNC_NAME
": %s is not a known address for \"%s\": "
"spoofed address?\n",
client_addr(fd),
name_buf);
strcpy(name_buf, default_name);
}
freeaddrinfo(res0);
return 0;
}

View File

File diff suppressed because it is too large Load Diff

342
compat.c
View File

@@ -1,307 +1,75 @@
/*
* Compatibility routines for older rsync protocol versions.
*
* Copyright (C) Andrew Tridgell 1996
* Copyright (C) Paul Mackerras 1996
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
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.
*/
/* compatability routines for older rsync protocol versions */
#include "rsync.h"
int remote_protocol = 0;
int file_extra_cnt = 0; /* count of file-list extras that everyone gets */
int inc_recurse = 0;
extern int verbose;
extern int am_server;
extern int am_sender;
extern int local_server;
extern int inplace;
extern int recurse;
extern int use_qsort;
extern int allow_inc_recurse;
extern int append_mode;
extern int fuzzy_basis;
extern int read_batch;
extern int delay_updates;
extern int checksum_seed;
extern int basis_dir_cnt;
extern int prune_empty_dirs;
extern int protocol_version;
extern int protect_args;
extern int preserve_links;
extern int preserve_perms;
extern int preserve_devices;
extern int preserve_uid;
extern int preserve_gid;
extern int preserve_acls;
extern int preserve_xattrs;
extern int need_messages_from_generator;
extern int delete_mode, delete_before, delete_during, delete_after;
extern char *shell_cmd;
extern char *partial_dir;
extern char *dest_option;
extern char *files_from;
extern char *filesfrom_host;
extern struct filter_list_struct filter_list;
extern int need_unsorted_flist;
#ifdef ICONV_OPTION
extern iconv_t ic_send, ic_recv;
#endif
extern int preserve_times;
extern int always_checksum;
extern int checksum_seed;
/* These index values are for the file-list's extra-attribute array. */
int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
extern int remote_version;
extern int verbose;
#ifdef ICONV_OPTION
int filesfrom_convert = 0;
#endif
#define CF_INC_RECURSE (1<<0)
#define CF_SYMLINK_TIMES (1<<1)
static const char *client_info;
/* The server makes sure that if either side only supports a pre-release
* version of a protocol, that both sides must speak a compatible version
* of that protocol for it to be advertised as available. */
static void check_sub_protocol(void)
{
char *dot;
int their_protocol, their_sub;
#if SUBPROTOCOL_VERSION != 0
int our_sub = protocol_version < PROTOCOL_VERSION ? 0 : SUBPROTOCOL_VERSION;
#else
int our_sub = 0;
#endif
/* client_info starts with VER.SUB string if client is a pre-release. */
if (!(their_protocol = atoi(client_info))
|| !(dot = strchr(client_info, '.'))
|| !(their_sub = atoi(dot+1))) {
#if SUBPROTOCOL_VERSION != 0
if (our_sub)
protocol_version--;
#endif
return;
}
if (their_protocol < protocol_version) {
if (their_sub)
protocol_version = their_protocol - 1;
return;
}
if (their_protocol > protocol_version)
their_sub = 0; /* 0 == final version of older protocol */
if (their_sub != our_sub)
protocol_version--;
}
void set_allow_inc_recurse(void)
{
client_info = shell_cmd ? shell_cmd : "";
if (!recurse || use_qsort)
allow_inc_recurse = 0;
else if (!am_sender
&& (delete_before || delete_after
|| delay_updates || prune_empty_dirs))
allow_inc_recurse = 0;
else if (am_server && !local_server
&& (strchr(client_info, 'i') == NULL))
allow_inc_recurse = 0;
}
extern int read_batch; /* dw */
extern int write_batch; /* dw */
void setup_protocol(int f_out,int f_in)
{
if (am_sender)
file_extra_cnt += PTR_EXTRA_CNT;
else
file_extra_cnt++;
if (preserve_uid)
uid_ndx = ++file_extra_cnt;
if (preserve_gid)
gid_ndx = ++file_extra_cnt;
if (preserve_acls && !am_sender)
acls_ndx = ++file_extra_cnt;
if (preserve_xattrs)
xattrs_ndx = ++file_extra_cnt;
if (am_server)
set_allow_inc_recurse();
if (remote_protocol == 0) {
if (am_server && !local_server)
check_sub_protocol();
if (!read_batch)
write_int(f_out, protocol_version);
remote_protocol = read_int(f_in);
if (protocol_version > remote_protocol)
protocol_version = remote_protocol;
}
if (read_batch && remote_protocol > protocol_version) {
rprintf(FERROR, "The protocol version in the batch file is too new (%d > %d).\n",
remote_protocol, protocol_version);
exit_cleanup(RERR_PROTOCOL);
if (remote_version == 0) {
if (am_server) {
remote_version = read_int(f_in);
write_int(f_out,PROTOCOL_VERSION);
} else {
write_int(f_out,PROTOCOL_VERSION);
remote_version = read_int(f_in);
}
}
if (verbose > 3) {
rprintf(FINFO, "(%s) Protocol versions: remote=%d, negotiated=%d\n",
am_server? "Server" : "Client", remote_protocol, protocol_version);
}
if (remote_protocol < MIN_PROTOCOL_VERSION
|| remote_protocol > MAX_PROTOCOL_VERSION) {
rprintf(FERROR,"protocol version mismatch -- is your shell clean?\n");
if (remote_version < MIN_PROTOCOL_VERSION ||
remote_version > MAX_PROTOCOL_VERSION) {
rprintf(FERROR,"protocol version mismatch - is your shell clean?\n");
rprintf(FERROR,"(see the rsync man page for an explanation)\n");
exit_cleanup(RERR_PROTOCOL);
}
if (remote_protocol < OLD_PROTOCOL_VERSION) {
rprintf(FINFO,"%s is very old version of rsync, upgrade recommended.\n",
am_server? "Client" : "Server");
}
if (protocol_version < MIN_PROTOCOL_VERSION) {
rprintf(FERROR, "--protocol must be at least %d on the %s.\n",
MIN_PROTOCOL_VERSION, am_server? "Server" : "Client");
exit_cleanup(RERR_PROTOCOL);
}
if (protocol_version > PROTOCOL_VERSION) {
rprintf(FERROR, "--protocol must be no more than %d on the %s.\n",
PROTOCOL_VERSION, am_server? "Server" : "Client");
exit_cleanup(RERR_PROTOCOL);
}
if (read_batch)
check_batch_flags();
if (protocol_version < 30) {
if (append_mode == 1)
append_mode = 2;
if (preserve_acls && !local_server) {
rprintf(FERROR,
"--acls requires protocol 30 or higher"
" (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (preserve_xattrs && !local_server) {
rprintf(FERROR,
"--xattrs requires protocol 30 or higher"
" (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
}
if (delete_mode && !(delete_before+delete_during+delete_after)) {
if (protocol_version < 30)
delete_before = 1;
else
delete_during = 1;
}
if (protocol_version < 29) {
if (fuzzy_basis) {
rprintf(FERROR,
"--fuzzy requires protocol 29 or higher"
" (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (basis_dir_cnt && inplace) {
rprintf(FERROR,
"%s with --inplace requires protocol 29 or higher"
" (negotiated %d).\n",
dest_option, protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (basis_dir_cnt > 1) {
rprintf(FERROR,
"Using more than one %s option requires protocol"
" 29 or higher (negotiated %d).\n",
dest_option, protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
if (prune_empty_dirs) {
rprintf(FERROR,
"--prune-empty-dirs requires protocol 29 or higher"
" (negotiated %d).\n",
protocol_version);
exit_cleanup(RERR_PROTOCOL);
}
} else if (protocol_version >= 30) {
int compat_flags;
}
if (remote_version >= 12) {
if (am_server) {
compat_flags = allow_inc_recurse ? CF_INC_RECURSE : 0;
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
compat_flags |= CF_SYMLINK_TIMES;
#endif
write_byte(f_out, compat_flags);
} else
compat_flags = read_byte(f_in);
/* The inc_recurse var MUST be set to 0 or 1. */
inc_recurse = compat_flags & CF_INC_RECURSE ? 1 : 0;
if (am_sender) {
receiver_symlink_times = am_server
? strchr(client_info, 'L') != NULL
: !!(compat_flags & CF_SYMLINK_TIMES);
}
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
else
receiver_symlink_times = 1;
#endif
if (inc_recurse && !allow_inc_recurse) {
/* This should only be able to happen in a batch. */
fprintf(stderr,
"Incompatible options specified for inc-recursive %s.\n",
read_batch ? "batch file" : "connection");
exit_cleanup(RERR_SYNTAX);
}
need_messages_from_generator = 1;
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
} else if (!am_sender) {
receiver_symlink_times = 1;
#endif
}
if (need_unsorted_flist && (!am_sender || inc_recurse))
unsort_ndx = ++file_extra_cnt;
if (partial_dir && *partial_dir != '/' && (!am_server || local_server)) {
int flags = MATCHFLG_NO_PREFIXES | MATCHFLG_DIRECTORY;
if (!am_sender || protocol_version >= 30)
flags |= MATCHFLG_PERISHABLE;
parse_rule(&filter_list, partial_dir, flags, 0);
}
#ifdef ICONV_OPTION
if (protect_args && files_from) {
if (am_sender)
filesfrom_convert = filesfrom_host && ic_send != (iconv_t)-1;
else
filesfrom_convert = !filesfrom_host && ic_recv != (iconv_t)-1;
}
#endif
if (am_server) {
if (!checksum_seed)
if (read_batch || write_batch) /* dw */
checksum_seed = 32761;
else
checksum_seed = time(NULL);
write_int(f_out, checksum_seed);
} else {
checksum_seed = read_int(f_in);
write_int(f_out,checksum_seed);
} else {
checksum_seed = read_int(f_in);
}
}
checksum_init();
}

989
config.guess vendored
View File

File diff suppressed because it is too large Load Diff

493
config.sub vendored
View File

@@ -1,10 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
# Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
# Free Software Foundation, Inc.
timestamp='2006-07-02'
timestamp='2001-06-08'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -22,17 +21,15 @@ timestamp='2006-07-02'
#
# 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., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# 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>. Submit a context
# diff and a properly formatted ChangeLog entry.
# Please send patches to <config-patches@gnu.org>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -72,7 +69,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
@@ -85,11 +82,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit ;;
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit ;;
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -101,7 +98,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
exit ;;
exit 0;;
* )
break ;;
@@ -120,9 +117,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* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
@@ -148,7 +143,7 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray)
-apple | -axis)
os=
basic_machine=$1
;;
@@ -173,10 +168,6 @@ case $os in
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -193,10 +184,6 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -236,56 +223,26 @@ esac
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| mt \
| msp430 \
| nios | nios2 \
| ns16k | ns32k \
| or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
| z8k)
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)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
@@ -295,9 +252,6 @@ case $basic_machine in
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -311,66 +265,31 @@ case $basic_machine in
exit 1
;;
# Recognize the basic CPU types with company name.
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-* | avr32-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | 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-* | iq2000-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
| xstormy16-* | xtensa-* \
| ymp-* \
| z8k-*)
# 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-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -388,9 +307,6 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
@@ -405,12 +321,6 @@ case $basic_machine in
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amd64-*)
basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
@@ -442,10 +352,6 @@ 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
@@ -466,45 +372,30 @@ case $basic_machine in
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
cray | ymp)
basic_machine=ymp-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
cray2)
basic_machine=cray2-cray
os=-unicos
;;
cr16c)
basic_machine=cr16c-unknown
os=-elf
[cjt]90)
basic_machine=${basic_machine}-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
crx)
basic_machine=crx-unknown
os=-elf
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
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
@@ -513,10 +404,6 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
@@ -689,27 +576,32 @@ 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/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
mvs)
basic_machine=i370-ibm
os=-mvs
@@ -785,13 +677,6 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
basic_machine=or32-unknown
;;
os400)
basic_machine=powerpc-ibm
os=-os400
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
@@ -814,64 +699,42 @@ case $basic_machine in
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
pentium | p5 | k5 | k6 | nexgen)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
pentiumpro | p6 | 6x86 | athlon)
basic_machine=i686-pc
;;
pentiumii | pentium2 | pentiumiii | pentium3)
pentiumii | pentium2)
basic_machine=i686-pc
;;
pentium4)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
pentium-* | p5-* | k5-* | k6-* | nexgen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
pentiumii-* | pentium2-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium4-*)
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
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
;;
@@ -879,10 +742,6 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -893,26 +752,10 @@ 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
;;
sei)
basic_machine=mips-sei
os=-seiux
;;
sequent)
basic_machine=i386-sequent
;;
@@ -920,10 +763,7 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh64)
basic_machine=sh64-unknown
;;
sparclite-wrs | simso-wrs)
sparclite-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
@@ -990,42 +830,22 @@ case $basic_machine in
os=-dynix
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
basic_machine=t3e-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
tpf)
basic_machine=s390x-ibm
os=-tpf
;;
udi29k)
basic_machine=a29k-amd
os=-udi
@@ -1047,8 +867,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
@@ -1069,17 +889,17 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
windows32)
basic_machine=i386-pc
os=-windows32-msvcrt
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
xmp)
basic_machine=xmp-cray
os=-unicos
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
@@ -1100,12 +920,16 @@ 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
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
@@ -1122,13 +946,13 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
sh3 | sh4)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
cydra)
basic_machine=cydra-cydrome
;;
orion)
@@ -1143,6 +967,10 @@ 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.
;;
@@ -1198,23 +1026,16 @@ case $os in
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers*)
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1226,21 +1047,16 @@ case $os in
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
os=-nto-qnx
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux-dietlibc)
os=-linux-dietlibc
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
@@ -1253,9 +1069,6 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
os=-os400
;;
-wince*)
os=-wince
;;
@@ -1274,23 +1087,14 @@ case $os in
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-syllable*)
os=-syllable
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
os=-nextstep2
;;
-nsk*)
os=-nsk
@@ -1302,9 +1106,6 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
os=-tpf
;;
-triton*)
os=-sysv3
;;
@@ -1332,17 +1133,8 @@ case $os in
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-none)
;;
@@ -1366,9 +1158,6 @@ else
# system, and we'll never get to this point.
case $basic_machine in
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
@@ -1378,14 +1167,10 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
pdp11-*)
os=-none
;;
*-dec | vax-*)
@@ -1412,9 +1197,6 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
@@ -1424,15 +1206,9 @@ case $basic_machine in
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
@@ -1484,19 +1260,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)
@@ -1565,16 +1341,10 @@ case $basic_machine in
-mvs* | -opened*)
vendor=ibm
;;
-os400*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-tpf*)
vendor=ibm
;;
-vxsim* | -vxworks* | -windiss*)
-vxsim* | -vxworks*)
vendor=wrs
;;
-aux*)
@@ -1589,16 +1359,13 @@ 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/"`
;;
esac
echo $basic_machine$os
exit
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)

25
configure vendored
View File

@@ -1,25 +0,0 @@
#!/bin/sh -e
# This configure script ensures that the configure.sh script exists, and
# if not, it tries to fetch rsync's generated files or build them. We
# then transfer control to the configure.sh script to do the real work.
dir=`dirname $0`
realconfigure="$dir/configure.sh"
if test ! -f "$realconfigure"; then
if test -f "$HOME/build_farm/build_test.fns"; then
# Allow the build farm to grab latest files via rsync.
actions='build fetch'
else
actions='build'
fi
if "$dir/prepare-source" $actions; then
:
else
echo 'Failed to build configure.sh and/or config.h.in -- giving up.' >&2
rm -f "$realconfigure"
exit 1
fi
fi
exec "$realconfigure" "${@}"

View File

@@ -3,9 +3,9 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT()
AC_CONFIG_SRCDIR([byteorder.h])
AC_CONFIG_HEADER(config.h)
AC_PREREQ(2.59)
AC_PREREQ(2.52)
RSYNC_VERSION=3.0.2
RSYNC_VERSION=2.5.2pre3
AC_SUBST(RSYNC_VERSION)
AC_MSG_NOTICE([Configuring rsync $RSYNC_VERSION])
@@ -18,7 +18,6 @@ AC_CANONICAL_TARGET([])
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CPP
AC_PROG_EGREP
AC_PROG_INSTALL
AC_PROG_CC_STDC
AC_SUBST(SHELL)
@@ -26,7 +25,8 @@ AC_SUBST(SHELL)
AC_DEFINE([_GNU_SOURCE], 1,
[Define _GNU_SOURCE so that we get all necessary prototypes])
if test x"$ac_cv_prog_cc_stdc" = x"no"; then
if test "$xac_cv_prog_cc_stdc" = xno
then
AC_MSG_WARN([rsync requires an ANSI C compiler and you don't seem to have one])
fi
@@ -37,10 +37,12 @@ fi
AC_MSG_CHECKING([whether to include debugging symbols])
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--disable-debug],
[disable debugging symbols and features]))
AC_HELP_STRING([--enable-debug],
[including debugging symbols and features (default yes)]),
[], [])
if test x"$enable_debug" = x"no"; then
if test x"$enable_debug" = x"no"
then
AC_MSG_RESULT(no)
CFLAGS=${CFLAGS-"-O"}
else
@@ -51,104 +53,42 @@ else
fi
AC_ARG_ENABLE(profile,
AC_HELP_STRING([--enable-profile],
[turn on CPU profiling]))
if test x"$enable_profile" = x"yes"; then
AC_HELP_STRING([--enable-profile],
[turn on CPU profiling (default no)],
[], []))
if test x"$enable_profile" = xyes
then
CFLAGS="$CFLAGS -pg"
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" = x"yes"; 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"
# If GCC, turn on warnings.
if test x"$GCC" = x"yes"; then
if test "x$GCC" = "xyes"
then
CFLAGS="$CFLAGS -Wall -W"
fi
AC_ARG_WITH(included-popt,
AC_HELP_STRING([--with-included-popt], [use bundled popt library, not from system]))
[ --with-included-popt use bundled popt library, not from system])
AC_ARG_WITH(rsync-path,
AC_HELP_STRING([--with-rsync-path=PATH], [set default --rsync-path to PATH (default: rsync)]),
[ --with-rsync-path=PATH set default --rsync-path to PATH (default: \"rsync\")],
[ RSYNC_PATH="$with_rsync_path" ],
[ RSYNC_PATH="rsync" ])
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [location of rsync on remote machine])
AC_ARG_WITH(rsyncd-conf,
AC_HELP_STRING([--with-rsyncd-conf=PATH], [set configuration file for rsync server to PATH (default: /etc/rsyncd.conf)]),
[ if test ! -z "$with_rsyncd_conf" ; then
case $with_rsyncd_conf in
yes|no)
RSYNCD_SYSCONF="/etc/rsyncd.conf"
;;
/*)
RSYNCD_SYSCONF="$with_rsyncd_conf"
;;
*)
AC_MSG_ERROR(You must specify an absolute path to --with-rsyncd-conf=PATH)
;;
esac
else
RSYNCD_SYSCONF="/etc/rsyncd.conf"
fi ],
[ RSYNCD_SYSCONF="/etc/rsyncd.conf" ])
AC_DEFINE_UNQUOTED(RSYNCD_SYSCONF, "$RSYNCD_SYSCONF", [location of configuration file for rsync server])
AC_ARG_WITH(rsh,
AC_HELP_STRING([--with-rsh=CMD], [set remote shell command to CMD (default: ssh)]))
AC_DEFINE_UNQUOTED(RSYNC_PATH, "$RSYNC_PATH", [ ])
AC_CHECK_PROG(HAVE_REMSH, remsh, 1, 0)
if test x$HAVE_REMSH = x1; then
AC_DEFINE(HAVE_REMSH, 1, [Define to 1 if remote shell is remsh, not rsh])
fi
AC_DEFINE_UNQUOTED(HAVE_REMSH, $HAVE_REMSH, [ ])
if test x"$with_rsh" != x; then
RSYNC_RSH="$with_rsh"
else
RSYNC_RSH="ssh"
fi
AC_DEFINE_UNQUOTED(RSYNC_RSH, "$RSYNC_RSH", [default -e command])
AC_CHECK_PROG(HAVE_YODL2MAN, yodl2man, 1, 0)
if test x$HAVE_YODL2MAN = x1; then
MAKE_MAN=man
fi
AC_ARG_WITH(nobody-group,
AC_HELP_STRING([--with-nobody-group=GROUP],
[set the default unprivileged group (default nobody or nogroup)]),
[ NOBODY_GROUP="$with_nobody_group" ])
if test x"$with_nobody_group" = x; then
AC_MSG_CHECKING([the group for user "nobody"])
if grep '^nobody:' /etc/group >/dev/null 2>&1; then
NOBODY_GROUP=nobody
elif grep '^nogroup:' /etc/group >/dev/null 2>&1; then
NOBODY_GROUP=nogroup
else
NOBODY_GROUP=nobody # test for others?
fi
AC_MSG_RESULT($NOBODY_GROUP)
fi
AC_DEFINE_UNQUOTED(NOBODY_USER, "nobody", [unprivileged user--e.g. nobody])
AC_DEFINE_UNQUOTED(NOBODY_GROUP, "$NOBODY_GROUP", [unprivileged group for unprivileged user])
# arrgh. libc in some old debian version screwed up the largefile
# arrgh. libc in the current debian stable screws up the largefile
# stuff, getting byte range locking wrong
AC_CACHE_CHECK([for broken largefile support],rsync_cv_HAVE_BROKEN_LARGEFILE,[
AC_TRY_RUN([
@@ -158,29 +98,24 @@ AC_TRY_RUN([
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
int main(void)
{
struct flock lock;
int status;
char tpl[32] = "/tmp/locktest.XXXXXX";
int fd = mkstemp(tpl);
if (fd < 0) {
strcpy(tpl, "conftest.dat");
fd = open(tpl, O_CREAT|O_RDWR, 0600);
}
int status;
int fd = open("conftest.dat", O_CREAT|O_RDWR, 0600);
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 1;
lock.l_pid = 0;
fcntl(fd,F_SETLK,&lock);
if (fork() == 0) {
lock.l_start = 1;
_exit(fcntl(fd,F_SETLK,&lock) == 0);
}
wait(&status);
unlink(tpl);
lock.l_start = 1;
exit(fcntl(fd,F_SETLK,&lock) == 0);
}
wait(&status);
unlink("conftest.dat");
exit(WEXITSTATUS(status));
}
],
@@ -193,10 +128,11 @@ ipv6type=unknown
ipv6lib=none
ipv6trylibc=yes
AC_ARG_ENABLE(ipv6,
AC_HELP_STRING([--disable-ipv6],
[don't even try to use IPv6]))
if test x"$enable_ipv6" != x"no"; then
AC_ARG_ENABLE(ipv6,
AC_HELP_STRING([--disable-ipv6], [don't even try to use IPv6]))
if test "x$enable_ipv6" != xno
then
AC_MSG_CHECKING([ipv6 stack type])
for i in inria kame linux-glibc linux-inet6 toshiba v6d zeta; do
case $i in
@@ -218,7 +154,7 @@ yes
#ifdef __KAME__
yes
#endif],
[ipv6type=$i;
[ipv6type=$i;
AC_DEFINE(INET6, 1, [true if you have IPv6])])
;;
linux-glibc)
@@ -285,92 +221,40 @@ yes
AC_SEARCH_LIBS(getaddrinfo, inet6)
fi
dnl Do you want to disable use of locale functions
AC_ARG_ENABLE([locale],
AC_HELP_STRING([--disable-locale],
[disable locale features]))
AH_TEMPLATE([CONFIG_LOCALE],
[Undefine if you don't want locale features. By default this is defined.])
if test x"$enable_locale" != x"no"; then
AC_DEFINE(CONFIG_LOCALE)
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 to 1 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 compat.h sys/param.h ctype.h sys/wait.h \
sys/ioctl.h sys/filio.h string.h stdlib.h sys/socket.h sys/mode.h \
sys/un.h sys/attr.h mcheck.h arpa/inet.h arpa/nameser.h locale.h \
netdb.h malloc.h float.h limits.h iconv.h libcharset.h langinfo.h \
sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h \
popt.h popt/popt.h)
AC_HEADER_MAJOR
AC_CACHE_CHECK([if makedev takes 3 args],rsync_cv_MAKEDEV_TAKES_3_ARGS,[
AC_TRY_RUN([
#include <sys/types.h>
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
# if !defined makedev && (defined mkdev || defined _WIN32 || defined __WIN32__)
# define makedev mkdev
# endif
#elif defined MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#endif
int main(void)
{
dev_t dev = makedev(0, 5, 7);
if (major(dev) != 5 || minor(dev) != 7)
exit(1);
return 0;
}
],
rsync_cv_MAKEDEV_TAKES_3_ARGS=yes,rsync_cv_MAKEDEV_TAKES_3_ARGS=no,rsync_cv_MAKEDEV_TAKES_3_ARGS=no)])
if test x"$rsync_cv_MAKEDEV_TAKES_3_ARGS" = x"yes"; then
AC_DEFINE(MAKEDEV_TAKES_3_ARGS, 1, [Define to 1 if makedev() takes 3 args])
fi
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(netdb.h)
AC_CHECK_HEADERS(malloc.h)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(long long)
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int16_t)
AC_CHECK_SIZEOF(uint16_t)
AC_CHECK_SIZEOF(int32_t)
AC_CHECK_SIZEOF(uint32_t)
AC_CHECK_SIZEOF(int64_t)
AC_CHECK_SIZEOF(off_t)
AC_CHECK_SIZEOF(off64_t)
AC_CHECK_SIZEOF(time_t)
AC_C_INLINE
AC_C_LONG_DOUBLE
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_CHECK_TYPES([mode_t,off_t,size_t,pid_t,id_t])
AC_TYPE_MODE_T
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_TYPE_PID_T
AC_TYPE_GETGROUPS
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_TYPE([ino_t], [unsigned])
TYPE_SOCKLEN_T
AC_CACHE_CHECK([for errno in errno.h],rsync_cv_errno, [
AC_TRY_COMPILE([#include <errno.h>],[int i = errno],
rsync_cv_errno=yes,rsync_cv_have_errno_decl=no)])
if test x"$rsync_cv_errno" = x"yes"; then
AC_DEFINE(HAVE_ERRNO_DECL, 1, [Define to 1 if errno is declared in errno.h])
AC_DEFINE(HAVE_ERRNO_DECL, 1, [ ])
fi
# The following test taken from the cvs sources
@@ -401,133 +285,40 @@ if test x"$ac_cv_func_connect" = x"no"; then
esac
dnl We can't just call AC_CHECK_FUNCS(connect) here, because the value
dnl has been cached.
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
if test x"$ac_cv_lib_socket_connect" = x"yes" ||
test x"$ac_cv_lib_inet_connect" = x"yes"; then
# ac_cv_func_connect=yes
# don't! it would cause AC_CHECK_FUNC to succeed next time configure is run
AC_DEFINE(HAVE_CONNECT, 1, [Define to 1 if you have the "connect" function])
AC_DEFINE(HAVE_CONNECT, 1, [ ])
fi
fi
AC_SEARCH_LIBS(inet_ntop, resolv)
# Solaris and HP-UX weirdness:
# Search for libiconv_open (not iconv_open) to discover if -liconv is needed!
AC_SEARCH_LIBS(libiconv_open, iconv)
AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL(am_cv_proto_iconv, [
AC_TRY_COMPILE([
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const")
am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'`
AC_MSG_RESULT([$]{ac_t:-
}[$]am_cv_proto_iconv)
AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1,
[Define as const if the declaration of iconv() needs const.])
AC_CHECK_LIB(resolv, inet_ntop)
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(inet_ntop, , AC_LIBOBJ(lib/inet_ntop))
AC_CHECK_FUNCS(inet_pton, , AC_LIBOBJ(lib/inet_pton))
AC_HAVE_TYPE([struct addrinfo], [#include <netdb.h>])
AC_HAVE_TYPE([struct sockaddr_storage], [#include <sys/types.h>
#include <sys/socket.h>])
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" -a x"$ac_cv_type_struct_addrinfo" = 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 to 1 if you have the "getaddrinfo" function and required types.])],
[AC_MSG_RESULT([no])
AC_LIBOBJ(lib/getaddrinfo)])])
else
AC_LIBOBJ(lib/getaddrinfo)
fi
AC_CHECK_MEMBER([struct sockaddr.sa_len],
[ AC_DEFINE(HAVE_SOCKADDR_LEN, 1, [Do we have sockaddr.sa_len?]) ],
AC_CHECK_MEMBER([struct sockaddr.sa_len],
[ AC_DEFINE(HAVE_SOCKADDR_LEN) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
])
AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
[ AC_DEFINE(HAVE_SOCKADDR_IN_LEN, 1, [Do we have sockaddr_in.sin_len?]) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
])
AC_CHECK_MEMBER([struct sockaddr_un.sun_len],
[ AC_DEFINE(HAVE_SOCKADDR_UN_LEN, 1, [Do we have sockaddr_un.sun_len?]) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
])
AC_CHECK_MEMBER([struct sockaddr_in6.sin6_scope_id],
[ AC_DEFINE(HAVE_SOCKADDR_IN6_SCOPE_ID, 1, [Do we have sockaddr_in6.sin6_scope_id?]) ],
[],
[
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
])
AC_HAVE_TYPE([struct stat64], [#include <stdio.h>
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# if HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
])
AC_MSG_CHECKING(struct sockaddr_storage)
AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/socket.h>],
[struct sockaddr_storage x;],
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1,
[Define if you have strct sockaddr_storage.] ),
AC_MSG_RESULT(no))
# if we can't find strcasecmp, look in -lresolv (for Unixware at least)
#
@@ -536,108 +327,16 @@ if test x"$ac_cv_func_strcasecmp" = x"no"; then
AC_CHECK_LIB(resolv, strcasecmp)
fi
AC_CHECK_FUNCS(aclsort)
if test x"$ac_cv_func_aclsort" = x"no"; then
AC_CHECK_LIB(sec, aclsort)
fi
dnl At the moment we don't test for a broken memcmp(), because all we
dnl need to do is test for equality, not comparison, and it seems that
dnl every platform has a memcmp that can do at least that.
dnl every platform has a memcmp that can do at least that.
dnl AC_FUNC_MEMCMP
AC_FUNC_UTIME_NULL
AC_FUNC_ALLOCA
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup chown chmod lchmod mknod mkfifo \
fchmod fstat ftruncate strchr readlink link utime utimes lutimes strftime \
memmove lchown vsnprintf snprintf vasprintf asprintf setsid strpbrk \
strlcat strlcpy strtol mallinfo getgroups setgroups geteuid getegid \
setlocale setmode open64 lseek64 mkstemp64 mtrace va_copy __va_copy \
strerror putenv iconv_open locale_charset nl_langinfo getxattr \
extattr_get_link sigaction sigprocmask setattrlist)
dnl cygwin iconv.h defines iconv_open as libiconv_open
if test x"$ac_cv_func_iconv_open" != x"yes"; then
AC_CHECK_FUNC(libiconv_open, [ac_cv_func_iconv_open=yes; AC_DEFINE(HAVE_ICONV_OPEN, 1)])
fi
AC_CHECK_FUNCS(getpgrp tcgetpgrp)
if test $ac_cv_func_getpgrp = yes; then
AC_FUNC_GETPGRP
fi
AC_ARG_ENABLE(iconv,
AC_HELP_STRING([--disable-iconv],
[disable rsync's --iconv option]),
[], [enable_iconv=$ac_cv_func_iconv_open])
AH_TEMPLATE([ICONV_OPTION],
[Define if you want the --iconv option. Specifing a value will set the
default iconv setting (a NULL means no --iconv processing by default).])
if test x"$enable_iconv" != x"no"; then
if test x"$enable_iconv" = x"yes"; then
AC_DEFINE(ICONV_OPTION, NULL)
else
AC_DEFINE_UNQUOTED(ICONV_OPTION, "$enable_iconv")
fi
AC_DEFINE(UTF8_CHARSET, "UTF-8", [String to pass to iconv() for the UTF-8 charset.])
fi
AC_CACHE_CHECK([whether chown() modifies symlinks],rsync_cv_chown_modifies_symlink,[
AC_TRY_RUN([
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>
main() {
char const *dangling_symlink = "conftest.dangle";
unlink(dangling_symlink);
if (symlink("conftest.no-such", dangling_symlink) < 0) abort();
if (chown(dangling_symlink, getuid(), getgid()) < 0 && errno == ENOENT) exit(1);
exit(0);
}],
rsync_cv_chown_modifies_symlink=yes,rsync_cv_chown_modifies_symlink=no,rsync_cv_chown_modifies_symlink=no)])
if test $rsync_cv_chown_modifies_symlink = yes; then
AC_DEFINE(CHOWN_MODIFIES_SYMLINK, 1, [Define to 1 if chown modifies symlinks.])
fi
AC_CACHE_CHECK([whether link() can hard-link symlinks],rsync_cv_can_hardlink_symlink,[
AC_TRY_RUN([
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>
#define FILENAME "conftest.dangle"
main() {
unlink(FILENAME);
if (symlink("conftest.no-such", FILENAME) < 0) abort();
if (link(FILENAME, FILENAME "2") < 0) exit(1);
exit(0);
}],
rsync_cv_can_hardlink_symlink=yes,rsync_cv_can_hardlink_symlink=no,rsync_cv_can_hardlink_symlink=no)])
if test $rsync_cv_can_hardlink_symlink = yes; then
AC_DEFINE(CAN_HARDLINK_SYMLINK, 1, [Define to 1 if link() can hard-link symlinks.])
fi
AC_CACHE_CHECK([whether link() can hard-link special files],rsync_cv_can_hardlink_special,[
AC_TRY_RUN([
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>
#define FILENAME "conftest.fifi"
main() {
unlink(FILENAME);
if (mkfifo(FILENAME, 0777) < 0) abort();
if (link(FILENAME, FILENAME "2") < 0) exit(1);
exit(0);
}],
rsync_cv_can_hardlink_special=yes,rsync_cv_can_hardlink_special=no,rsync_cv_can_hardlink_special=no)])
if test $rsync_cv_can_hardlink_special = yes; then
AC_DEFINE(CAN_HARDLINK_SPECIAL, 1, [Define to 1 if link() can hard-link special files.])
fi
AC_CHECK_FUNCS(waitpid wait4 getcwd strdup strerror chown chmod mknod)
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)
AC_CACHE_CHECK([for working socketpair],rsync_cv_HAVE_SOCKETPAIR,[
AC_TRY_RUN([
@@ -650,42 +349,66 @@ main() {
}],
rsync_cv_HAVE_SOCKETPAIR=yes,rsync_cv_HAVE_SOCKETPAIR=no,rsync_cv_HAVE_SOCKETPAIR=cross)])
if test x"$rsync_cv_HAVE_SOCKETPAIR" = x"yes"; then
AC_DEFINE(HAVE_SOCKETPAIR, 1, [Define to 1 if you have the "socketpair" function])
AC_DEFINE(HAVE_SOCKETPAIR, 1, [ ])
fi
if test x"$with_included_popt" != x"yes"; then
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
AC_CACHE_CHECK([for working fnmatch],rsync_cv_HAVE_FNMATCH,[
AC_TRY_RUN([#include <fnmatch.h>
main() { exit((fnmatch("*.o", "x.o", FNM_PATHNAME) == 0 &&
fnmatch("a/b/*", "a/b/c/d", FNM_PATHNAME) != 0) ? 0: 1); }],
rsync_cv_HAVE_FNMATCH=yes,rsync_cv_HAVE_FNMATCH=no,rsync_cv_HAVE_FNMATCH=cross)])
if test x"$rsync_cv_HAVE_FNMATCH" = x"yes"; then
AC_DEFINE(HAVE_FNMATCH, 1, [ ])
fi
if test x"$ac_cv_header_popt_popt_h" = x"yes"; then
# If the system has /usr/include/popt/popt.h, we enable the
# included popt because an attempt to "#include <popt/popt.h>"
# would use our included header file anyway (due to -I.), and
# might conflict with the system popt.
with_included_popt=yes
elif test x"$ac_cv_header_popt_h" != x"yes"; then
with_included_popt=yes
if test x"$with_included_popt" != x"yes"
then
AC_CHECK_LIB(popt, poptGetContext, , [with_included_popt=yes])
fi
AC_MSG_CHECKING([whether to use included libpopt])
if test x"$with_included_popt" = x"yes"; then
if test x"$with_included_popt" = x"yes"
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
AC_CACHE_CHECK([for unsigned char],rsync_cv_SIGNED_CHAR_OK,[
AC_TRY_COMPILE([],[signed char *s = ""],
rsync_cv_SIGNED_CHAR_OK=yes,rsync_cv_SIGNED_CHAR_OK=no)])
if test x"$rsync_cv_SIGNED_CHAR_OK" = x"yes"; then
AC_DEFINE(SIGNED_CHAR_OK, 1, [Define to 1 if "signed char" is a valid type])
AC_CACHE_CHECK([for long long],rsync_cv_HAVE_LONGLONG,[
AC_TRY_RUN([#include <stdio.h>
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }],
rsync_cv_HAVE_LONGLONG=yes,rsync_cv_HAVE_LONGLONG=no,rsync_cv_HAVE_LONGLONG=cross)])
if test x"$rsync_cv_HAVE_LONGLONG" = x"yes"; then
AC_DEFINE(HAVE_LONGLONG, 1, [ ])
fi
AC_CACHE_CHECK([for off64_t],rsync_cv_HAVE_OFF64_T,[
AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
rsync_cv_HAVE_OFF64_T=yes,rsync_cv_HAVE_OFF64_T=no,rsync_cv_HAVE_OFF64_T=cross)])
if test x"$rsync_cv_HAVE_OFF64_T" = x"yes"; then
AC_DEFINE(HAVE_OFF64_T, 1, [ ])
fi
AC_CACHE_CHECK([for short ino_t],rsync_cv_HAVE_SHORT_INO_T,[
AC_TRY_RUN([#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
main() { if (sizeof(ino_t) < sizeof(unsigned int)) return 0; return 1; }],
rsync_cv_HAVE_SHORT_INO_T=yes,rsync_cv_HAVE_SHORT_INO_T=no,rsync_cv_HAVE_SHORT_INO_T=cross)])
if test x"$rsync_cv_HAVE_SHORT_INO_T" = x"yes"; then
AC_DEFINE(HAVE_SHORT_INO_T, 1, [ ])
fi
AC_CACHE_CHECK([for unsigned char],rsync_cv_HAVE_UNSIGNED_CHAR,[
AC_TRY_RUN([#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }],
rsync_cv_HAVE_UNSIGNED_CHAR=yes,rsync_cv_HAVE_UNSIGNED_CHAR=no,rsync_cv_HAVE_UNSIGNED_CHAR=cross)])
if test x"$rsync_cv_HAVE_UNSIGNED_CHAR" = x"yes"; then
AC_DEFINE(HAVE_UNSIGNED_CHAR, 1, [ ])
fi
AC_CACHE_CHECK([for broken readdir],rsync_cv_HAVE_BROKEN_READDIR,[
@@ -696,32 +419,33 @@ if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
di->d_name[0] == 0) exit(0); exit(1);} ],
rsync_cv_HAVE_BROKEN_READDIR=yes,rsync_cv_HAVE_BROKEN_READDIR=no,rsync_cv_HAVE_BROKEN_READDIR=cross)])
if test x"$rsync_cv_HAVE_BROKEN_READDIR" = x"yes"; then
AC_DEFINE(HAVE_BROKEN_READDIR, 1, [Define to 1 if readdir() is broken])
AC_DEFINE(HAVE_BROKEN_READDIR, 1, [ ])
fi
AC_CACHE_CHECK([for utimbuf],rsync_cv_HAVE_STRUCT_UTIMBUF,[
AC_CACHE_CHECK([for utimbuf],rsync_cv_HAVE_UTIMBUF,[
AC_TRY_COMPILE([#include <sys/types.h>
#include <utime.h>],
[struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));],
rsync_cv_HAVE_STRUCT_UTIMBUF=yes,rsync_cv_HAVE_STRUCT_UTIMBUF=no)])
if test x"$rsync_cv_HAVE_STRUCT_UTIMBUF" = x"yes"; then
AC_DEFINE(HAVE_STRUCT_UTIMBUF, 1, [Define to 1 if you have the "struct utimbuf" type])
rsync_cv_HAVE_UTIMBUF=yes,rsync_cv_HAVE_UTIMBUF=no,rsync_cv_HAVE_UTIMBUF=cross)])
if test x"$rsync_cv_HAVE_UTIMBUF" = x"yes"; then
AC_DEFINE(HAVE_UTIMBUF, 1, [ ])
fi
AC_CACHE_CHECK([if gettimeofday takes tz argument],rsync_cv_HAVE_GETTIMEOFDAY_TZ,[
AC_TRY_COMPILE([#include <sys/time.h>
#include <unistd.h>],
[struct timeval tv; exit(gettimeofday(&tv, NULL));],
rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes,rsync_cv_HAVE_GETTIMEOFDAY_TZ=no)])
if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" != x"no"; then
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ, 1, [Define to 1 if gettimeofday() takes a time-zone arg])
AC_TRY_RUN([
#include <sys/time.h>
#include <unistd.h>
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}],
rsync_cv_HAVE_GETTIMEOFDAY_TZ=yes,rsync_cv_HAVE_GETTIMEOFDAY_TZ=no,rsync_cv_HAVE_GETTIMEOFDAY_TZ=cross)])
if test x"$rsync_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ, 1, [ ])
fi
AC_CACHE_CHECK([for C99 vsnprintf],rsync_cv_HAVE_C99_VSNPRINTF,[
AC_TRY_RUN([
#include <sys/types.h>
#include <stdarg.h>
void foo(const char *format, ...) {
void foo(const char *format, ...) {
va_list ap;
int len;
char buf[5];
@@ -739,7 +463,7 @@ main() { foo("hello"); }
],
rsync_cv_HAVE_C99_VSNPRINTF=yes,rsync_cv_HAVE_C99_VSNPRINTF=no,rsync_cv_HAVE_C99_VSNPRINTF=cross)])
if test x"$rsync_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [Define to 1 if vsprintf has a C99-compatible return value])
AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [ ])
fi
@@ -748,10 +472,10 @@ AC_TRY_RUN([#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
main() {
main() {
struct stat st;
char tpl[20]="/tmp/test.XXXXXX";
int fd = mkstemp(tpl);
char tpl[20]="/tmp/test.XXXXXX";
int fd = mkstemp(tpl);
if (fd == -1) exit(1);
unlink(tpl);
if (fstat(fd, &st) != 0) exit(1);
@@ -762,46 +486,37 @@ rsync_cv_HAVE_SECURE_MKSTEMP=yes,
rsync_cv_HAVE_SECURE_MKSTEMP=no,
rsync_cv_HAVE_SECURE_MKSTEMP=cross)])
if test x"$rsync_cv_HAVE_SECURE_MKSTEMP" = x"yes"; then
case $target_os in
hpux*)
dnl HP-UX has a broken mkstemp() implementation they refuse to fix,
dnl so we noisily skip using it. See HP change request JAGaf34426
dnl for details. (sbonds)
AC_MSG_WARN(Skipping broken HP-UX mkstemp() -- using mktemp() instead)
;;
*)
AC_DEFINE(HAVE_SECURE_MKSTEMP, 1, [Define to 1 if mkstemp() is available and works right])
;;
esac
AC_DEFINE(HAVE_SECURE_MKSTEMP, 1, [ ])
fi
AC_CACHE_CHECK([if mknod creates FIFOs],rsync_cv_MKNOD_CREATES_FIFOS,[
AC_CACHE_CHECK([for broken inet_ntoa],rsync_cv_REPLACE_INET_NTOA,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
main() { int rc, ec; char *fn = "fifo-test";
unlink(fn); rc = mknod(fn,S_IFIFO,0600); ec = errno; unlink(fn);
if (rc) {printf("(%d %d) ",rc,ec); return ec;}
return 0;}],
rsync_cv_MKNOD_CREATES_FIFOS=yes,rsync_cv_MKNOD_CREATES_FIFOS=no,rsync_cv_MKNOD_CREATES_FIFOS=cross)])
if test x"$rsync_cv_MKNOD_CREATES_FIFOS" = x"yes"; then
AC_DEFINE(MKNOD_CREATES_FIFOS, 1, [Define to 1 if mknod() can create FIFOs.])
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
main() { struct in_addr ip; ip.s_addr = 0x12345678;
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(1); }
exit(0);}],
rsync_cv_REPLACE_INET_NTOA=no,rsync_cv_REPLACE_INET_NTOA=yes,rsync_cv_REPLACE_INET_NTOA=cross)])
if test x"$rsync_cv_REPLACE_INET_NTOA" = x"yes"; then
AC_DEFINE(REPLACE_INET_NTOA, 1, [ ])
fi
AC_CACHE_CHECK([if mknod creates sockets],rsync_cv_MKNOD_CREATES_SOCKETS,[
AC_CACHE_CHECK([for broken inet_aton],rsync_cv_REPLACE_INET_ATON,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/stat.h>
#include <errno.h>
main() { int rc, ec; char *fn = "sock-test";
unlink(fn); rc = mknod(fn,S_IFSOCK,0600); ec = errno; unlink(fn);
if (rc) {printf("(%d %d) ",rc,ec); return ec;}
return 0;}],
rsync_cv_MKNOD_CREATES_SOCKETS=yes,rsync_cv_MKNOD_CREATES_SOCKETS=no,rsync_cv_MKNOD_CREATES_SOCKETS=cross)])
if test x"$rsync_cv_MKNOD_CREATES_SOCKETS" = x"yes"; then
AC_DEFINE(MKNOD_CREATES_SOCKETS, 1, [Define to 1 if mknod() can create sockets.])
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
main() { struct in_addr ip;
if (inet_aton("example", &ip) == 0) exit(0); exit(1);}],
rsync_cv_REPLACE_INET_ATON=no,rsync_cv_REPLACE_INET_ATON=yes,rsync_cv_REPLACE_INET_ATON=cross)])
if test x"$rsync_cv_REPLACE_INET_ATON" = x"yes"; then
AC_DEFINE(REPLACE_INET_ATON, 1, [ ])
fi
#
@@ -834,146 +549,6 @@ AC_SUBST(OBJ_SAVE)
AC_SUBST(OBJ_RESTORE)
AC_SUBST(CC_SHOBJ_FLAG)
AC_SUBST(BUILD_POPT)
AC_SUBST(MAKE_MAN)
AC_CHECK_FUNCS(_acl __acl _facl __facl)
#################################################
# check for ACL support
AC_MSG_CHECKING([whether to support ACLs])
AC_ARG_ENABLE(acl-support,
AC_HELP_STRING([--disable-acl-support],
[disable ACL support]))
if test x"$enable_acl_support" = x"no"; then
AC_MSG_RESULT(no)
else
case "$host_os" in
*sysv5*)
AC_MSG_RESULT(Using UnixWare ACLs)
AC_DEFINE(HAVE_UNIXWARE_ACLS, 1, [true if you have UnixWare ACLs])
AC_DEFINE(SUPPORT_ACLS, 1, [Define to 1 to add support for ACLs])
;;
*solaris*|*cygwin*)
AC_MSG_RESULT(Using solaris ACLs)
AC_DEFINE(HAVE_SOLARIS_ACLS, 1, [true if you have solaris ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
;;
*hpux*)
AC_MSG_RESULT(Using HPUX ACLs)
AC_DEFINE(HAVE_HPUX_ACLS, 1, [true if you have HPUX ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
;;
*irix*)
AC_MSG_RESULT(Using IRIX ACLs)
AC_DEFINE(HAVE_IRIX_ACLS, 1, [true if you have IRIX ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
;;
*aix*)
AC_MSG_RESULT(Using AIX ACLs)
AC_DEFINE(HAVE_AIX_ACLS, 1, [true if you have AIX ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
;;
*osf*)
AC_MSG_RESULT(Using Tru64 ACLs)
AC_DEFINE(HAVE_TRU64_ACLS, 1, [true if you have Tru64 ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
LIBS="$LIBS -lpacl"
;;
darwin*)
AC_MSG_RESULT(Using OS X ACLs)
AC_DEFINE(HAVE_OSX_ACLS, 1, [true if you have Mac OS X ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
;;
*)
AC_MSG_RESULT(running tests:)
AC_CHECK_LIB(acl,acl_get_file)
AC_CACHE_CHECK([for ACL support],samba_cv_HAVE_POSIX_ACLS,[
AC_TRY_LINK([#include <sys/types.h>
#include <sys/acl.h>],
[ acl_t acl; int entry_id; acl_entry_t *entry_p; return acl_get_entry( acl, entry_id, entry_p);],
samba_cv_HAVE_POSIX_ACLS=yes,samba_cv_HAVE_POSIX_ACLS=no)])
AC_MSG_CHECKING(ACL test results)
if test x"$samba_cv_HAVE_POSIX_ACLS" = x"yes"; then
AC_MSG_RESULT(Using posix ACLs)
AC_DEFINE(HAVE_POSIX_ACLS, 1, [true if you have posix ACLs])
AC_DEFINE(SUPPORT_ACLS, 1)
AC_CACHE_CHECK([for acl_get_perm_np],samba_cv_HAVE_ACL_GET_PERM_NP,[
AC_TRY_LINK([#include <sys/types.h>
#include <sys/acl.h>],
[ acl_permset_t permset_d; acl_perm_t perm; return acl_get_perm_np( permset_d, perm);],
samba_cv_HAVE_ACL_GET_PERM_NP=yes,samba_cv_HAVE_ACL_GET_PERM_NP=no)])
if test x"$samba_cv_HAVE_ACL_GET_PERM_NP" = x"yes"; then
AC_DEFINE(HAVE_ACL_GET_PERM_NP, 1, [true if you have acl_get_perm_np])
fi
else
if test x"$enable_acl_support" = x"yes"; then
AC_MSG_ERROR(Failed to find ACL support)
else
AC_MSG_RESULT(No ACL support found)
fi
fi
;;
esac
fi
#################################################
# check for extended attribute support
AC_MSG_CHECKING(whether to support extended attributes)
AC_ARG_ENABLE(xattr-support,
AC_HELP_STRING([--disable-xattr-support],
[disable extended attributes]),
[], [case "$ac_cv_func_getxattr$ac_cv_func_extattr_get_link" in
*yes*) enable_xattr_support=maybe ;;
*) enable_xattr_support=no ;;
esac])
AH_TEMPLATE([SUPPORT_XATTRS],
[Define to 1 to add support for extended attributes])
if test x"$enable_xattr_support" = x"no"; then
AC_MSG_RESULT(no)
else
case "$host_os" in
*linux*)
AC_MSG_RESULT(Using Linux xattrs)
AC_DEFINE(HAVE_LINUX_XATTRS, 1, [True if you have Linux xattrs])
AC_DEFINE(SUPPORT_XATTRS, 1)
;;
darwin*)
AC_MSG_RESULT(Using OS X xattrs)
AC_DEFINE(HAVE_OSX_XATTRS, 1, [True if you have Mac OS X xattrs])
AC_DEFINE(SUPPORT_XATTRS, 1)
;;
freebsd*)
AC_MSG_RESULT(Using FreeBSD extattrs)
AC_DEFINE(HAVE_FREEBSD_XATTRS, 1, [True if you have FreeBSD xattrs])
AC_DEFINE(SUPPORT_XATTRS, 1)
;;
*)
if test x"$enable_xattr_support" = x"yes"; then
AC_MSG_ERROR(Failed to find extended attribute support)
else
AC_MSG_RESULT(No extended attribute support found)
fi
;;
esac
fi
if test x"$enable_acl_support" = x"no" -o x"$enable_xattr_support" = x"no" -o x"$enable_iconv" = x"no"; then
AC_MSG_CHECKING([whether $CC supports -Wno-unused-parameter])
OLD_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wno-unused-parameter"
AC_COMPILE_IFELSE([ ], [rsync_warn_flag=yes], [rsync_warn_flag=no])
AC_MSG_RESULT([$rsync_warn_flag])
if test x"$rsync_warn_flag" = x"no"; then
CFLAGS="$OLD_CFLAGS"
fi
fi
case "$CC" in
' checker'*|checker*)
AC_DEFINE(FORCE_FD_ZERO_MEMSET, 1, [Used to make "checker" understand that FD_ZERO() clears memory.])
;;
esac
AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig])
AC_OUTPUT

View File

@@ -1,46 +1,49 @@
/*
* Support the max connections option.
*
* Copyright (C) 1998 Andrew Tridgell
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1998
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.
*/
/* support the max connections option */
#include "rsync.h"
/* A simple routine to do connection counting. This returns 1 on success
* and 0 on failure, with errno also being set if the open() failed (errno
* will be 0 if the lock request failed). */
int claim_connection(char *fname, int max_connections)
/****************************************************************************
simple routine to do connection counting
****************************************************************************/
int claim_connection(char *fname,int max_connections)
{
int fd, i;
if (max_connections == 0)
if (max_connections <= 0)
return 1;
if ((fd = open(fname, O_RDWR|O_CREAT, 0600)) < 0)
return 0;
fd = open(fname,O_RDWR|O_CREAT, 0600);
/* Find a free spot. */
for (i = 0; i < max_connections; i++) {
if (lock_range(fd, i*4, 4))
return 1;
if (fd == -1) {
return 0;
}
close(fd);
/* find a free spot */
for (i=0;i<max_connections;i++) {
if (lock_range(fd, i*4, 4)) return 1;
}
/* A lock failure needs to return an errno of 0. */
/* only interested in open failures */
errno = 0;
close(fd);
return 0;
}

View File

@@ -3,22 +3,21 @@ basically a summary of clientserver.c and authenticate.c.
-- Martin Pool <mbp@samba.org>
$Id$
This is the protocol used for rsync --daemon; i.e. connections to port
873 rather than invocations over a remote shell.
When the server accepts a connection, it prints a greeting
@RSYNCD: <version>.<subprotocol>
@RSYNCD: <version>
where <version> is the numeric version (see PROTOCOL_VERSION in rsync.h)
'.' is a literal period, and <subprotocol> is the numeric subprotocol
version (see SUBPROTOCOL_VERSION -- it will be 0 for final releases).
Protocols prior to 30 only output <version> alone. The daemon expects
to see a similar greeting back from the client. For protocols prior to
30, an absent ".<subprotocol>" value is assumed to be 0. For protocol
30, an absent value is a fatal error. The daemon then follows this line
with a free-format text message-of-the-day (if any is defined).
where <version> is the numeric version; currently 24. It follows this
with a free text message-of-the-day. It expects to see a similar
greeting back from the client.
The server is now in the connected state. The client can either send
the command
@@ -76,13 +75,8 @@ stay tuned (or write it yourself!).
------------
Protocol version changes
30 (2007-10-04, 3.0.0pre1)
25 (2001-08-20, 2.4.7pre2)
The use of a ".<subprotocol>" number was added to
@RSYNCD: <version>.<subprotocol>
25 (2001-08-20, 2.4.7pre2)
Send an explicit "@RSYNC EXIT" command at the end of the
module listing. We never intentionally end the transmission
by just closing the socket anymore.
Send an explicit "@RSYNC EXIT" command at the end of the
module listing. We never intentionally end the transmission
by just closing the socket anymore.

View File

@@ -1,20 +0,0 @@
Handling the rsync SGML documentation
rsync documentation is now primarily in Docbook format. Docbook is an
SGML/XML documentation format that is becoming standard on free
operating systems. It's also used for Samba documentation.
The SGML files are source code that can be translated into various
useful output formats, primarily PDF, HTML, Postscript and plain text.
To do this transformation on Debian, you should install the
docbook-utils package. Having done that, you can say
docbook2pdf rsync.sgml
and so on.
On other systems you probably need James Clark's "sp" and "JadeTeX"
packages. Work it out for yourself and send a note to the mailing
list.

View File

@@ -1,42 +0,0 @@
Notes on rsync profiling
strlcpy is hot:
0.00 0.00 1/7735635 push_dir [68]
0.00 0.00 1/7735635 pop_dir [71]
0.00 0.00 1/7735635 send_file_list [15]
0.01 0.00 18857/7735635 send_files [4]
0.04 0.00 129260/7735635 send_file_entry [18]
0.04 0.00 129260/7735635 make_file [20]
0.04 0.00 141666/7735635 send_directory <cycle 1> [36]
2.29 0.00 7316589/7735635 f_name [13]
[14] 11.7 2.42 0.00 7735635 strlcpy [14]
Here's the top few functions:
46.23 9.57 9.57 13160929 0.00 0.00 mdfour64
14.78 12.63 3.06 13160929 0.00 0.00 copy64
11.69 15.05 2.42 7735635 0.00 0.00 strlcpy
10.05 17.13 2.08 41438 0.05 0.38 sum_update
4.11 17.98 0.85 13159996 0.00 0.00 mdfour_update
1.50 18.29 0.31 file_compare
1.45 18.59 0.30 129261 0.00 0.01 send_file_entry
1.23 18.84 0.26 2557585 0.00 0.00 f_name
1.11 19.07 0.23 1483750 0.00 0.00 u_strcmp
1.11 19.30 0.23 118129 0.00 0.00 writefd_unbuffered
0.92 19.50 0.19 1085011 0.00 0.00 writefd
0.43 19.59 0.09 156987 0.00 0.00 read_timeout
0.43 19.68 0.09 129261 0.00 0.00 clean_fname
0.39 19.75 0.08 32887 0.00 0.38 matched
0.34 19.82 0.07 1 70.00 16293.92 send_files
0.29 19.89 0.06 129260 0.00 0.00 make_file
0.29 19.95 0.06 75430 0.00 0.00 read_unbuffered
mdfour could perhaps be made faster:
/* NOTE: This code makes no attempt to be fast! */
There might be an optimized version somewhere that we can borrow.

View File

@@ -1,351 +0,0 @@
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">
<book id="rsync">
<bookinfo>
<title>rsync</title>
<copyright>
<year>1996 -- 2002</year>
<holder>Martin Pool</holder>
<holder>Andrew Tridgell</holder>
</copyright>
<author>
<firstname>Martin</firstname>
<surname>Pool</surname>
</author>
</bookinfo>
<chapter>
<title>Introduction</title>
<para>rsync is a flexible program for efficiently copying files or
directory trees.
<para>rsync has many options to select which files will be copied
and how they are to be transferred. It may be used as an
alternative to ftp, http, scp or rcp.
<para>The rsync remote-update protocol allows rsync to transfer just
the differences between two sets of files across the network link,
using an efficient checksum-search algorithm described in the
technical report that accompanies this package.</para>
<para>Some of the additional features of rsync are:</para>
<itemizedlist>
<listitem>
<para>support for copying links, devices, owners, groups and
permissions
</para>
</listitem>
<listitem>
<para>
exclude and exclude-from options similar to GNU tar
</para>
</listitem>
<listitem>
<para>
a CVS exclude mode for ignoring the same files that CVS would ignore
</listitem>
<listitem>
<para>
can use any transparent remote shell, including rsh or ssh
</listitem>
<listitem>
<para>
does not require root privileges
</listitem>
<listitem>
<para>
pipelining of file transfers to minimize latency costs
</listitem>
<listitem>
<para>
support for anonymous or authenticated rsync servers (ideal for
mirroring)
</para>
</listitem>
</itemizedlist>
</chapter>
<chapter>
<title>Using rsync</title>
<section>
<title>
Introductory example
</title>
<para>
Probably the most common case of rsync usage is to copy files
to or from a remote machine using
<application>ssh</application> as a network transport. In
this situation rsync is a good alternative to
<application>scp</application>.
</para>
<para>
The most commonly used arguments for rsync are
</para>
<variablelist>
<varlistentry>
<term><option>-v</option></term>
<listitem>
<para>Be verbose. Primarily, display the name of each file as it is copied.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-a</option></term>
<listitem>
<para>
Reproduce the structure and attributes of the origin files as exactly
as possible: this includes copying subdirectories, symlinks, special
files, ownership and permissions. (@xref{Attributes to
copy}.)
</para>
</listitem>
</varlistentry>
</variablelist>
<para><option>-v </option>
<para><option>-z</option>
Compress network traffic, using a modified version of the
@command{zlib} library.</para>
<para><option>-P</option>
Display a progress indicator while files are transferred. This should
normally be ommitted if rsync is not run on a terminal.
</para>
</section>
<section>
<title>Local and remote</title>
<para>There are six different ways of using rsync. They
are:</para>
<!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE MSGSET PROCEDURE SIDEBAR QANDASET ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS ABSTRACT AUTHORBLURB EPIGRAPH INDEXTERM REFENTRY SECTION) -->
<orderedlist>
<listitem>
<para>
for copying local files. This is invoked when neither
source nor destination path contains a @code{:} separator
<listitem>
<para>
for copying from the local machine to a remote machine using
a remote shell program as the transport (such as rsh or
ssh). This is invoked when the destination path contains a
single @code{:} separator.
<listitem>
<para>
for copying from a remote machine to the local machine
using a remote shell program. This is invoked when the source
contains a @code{:} separator.
<listitem>
<para>
for copying from a remote rsync server to the local
machine. This is invoked when the source path contains a @code{::}
separator or a @code{rsync://} URL.
<listitem>
<para>
for copying from the local machine to a remote rsync
server. This is invoked when the destination path contains a @code{::}
separator.
<listitem>
<para>
for listing files on a remote machine. This is done the
same way as rsync transfers except that you leave off the
local destination.
</listitem>
</orderedlist>
<para>
Note that in all cases (other than listing) at least one of the source
and destination paths must be local.
<para>
Any one invocation of rsync makes a copy in a single direction. rsync
currently has no equivalent of @command{ftp}'s interactive mode.
@cindex @sc{nfs}
@cindex network filesystems
@cindex remote filesystems
<para>
rsync's network protocol is generally faster at copying files than
network filesystems such as @sc{nfs} or @sc{cifs}. It is better to
run rsync on the file server either as a daemon or over ssh than
running rsync giving the network directory.
</para>
</section>
</chapter>
<chapter>
<title>Frequently asked questions</title>
<!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE MSGSET PROCEDURE SIDEBAR QANDASET ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS ABSTRACT AUTHORBLURB EPIGRAPH INDEXTERM SECTION SIMPLESECT REFENTRY SECT1) -->
<qandaset>
<!-- one of (QANDADIV QANDAENTRY) -->
<qandaentry>
<question>
<!-- one of (CALLOUTLIST GLOSSLIST ITEMIZEDLIST ORDEREDLIST
SEGMENTEDLIST SIMPLELIST VARIABLELIST CAUTION IMPORTANT NOTE
TIP WARNING LITERALLAYOUT PROGRAMLISTING PROGRAMLISTINGCO
SCREEN SCREENCO SCREENSHOT SYNOPSIS CMDSYNOPSIS FUNCSYNOPSIS
CLASSSYNOPSIS FIELDSYNOPSIS CONSTRUCTORSYNOPSIS
DESTRUCTORSYNOPSIS METHODSYNOPSIS FORMALPARA PARA SIMPARA
ADDRESS BLOCKQUOTE GRAPHIC GRAPHICCO MEDIAOBJECT
MEDIAOBJECTCO INFORMALEQUATION INFORMALEXAMPLE
INFORMALFIGURE INFORMALTABLE EQUATION EXAMPLE FIGURE TABLE
PROCEDURE ANCHOR BRIDGEHEAD REMARK HIGHLIGHTS INDEXTERM) -->
<para>Are there mailing lists for rsync?
</question>
<answer>
<para>Yes, and you can subscribe and unsubscribe through a
web interface at
<ulink
url="http://lists.samba.org/">http://lists.samba.org/</ulink>
</para>
<para>
If you are having trouble with the mailing list, please
send mail to the administrator
<email>rsync-admin@lists.samba.org</email>
not to the list itself.
</para>
<para>
The mailing list archives are searchable. Use
<ulink url="http://google.com/">Google</ulink> and prepend
the search with <userinput>site:lists.samba.org
rsync</userinput>, plus relevant keywords.
</para>
</answer>
</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>
<para>Is rsync useful for a single large file like an ISO image?</para>
</question>
<answer>
<para>
Yes, but note the following:
<para>
Background: A common use of rsync is to update a file (or set of files) in one location from a more
correct or up-to-date copy in another location, taking advantage of portions of the files that are
identical to speed up the process. (Note that rsync will transfer a file in its entirety if no copy
exists at the destination.)
<para>
(This discussion is written in terms of updating a local copy of a file from a correct file in a
remote location, although rsync can work in either direction.)
<para>
The file to be updated (the local file) must be in a destination directory that has enough space for
two copies of the file. (In addition, keep an extra copy of the file to be updated in a different
location for safety -- see the discussion (below) about rsync's behavior when the rsync process is
interrupted before completion.)
<para>
The local file must have the same name as the remote file being sync'd to (I think?). If you are
trying to upgrade an iso from, for example, beta1 to beta2, rename the local file to the same name
as the beta2 file. *(This is a useful thing to do -- only the changed portions will be
transmitted.)*
<para>
The extra copy of the local file kept in a different location is because of rsync's behavior if
interrupted before completion:
<para>
* If you specify the --partial option and rsync is interrupted, rsync will save the partially
rsync'd file and throw away the original local copy. (The partially rsync'd file is correct but
truncated.) If rsync is restarted, it will not have a local copy of the file to check for duplicate
blocks beyond the section of the file that has already been rsync'd, thus the remainder of the rsync
process will be a "pure transfer" of the file rather than taking advantage of the rsync algorithm.
<para>
* If you don't specify the --partial option and rsync is interrupted, rsync will throw away the
partially rsync'd file, and, when rsync is restarted starts the rsync process over from the
beginning.
<para>
Which of these is most desirable depends on the degree of commonality between the local and remote
copies of the file *and how much progress was made before the interruption*.
<para>
The ideal approach after an interruption would be to create a new file by taking the original file
and deleting a portion equal in size to the portion already rsync'd and then appending *the
remaining* portion to the portion of the file that has already been rsync'd. (There has been some
discussion about creating an option to do this automatically.)
The --compare-dest option is useful when transferring multiple files, but is of no benefit in
transferring a single file. (AFAIK)
*Other potentially useful information can be found at:
-[3]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFile
This answer, formatted with "real" bullets, can be found at:
-[4]http://twiki.org/cgi-bin/view/Wikilearn/RsyncingALargeFileFAQ*
</para>
</answer>
</qandaentry>
</qandaset>
</chapter>
<appendix>
<title>Other Resources</title>
<para><ulink url="http://www.ccp14.ac.uk/ccp14admin/rsync/"></ulink></para>
</appendix>
</book>

View File

@@ -1,51 +1,44 @@
/* -*- c-file-style: "linux"; -*-
Copyright (C) 1998-2000 by Andrew Tridgell
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.
*/
/*
* Error codes returned by rsync.
*
* Copyright (C) 1998-2000 Andrew Tridgell
* Copyright (C) 2003-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
* error codes returned by rsync. If you change these, please also update the
* string mappings in log.c
*/
/* If you change these, please also update the string mappings in log.c and
* the EXIT VALUES in rsync.yo. */
#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 */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_STARTCLIENT 5 /* error starting client-server protocol */
#define RERR_UNSUPPORTED 4 /* requested action not supported */
#define RERR_SOCKETIO 10 /* error in socket IO */
#define RERR_FILEIO 11 /* error in file IO */
#define RERR_STREAMIO 12 /* error in rsync protocol data stream */
#define RERR_MESSAGEIO 13 /* errors with program diagnostics */
#define RERR_IPC 14 /* error in IPC code */
#define RERR_CRASHED 15 /* sibling crashed */
#define RERR_TERMINATED 16 /* sibling terminated abnormally */
#define RERR_SIGNAL1 19 /* status returned when sent SIGUSR1 */
#define RERR_SIGNAL 20 /* status returned when sent SIGINT, SIGTERM, SIGHUP */
#define RERR_SIGNAL 20 /* status returned when sent SIGUSR1, SIGINT */
#define RERR_WAITCHILD 21 /* some error returned by waitpid() */
#define RERR_MALLOC 22 /* error allocating core memory buffers */
#define RERR_PARTIAL 23 /* partial transfer */
#define RERR_VANISHED 24 /* file(s) vanished on sender side */
#define RERR_DEL_LIMIT 25 /* skipped some deletes due to --max-delete */
#define RERR_TIMEOUT 30 /* timeout in data send/receive */
#define RERR_CONTIMEOUT 35 /* timeout waiting for daemon connection */
/* Although it doesn't seem to be specified anywhere,
* ssh and the shell seem to return these values:

1506
exclude.c
View File

File diff suppressed because it is too large Load Diff

301
fileio.c
View File

@@ -1,145 +1,87 @@
/*
* File IO utilities used in rsync.
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1998
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 utilities used in rsync
*/
#include "rsync.h"
#ifndef ENODATA
#define ENODATA EAGAIN
#endif
extern int sparse_files;
static char last_byte;
static size_t sparse_seek = 0;
static int last_sparse;
extern int sparse_files;
int sparse_end(int f)
{
int ret;
if (!sparse_seek)
return 0;
do_lseek(f, sparse_seek-1, SEEK_CUR);
sparse_seek = 0;
do {
ret = write(f, "", 1);
} while (ret < 0 && errno == EINTR);
return ret <= 0 ? -1 : 0;
if (last_sparse) {
do_lseek(f,-1,SEEK_CUR);
return (write(f,&last_byte,1) == 1 ? 0 : -1);
}
last_sparse = 0;
return 0;
}
static int write_sparse(int f, char *buf, size_t len)
static int write_sparse(int f,char *buf,size_t len)
{
size_t l1 = 0, l2 = 0;
int l1=0,l2=0;
int ret;
for (l1 = 0; l1 < len && buf[l1] == 0; l1++) {}
for (l2 = 0; l2 < len-l1 && buf[len-(l2+1)] == 0; l2++) {}
for (l1=0;l1<len && buf[l1]==0;l1++) ;
for (l2=0;l2<(len-l1) && buf[len-(l2+1)]==0;l2++) ;
/* XXX Riddle me this: why does this function SLOW DOWN when I
* remove the following (unneeded) line?? Core Duo weirdness? */
last_byte = buf[len-1];
sparse_seek += l1;
if (l1 == len || l2 > 0)
last_sparse=1;
if (l1 == len)
return len;
if (sparse_seek)
do_lseek(f, sparse_seek, SEEK_CUR);
sparse_seek = l2;
while ((ret = write(f, buf + l1, len - (l1+l2))) <= 0) {
if (ret < 0 && errno == EINTR)
continue;
return ret;
if (l1 > 0) {
do_lseek(f,l1,SEEK_CUR);
}
if (ret != (int)(len - (l1+l2)))
return l1+ret;
if (l1 == len)
return len;
if ((ret=write(f,buf+l1,len-(l1+l2))) != len-(l1+l2)) {
if (ret == -1 || ret == 0) return ret;
return (l1+ret);
}
if (l2 > 0)
do_lseek(f,l2,SEEK_CUR);
return len;
}
static char *wf_writeBuf;
static size_t wf_writeBufSize;
static size_t wf_writeBufCnt;
int flush_write_file(int f)
{
int ret = 0;
char *bp = wf_writeBuf;
while (wf_writeBufCnt > 0) {
if ((ret = write(f, bp, wf_writeBufCnt)) < 0) {
if (errno == EINTR)
continue;
return ret;
}
wf_writeBufCnt -= ret;
bp += ret;
}
return ret;
}
/*
* write_file does not allow incomplete writes. It loops internally
* until len bytes are written or errno is set.
*/
int write_file(int f,char *buf,size_t len)
{
int ret = 0;
while (len > 0) {
int r1;
if (sparse_files > 0) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
r1 = write_sparse(f, buf, len1);
} else {
if (!wf_writeBuf) {
wf_writeBufSize = WRITE_SIZE * 8;
wf_writeBufCnt = 0;
wf_writeBuf = new_array(char, wf_writeBufSize);
if (!wf_writeBuf)
out_of_memory("write_file");
}
r1 = MIN(len, wf_writeBufSize - wf_writeBufCnt);
if (r1) {
memcpy(wf_writeBuf + wf_writeBufCnt, buf, r1);
wf_writeBufCnt += r1;
}
if (wf_writeBufCnt == wf_writeBufSize) {
if (flush_write_file(f) < 0)
return -1;
if (!r1 && len)
continue;
}
}
if (!sparse_files) {
return write(f,buf,len);
}
while (len>0) {
int len1 = MIN(len, SPARSE_WRITE_SIZE);
int r1 = write_sparse(f, buf, len1);
if (r1 <= 0) {
if (ret > 0)
return ret;
if (ret > 0) return ret;
return r1;
}
len -= r1;
@@ -150,71 +92,80 @@ int write_file(int f,char *buf,size_t len)
}
/* This provides functionality somewhat similar to mmap() but using read().
* It gives sliding window access to a file. mmap() is not used because of
* the possibility of another program (such as a mailer) truncating the
* file thus giving us a SIGBUS. */
struct map_struct *map_file(int fd, OFF_T len, int32 read_size,
int32 blk_size)
/* this provides functionality somewhat similar to mmap() but using
read(). It gives sliding window access to a file. mmap() is not
used because of the possibility of another program (such as a
mailer) truncating the file thus giving us a SIGBUS */
struct map_struct *map_file(int fd,OFF_T len)
{
struct map_struct *map;
if (!(map = new0(struct map_struct)))
out_of_memory("map_file");
if (blk_size && (read_size % blk_size))
read_size += blk_size - (read_size % blk_size);
map = (struct map_struct *)malloc(sizeof(*map));
if (!map) out_of_memory("map_file");
map->fd = fd;
map->file_size = len;
map->def_window_size = read_size;
map->p = NULL;
map->p_size = 0;
map->p_offset = 0;
map->p_fd_offset = 0;
map->p_len = 0;
return map;
}
/* slide the read window in the file */
char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
char *map_ptr(struct map_struct *map,OFF_T offset,int len)
{
int32 nread;
int nread;
OFF_T window_start, read_start;
int32 window_size, read_size, read_offset;
int window_size, read_size, read_offset;
if (len == 0)
if (len == 0) {
return NULL;
if (len < 0) {
rprintf(FERROR, "invalid len passed to map_ptr: %ld\n",
(long)len);
exit_cleanup(RERR_FILEIO);
}
/* can't go beyond the end of file */
if (len > (map->file_size - offset)) {
len = map->file_size - offset;
}
/* in most cases the region will already be available */
if (offset >= map->p_offset && offset+len <= map->p_offset+map->p_len)
return map->p + (offset - map->p_offset);
if (offset >= map->p_offset &&
offset+len <= map->p_offset+map->p_len) {
return (map->p + (offset - map->p_offset));
}
/* nope, we are going to have to do a read. Work out our desired window */
window_start = offset;
window_size = map->def_window_size;
if (window_start + window_size > map->file_size)
window_size = (int32)(map->file_size - window_start);
if (len > window_size)
window_size = len;
if (offset > 2*CHUNK_SIZE) {
window_start = offset - 2*CHUNK_SIZE;
window_start &= ~((OFF_T)(CHUNK_SIZE-1)); /* assumes power of 2 */
} else {
window_start = 0;
}
window_size = MAX_MAP_SIZE;
if (window_start + window_size > map->file_size) {
window_size = map->file_size - window_start;
}
if (offset + len > window_start + window_size) {
window_size = (offset+len) - window_start;
}
/* make sure we have allocated enough memory for the window */
if (window_size > map->p_size) {
map->p = realloc_array(map->p, char, window_size);
if (!map->p)
out_of_memory("map_ptr");
map->p = (char *)Realloc(map->p, window_size);
if (!map->p) out_of_memory("map_ptr");
map->p_size = window_size;
}
/* Now try to avoid re-reading any bytes by reusing any bytes
* from the previous buffer. */
/* now try to avoid re-reading any bytes by reusing any bytes from the previous
buffer. */
if (window_start >= map->p_offset &&
window_start < map->p_offset + map->p_len &&
window_start + window_size >= map->p_offset + map->p_len) {
read_start = map->p_offset + map->p_len;
read_offset = (int32)(read_start - window_start);
read_offset = read_start - window_start;
read_size = window_size - read_offset;
memmove(map->p, map->p + (map->p_len - read_offset), read_offset);
} else {
@@ -224,53 +175,39 @@ char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
}
if (read_size <= 0) {
rprintf(FERROR, "invalid read_size of %ld in map_ptr\n",
(long)read_size);
exit_cleanup(RERR_FILEIO);
}
if (map->p_fd_offset != read_start) {
OFF_T ret = do_lseek(map->fd, read_start, SEEK_SET);
if (ret != read_start) {
rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
(double)ret, (double)read_start);
exit_cleanup(RERR_FILEIO);
rprintf(FINFO,"Warning: unexpected read size of %d in map_ptr\n", read_size);
} else {
if (map->p_fd_offset != read_start) {
if (do_lseek(map->fd,read_start,SEEK_SET) != read_start) {
rprintf(FERROR,"lseek failed in map_ptr\n");
exit_cleanup(RERR_FILEIO);
}
map->p_fd_offset = read_start;
}
map->p_fd_offset = read_start;
}
map->p_offset = window_start;
map->p_len = window_size;
while (read_size > 0) {
nread = read(map->fd, map->p + read_offset, read_size);
if (nread <= 0) {
if (!map->status)
map->status = nread ? errno : ENODATA;
/* The best we can do is zero the buffer -- the file
* has changed mid transfer! */
memset(map->p + read_offset, 0, read_size);
break;
if ((nread=read(map->fd,map->p + read_offset,read_size)) != read_size) {
if (nread < 0) nread = 0;
/* the best we can do is zero the buffer - the file
has changed mid transfer! */
memset(map->p+read_offset+nread, 0, read_size - nread);
}
map->p_fd_offset += nread;
read_offset += nread;
read_size -= nread;
}
return map->p;
map->p_offset = window_start;
map->p_len = window_size;
return map->p + (offset - map->p_offset);
}
int unmap_file(struct map_struct *map)
void unmap_file(struct map_struct *map)
{
int ret;
if (map->p) {
free(map->p);
map->p = NULL;
}
ret = map->status;
memset(map, 0, sizeof map[0]);
memset(map, 0, sizeof(*map));
free(map);
return ret;
}

3499
flist.c
View File

File diff suppressed because it is too large Load Diff

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +0,0 @@
#include "rsync.h"
int main(int argc, char *argv[])
{
STRUCT_STAT st;
int ret;
while (--argc > 0) {
#ifdef USE_STAT64_FUNCS
ret = stat64(*++argv, &st);
#else
ret = stat(*++argv, &st);
#endif
if (ret < 0) {
fprintf(stderr, "Unable to stat `%s'\n", *argv);
exit(1);
}
printf("%ld/%ld\n", (long)major(st.st_dev),
(long)minor(st.st_dev));
}
return 0;
}

View File

@@ -1,62 +0,0 @@
/*
* 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.
*
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2003-2008 Wayne Davison
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* 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, visit the http://fsf.org website.
*/
#include "rsync.h"
int
main(UNUSED(int argc), UNUSED(char *argv[]))
{
int n, i;
gid_t *list;
gid_t gid = MY_GID();
int gid_in_list = 0;
#ifdef HAVE_GETGROUPS
if ((n = getgroups(0, NULL)) < 0) {
perror("getgroups");
return 1;
}
#else
n = 0;
#endif
list = (gid_t*)malloc(sizeof (gid_t) * (n + 1));
if (!list) {
fprintf(stderr, "out of memory!\n");
exit(1);
}
#ifdef HAVE_GETGROUPS
if (n > 0)
n = getgroups(n, list);
#endif
for (i = 0; i < n; i++) {
printf("%lu ", (unsigned long)list[i]);
if (list[i] == gid)
gid_in_list = 1;
}
/* The default gid might not be in the list on some systems. */
if (!gid_in_list)
printf("%lu", (unsigned long)gid);
printf("\n");
return 0;
}

View File

@@ -1,146 +0,0 @@
/*
* Routines to provide a memory-efficient hashtable.
*
* Copyright (C) 2007-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
#include "rsync.h"
#define HASH_LOAD_LIMIT(size) ((size)*3/4)
struct hashtable *hashtable_create(int size, int key64)
{
struct hashtable *tbl;
int node_size = key64 ? sizeof (struct ht_int64_node)
: sizeof (struct ht_int32_node);
/* Pick a power of 2 that can hold the requested size. */
if (size & (size-1) || size < 16) {
int req = size;
size = 16;
while (size < req)
size *= 2;
}
if (!(tbl = new(struct hashtable))
|| !(tbl->nodes = new_array0(char, size * node_size)))
out_of_memory("hashtable_create");
tbl->size = size;
tbl->entries = 0;
tbl->node_size = node_size;
tbl->key64 = key64;
return tbl;
}
void hashtable_destroy(struct hashtable *tbl)
{
free(tbl->nodes);
free(tbl);
}
/* This returns the node for the indicated key, either newly created or
* already existing. Returns NULL if not allocating and not found. */
void *hashtable_find(struct hashtable *tbl, int64 key, int allocate_if_missing)
{
int key64 = tbl->key64;
struct ht_int32_node *node;
uint32 ndx;
if (allocate_if_missing && tbl->entries > HASH_LOAD_LIMIT(tbl->size)) {
void *old_nodes = tbl->nodes;
int size = tbl->size * 2;
int i;
if (!(tbl->nodes = new_array0(char, size * tbl->node_size)))
out_of_memory("hashtable_node");
tbl->size = size;
tbl->entries = 0;
for (i = size / 2; i-- > 0; ) {
struct ht_int32_node *move_node = HT_NODE(tbl, old_nodes, i);
int64 move_key = HT_KEY(move_node, key64);
if (move_key == 0)
continue;
node = hashtable_find(tbl, move_key, 1);
node->data = move_node->data;
}
free(old_nodes);
}
if (!key64) {
/* Based on Jenkins One-at-a-time hash. */
uchar buf[4], *keyp = buf;
int i;
SIVAL(buf, 0, key);
for (ndx = 0, i = 0; i < 4; i++) {
ndx += keyp[i];
ndx += (ndx << 10);
ndx ^= (ndx >> 6);
}
ndx += (ndx << 3);
ndx ^= (ndx >> 11);
ndx += (ndx << 15);
} else {
/* Based on Jenkins hashword() from lookup3.c. */
uint32 a, b, c;
/* Set up the internal state */
a = b = c = 0xdeadbeef + (8 << 2);
#define rot(x,k) (((x)<<(k)) ^ ((x)>>(32-(k))))
b += (uint32)(key >> 32);
a += (uint32)key;
c ^= b; c -= rot(b, 14);
a ^= c; a -= rot(c, 11);
b ^= a; b -= rot(a, 25);
c ^= b; c -= rot(b, 16);
a ^= c; a -= rot(c, 4);
b ^= a; b -= rot(a, 14);
c ^= b; c -= rot(b, 24);
#undef rot
ndx = c;
}
/* If it already exists, return the node. If we're not
* allocating, return NULL if the key is not found. */
while (1) {
int64 nkey;
ndx &= tbl->size - 1;
node = HT_NODE(tbl, tbl->nodes, ndx);
nkey = HT_KEY(node, key64);
if (nkey == key)
return node;
if (nkey == 0) {
if (!allocate_if_missing)
return NULL;
break;
}
ndx++;
}
/* Take over this empty spot and then return the node. */
if (key64)
((struct ht_int64_node*)node)->key = key;
else
node->key = key;
tbl->entries++;
return node;
}

634
hlink.c
View File

@@ -1,531 +1,179 @@
/*
* Routines to support hard-linking.
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
Copyright (C) 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"
extern int verbose;
extern int dry_run;
extern int list_only;
extern int am_sender;
extern int inc_recurse;
extern int do_xfers;
extern int link_dest;
extern int preserve_acls;
extern int make_backups;
extern int protocol_version;
extern int remove_source_files;
extern int stdout_format_has_i;
extern int maybe_ATTRS_REPORT;
extern int unsort_ndx;
extern char *basis_dir[];
extern struct file_list *cur_flist;
extern int verbose;
#ifdef SUPPORT_HARD_LINKS
/* Starting with protocol 30, we use a simple hashtable on the sending side
* for hashing the st_dev and st_ino info. The receiving side gets told
* (via flags and a "group index") which items are hard-linked together, so
* we can avoid the pool of dev+inode data. For incremental recursion mode,
* the receiver will use a ndx hash to remember old pathnames. */
static struct hashtable *dev_tbl;
static struct hashtable *prior_hlinks;
static struct file_list *hlink_flist;
void init_hard_links(void)
#if SUPPORT_HARD_LINKS
static int hlink_compare(struct file_struct *f1, struct file_struct *f2)
{
if (am_sender || protocol_version < 30)
dev_tbl = hashtable_create(16, SIZEOF_INT64 == 8);
else if (inc_recurse)
prior_hlinks = hashtable_create(1024, 0);
if (!S_ISREG(f1->mode) && !S_ISREG(f2->mode))
return 0;
if (!S_ISREG(f1->mode))
return -1;
if (!S_ISREG(f2->mode))
return 1;
if (f1->dev != f2->dev)
return (int) (f1->dev > f2->dev ? 1 : -1);
if (f1->inode != f2->inode)
return (int) (f1->inode > f2->inode ? 1 : -1);
return file_compare(&f1, &f2);
}
struct ht_int64_node *idev_find(int64 dev, int64 ino)
{
static struct ht_int64_node *dev_node = NULL;
struct hashtable *tbl;
if (!dev_node || dev_node->key != dev) {
/* We keep a separate hash table of inodes for every device. */
dev_node = hashtable_find(dev_tbl, dev, 1);
if (!(tbl = dev_node->data))
tbl = dev_node->data = hashtable_create(512, SIZEOF_INT64 == 8);
} else
tbl = dev_node->data;
return hashtable_find(tbl, ino, 1);
}
void idev_destroy(void)
static struct file_struct *hlink_list;
static int hlink_count;
#endif
void init_hard_links(struct file_list *flist)
{
#if SUPPORT_HARD_LINKS
int i;
if (flist->count < 2)
return;
for (i = 0; i < dev_tbl->size; i++) {
struct ht_int32_node *node = HT_NODE(dev_tbl, dev_tbl->nodes, i);
if (node->data)
hashtable_destroy(node->data);
}
if (hlink_list)
free(hlink_list);
hashtable_destroy(dev_tbl);
if (!(hlink_list =
(struct file_struct *) malloc(sizeof(hlink_list[0]) *
flist->count)))
out_of_memory("init_hard_links");
for (i = 0; i < flist->count; i++)
memcpy(&hlink_list[i], flist->files[i],
sizeof(hlink_list[0]));
qsort(hlink_list, flist->count,
sizeof(hlink_list[0]), (int (*)()) hlink_compare);
hlink_count = flist->count;
#endif
}
static int hlink_compare_gnum(int *int1, int *int2)
/* check if a file should be skipped because it is the same as an
earlier hard link */
int check_hard_link(struct file_struct *file)
{
struct file_struct *f1 = hlink_flist->sorted[*int1];
struct file_struct *f2 = hlink_flist->sorted[*int2];
int32 gnum1 = F_HL_GNUM(f1);
int32 gnum2 = F_HL_GNUM(f2);
#if SUPPORT_HARD_LINKS
int low = 0, high = hlink_count - 1;
int ret = 0;
if (gnum1 != gnum2)
return gnum1 > gnum2 ? 1 : -1;
return *int1 > *int2 ? 1 : -1;
}
static void match_gnums(int32 *ndx_list, int ndx_count)
{
int32 from, prev;
struct file_struct *file, *file_next;
struct ht_int32_node *node = NULL;
int32 gnum, gnum_next;
qsort(ndx_list, ndx_count, sizeof ndx_list[0],
(int (*)()) hlink_compare_gnum);
for (from = 0; from < ndx_count; from++) {
file = hlink_flist->sorted[ndx_list[from]];
gnum = F_HL_GNUM(file);
if (inc_recurse) {
node = hashtable_find(prior_hlinks, gnum, 1);
if (!node->data) {
node->data = new_array0(char, 5);
assert(gnum >= hlink_flist->ndx_start);
file->flags |= FLAG_HLINK_FIRST;
prev = -1;
} else if (CVAL(node->data, 0) == 0) {
struct file_list *flist;
prev = IVAL(node->data, 1);
flist = flist_for_ndx(prev);
if (flist)
flist->files[prev - flist->ndx_start]->flags &= ~FLAG_HLINK_LAST;
else {
/* We skipped all prior files in this
* group, so mark this as a "first". */
file->flags |= FLAG_HLINK_FIRST;
prev = -1;
}
} else
prev = -1;
} else {
file->flags |= FLAG_HLINK_FIRST;
prev = -1;
}
for ( ; from < ndx_count-1; file = file_next, gnum = gnum_next, from++) { /*SHARED ITERATOR*/
file_next = hlink_flist->sorted[ndx_list[from+1]];
gnum_next = F_HL_GNUM(file_next);
if (gnum != gnum_next)
break;
F_HL_PREV(file) = prev;
/* The linked list uses over-the-wire ndx values. */
if (unsort_ndx)
prev = F_NDX(file);
else
prev = ndx_list[from] + hlink_flist->ndx_start;
}
if (prev < 0 && !inc_recurse) {
/* Disable hard-link bit and set DONE so that
* HLINK_BUMP()-dependent values are unaffected. */
file->flags &= ~(FLAG_HLINKED | FLAG_HLINK_FIRST);
file->flags |= FLAG_HLINK_DONE;
continue;
}
file->flags |= FLAG_HLINK_LAST;
F_HL_PREV(file) = prev;
if (inc_recurse && CVAL(node->data, 0) == 0) {
if (unsort_ndx)
prev = F_NDX(file);
else
prev = ndx_list[from] + hlink_flist->ndx_start;
SIVAL(node->data, 1, prev);
}
}
}
/* Analyze the hard-links in the file-list by creating a list of all the
* items that have hlink data, sorting them, and matching up identical
* values into clusters. These will be a single linked list from last
* to first when we're done. */
void match_hard_links(struct file_list *flist)
{
if (!list_only) {
int i, ndx_count = 0;
int32 *ndx_list;
if (!(ndx_list = new_array(int32, flist->used)))
out_of_memory("match_hard_links");
for (i = 0; i < flist->used; i++) {
if (F_IS_HLINKED(flist->sorted[i]))
ndx_list[ndx_count++] = i;
}
hlink_flist = flist;
if (ndx_count)
match_gnums(ndx_list, ndx_count);
free(ndx_list);
}
if (protocol_version < 30)
idev_destroy();
}
static int maybe_hard_link(struct file_struct *file, int ndx,
const char *fname, int statret, stat_x *sxp,
const char *oldname, STRUCT_STAT *old_stp,
const char *realname, int itemizing, enum logcode code)
{
if (statret == 0) {
if (sxp->st.st_dev == old_stp->st_dev
&& sxp->st.st_ino == old_stp->st_ino) {
if (itemizing) {
itemize(fname, file, ndx, statret, sxp,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS,
0, "");
}
if (verbose > 1 && maybe_ATTRS_REPORT)
rprintf(FCLIENT, "%s is uptodate\n", fname);
file->flags |= FLAG_HLINK_DONE;
return 0;
}
if (make_backups > 0) {
if (!make_backup(fname))
return -1;
} else if (robust_unlink(fname)) {
rsyserr(FERROR_XFER, errno, "unlink %s failed",
full_fname(fname));
return -1;
}
}
if (hard_link_one(file, fname, oldname, 0)) {
if (itemizing) {
itemize(fname, file, ndx, statret, sxp,
ITEM_LOCAL_CHANGE | ITEM_XNAME_FOLLOWS, 0,
realname);
}
if (code != FNONE && verbose)
rprintf(code, "%s => %s\n", fname, realname);
if (!hlink_list || !S_ISREG(file->mode))
return 0;
}
return -1;
}
/* Figure out if a prior entry is still there or if we just have a
* cached name for it. */
static char *check_prior(struct file_struct *file, int gnum,
int *prev_ndx_p, struct file_list **flist_p)
{
struct file_struct *fp;
struct ht_int32_node *node;
int prev_ndx = F_HL_PREV(file);
while (1) {
struct file_list *flist;
if (prev_ndx < 0
|| (flist = flist_for_ndx(prev_ndx)) == NULL)
while (low != high) {
int mid = (low + high) / 2;
ret = hlink_compare(&hlink_list[mid], file);
if (ret == 0) {
low = mid;
break;
fp = flist->files[prev_ndx - flist->ndx_start];
if (!(fp->flags & FLAG_SKIP_HLINK)) {
*prev_ndx_p = prev_ndx;
*flist_p = flist;
return NULL;
}
F_HL_PREV(file) = prev_ndx = F_HL_PREV(fp);
if (ret > 0)
high = mid;
else
low = mid + 1;
}
if ((node = hashtable_find(prior_hlinks, gnum, 0)) != NULL) {
assert(node->data != NULL);
if (CVAL(node->data, 0) != 0) {
*prev_ndx_p = -1;
*flist_p = NULL;
return node->data;
}
/* The prior file must have been skipped. */
F_HL_PREV(file) = -1;
}
*prev_ndx_p = -1;
*flist_p = NULL;
return NULL;
}
/* Only called if FLAG_HLINKED is set and FLAG_HLINK_FIRST is not. Returns:
* 0 = process the file, 1 = skip the file, -1 = error occurred. */
int hard_link_check(struct file_struct *file, int ndx, const char *fname,
int statret, stat_x *sxp, int itemizing,
enum logcode code)
{
STRUCT_STAT prev_st;
char namebuf[MAXPATHLEN], altbuf[MAXPATHLEN];
char *realname, *prev_name;
struct file_list *flist;
int gnum = inc_recurse ? F_HL_GNUM(file) : -1;
int prev_ndx;
prev_name = realname = check_prior(file, gnum, &prev_ndx, &flist);
if (!prev_name) {
struct file_struct *prev_file;
if (!flist) {
/* The previous file was skipped, so this one is
* treated as if it were the first in its group. */
return 0;
}
prev_file = flist->files[prev_ndx - flist->ndx_start];
/* Is the previous link not complete yet? */
if (!(prev_file->flags & FLAG_HLINK_DONE)) {
/* Is the previous link being transferred? */
if (prev_file->flags & FLAG_FILE_SENT) {
/* Add ourselves to the list of files that will
* be updated when the transfer completes, and
* mark ourself as waiting for the transfer. */
F_HL_PREV(file) = F_HL_PREV(prev_file);
F_HL_PREV(prev_file) = ndx;
file->flags |= FLAG_FILE_SENT;
cur_flist->in_progress++;
return 1;
}
return 0;
}
/* There is a finished file to link with! */
if (!(prev_file->flags & FLAG_HLINK_FIRST)) {
/* The previous previous is FIRST when prev is not. */
prev_name = realname = check_prior(prev_file, gnum, &prev_ndx, &flist);
assert(prev_name != NULL || flist != NULL);
/* Update our previous pointer to point to the FIRST. */
F_HL_PREV(file) = prev_ndx;
}
if (!prev_name) {
int alt_dest;
prev_file = flist->files[prev_ndx - flist->ndx_start];
/* F_HL_PREV() is alt_dest value when DONE && FIRST. */
alt_dest = F_HL_PREV(prev_file);
if (alt_dest >= 0 && dry_run) {
pathjoin(namebuf, MAXPATHLEN, basis_dir[alt_dest],
f_name(prev_file, NULL));
prev_name = namebuf;
realname = f_name(prev_file, altbuf);
} else {
prev_name = f_name(prev_file, namebuf);
realname = prev_name;
}
}
}
if (link_stat(prev_name, &prev_st, 0) < 0) {
rsyserr(FERROR_XFER, errno, "stat %s failed",
full_fname(prev_name));
return -1;
}
if (statret < 0 && basis_dir[0] != NULL) {
/* If we match an alt-dest item, we don't output this as a change. */
char cmpbuf[MAXPATHLEN];
stat_x alt_sx;
int j = 0;
#ifdef SUPPORT_ACLS
alt_sx.acc_acl = alt_sx.def_acl = NULL;
#endif
do {
pathjoin(cmpbuf, MAXPATHLEN, basis_dir[j], fname);
if (link_stat(cmpbuf, &alt_sx.st, 0) < 0)
continue;
if (link_dest) {
if (prev_st.st_dev != alt_sx.st.st_dev
|| prev_st.st_ino != alt_sx.st.st_ino)
continue;
statret = 1;
if (stdout_format_has_i == 0
|| (verbose < 2 && stdout_format_has_i < 2)) {
itemizing = 0;
code = FNONE;
if (verbose > 1 && maybe_ATTRS_REPORT)
rprintf(FCLIENT, "%s is uptodate\n", fname);
}
break;
}
if (!unchanged_file(cmpbuf, file, &alt_sx.st))
continue;
statret = 1;
if (unchanged_attrs(cmpbuf, file, &alt_sx))
break;
} while (basis_dir[++j] != NULL);
if (statret == 1) {
sxp->st = alt_sx.st;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
if (!ACL_READY(*sxp))
get_acl(cmpbuf, sxp);
else {
sxp->acc_acl = alt_sx.acc_acl;
sxp->def_acl = alt_sx.def_acl;
}
}
#endif
}
#ifdef SUPPORT_ACLS
else if (preserve_acls)
free_acl(&alt_sx);
#endif
}
if (maybe_hard_link(file, ndx, fname, statret, sxp, prev_name, &prev_st,
realname, itemizing, code) < 0)
return -1;
if (remove_source_files == 1 && do_xfers)
send_msg_int(MSG_SUCCESS, ndx);
return 1;
}
int hard_link_one(struct file_struct *file, const char *fname,
const char *oldname, int terse)
{
if (do_link(oldname, fname) < 0) {
enum logcode code;
if (terse) {
if (!verbose)
return 0;
code = FINFO;
} else
code = FERROR_XFER;
rsyserr(code, errno, "link %s => %s failed",
full_fname(fname), oldname);
if (hlink_compare(&hlink_list[low], file) != 0)
return 0;
}
file->flags |= FLAG_HLINK_DONE;
if (low > 0 &&
S_ISREG(hlink_list[low - 1].mode) &&
file->dev == hlink_list[low - 1].dev &&
file->inode == hlink_list[low - 1].inode)
return 1;
#endif
return 1;
return 0;
}
void finish_hard_link(struct file_struct *file, const char *fname, int fin_ndx,
STRUCT_STAT *stp, int itemizing, enum logcode code,
int alt_dest)
{
stat_x prev_sx;
STRUCT_STAT st;
char alt_name[MAXPATHLEN], *prev_name;
const char *our_name;
struct file_list *flist;
int prev_statret, ndx, prev_ndx = F_HL_PREV(file);
if (stp == NULL && prev_ndx >= 0) {
if (link_stat(fname, &st, 0) < 0) {
rsyserr(FERROR_XFER, errno, "stat %s failed",
full_fname(fname));
#if SUPPORT_HARD_LINKS
static void hard_link_one(int i)
{
STRUCT_STAT st1, st2;
if (link_stat(f_name(&hlink_list[i - 1]), &st1) != 0)
return;
if (link_stat(f_name(&hlink_list[i]), &st2) != 0) {
if (do_link
(f_name(&hlink_list[i - 1]),
f_name(&hlink_list[i])) != 0) {
if (verbose > 0)
rprintf(FINFO, "link %s => %s : %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]),
strerror(errno));
return;
}
} else {
if (st2.st_dev == st1.st_dev && st2.st_ino == st1.st_ino)
return;
if (robust_unlink(f_name(&hlink_list[i])) != 0 ||
do_link(f_name(&hlink_list[i - 1]),
f_name(&hlink_list[i])) != 0) {
if (verbose > 0)
rprintf(FINFO, "link %s => %s : %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]),
strerror(errno));
return;
}
stp = &st;
}
/* FIRST combined with DONE means we were the first to get done. */
file->flags |= FLAG_HLINK_FIRST | FLAG_HLINK_DONE;
F_HL_PREV(file) = alt_dest;
if (alt_dest >= 0 && dry_run) {
pathjoin(alt_name, MAXPATHLEN, basis_dir[alt_dest],
f_name(file, NULL));
our_name = alt_name;
} else
our_name = fname;
#ifdef SUPPORT_ACLS
prev_sx.acc_acl = prev_sx.def_acl = NULL;
#endif
while ((ndx = prev_ndx) >= 0) {
int val;
flist = flist_for_ndx(ndx);
assert(flist != NULL);
file = flist->files[ndx - flist->ndx_start];
file->flags = (file->flags & ~FLAG_HLINK_FIRST) | FLAG_HLINK_DONE;
prev_ndx = F_HL_PREV(file);
F_HL_PREV(file) = fin_ndx;
prev_name = f_name(file, NULL);
prev_statret = link_stat(prev_name, &prev_sx.st, 0);
val = maybe_hard_link(file, ndx, prev_name, prev_statret, &prev_sx,
our_name, stp, fname, itemizing, code);
flist->in_progress--;
#ifdef SUPPORT_ACLS
if (preserve_acls)
free_acl(&prev_sx);
#endif
if (val < 0)
continue;
if (remove_source_files == 1 && do_xfers)
send_msg_int(MSG_SUCCESS, ndx);
}
if (inc_recurse) {
int gnum = F_HL_GNUM(file);
struct ht_int32_node *node = hashtable_find(prior_hlinks, gnum, 0);
assert(node != NULL && node->data != NULL);
assert(CVAL(node->data, 0) == 0);
free(node->data);
if (!(node->data = strdup(our_name)))
out_of_memory("finish_hard_link");
}
if (verbose > 0)
rprintf(FINFO, "%s => %s\n",
f_name(&hlink_list[i]),
f_name(&hlink_list[i - 1]));
}
#endif
int skip_hard_link(struct file_struct *file, struct file_list **flist_p)
/**
* Create any hard links in the global hlink_list. They were put
* there by running init_hard_links on the filelist.
**/
void do_hard_links(void)
{
struct file_list *flist;
int prev_ndx;
#if SUPPORT_HARD_LINKS
int i;
file->flags |= FLAG_SKIP_HLINK;
if (!(file->flags & FLAG_HLINK_LAST))
return -1;
if (!hlink_list)
return;
check_prior(file, F_HL_GNUM(file), &prev_ndx, &flist);
if (prev_ndx >= 0) {
file = flist->files[prev_ndx - flist->ndx_start];
if (file->flags & (FLAG_HLINK_DONE|FLAG_FILE_SENT))
return -1;
file->flags |= FLAG_HLINK_LAST;
*flist_p = flist;
for (i = 1; i < hlink_count; i++) {
if (S_ISREG(hlink_list[i].mode) &&
S_ISREG(hlink_list[i - 1].mode) &&
hlink_list[i].basename && hlink_list[i - 1].basename &&
hlink_list[i].dev == hlink_list[i - 1].dev &&
hlink_list[i].inode == hlink_list[i - 1].inode) {
hard_link_one(i);
}
}
return prev_ndx;
}
#endif
}

110
ifuncs.h
View File

@@ -1,110 +0,0 @@
/* Inline functions for rsync.
*
* Copyright (C) 2007-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
static inline void
alloc_xbuf(xbuf *xb, size_t sz)
{
if (!(xb->buf = new_array(char, sz)))
out_of_memory("alloc_xbuf");
xb->size = sz;
xb->len = xb->pos = 0;
}
static inline void
realloc_xbuf(xbuf *xb, size_t sz)
{
char *bf = realloc_array(xb->buf, char, sz);
if (!bf)
out_of_memory("realloc_xbuf");
xb->buf = bf;
xb->size = sz;
}
static inline int
to_wire_mode(mode_t mode)
{
#ifdef SUPPORT_LINKS
#if _S_IFLNK != 0120000
if (S_ISLNK(mode))
return (mode & ~(_S_IFMT)) | 0120000;
#endif
#endif
return mode;
}
static inline mode_t
from_wire_mode(int mode)
{
#if _S_IFLNK != 0120000
if ((mode & (_S_IFMT)) == 0120000)
return (mode & ~(_S_IFMT)) | _S_IFLNK;
#endif
return mode;
}
static inline char *
d_name(struct dirent *di)
{
#ifdef HAVE_BROKEN_READDIR
return (di->d_name - 2);
#else
return di->d_name;
#endif
}
static inline int
isDigit(const char *ptr)
{
return isdigit(*(unsigned char *)ptr);
}
static inline int
isPrint(const char *ptr)
{
return isprint(*(unsigned char *)ptr);
}
static inline int
isSpace(const char *ptr)
{
return isspace(*(unsigned char *)ptr);
}
static inline int
isLower(const char *ptr)
{
return islower(*(unsigned char *)ptr);
}
static inline int
isUpper(const char *ptr)
{
return isupper(*(unsigned char *)ptr);
}
static inline int
toLower(const char *ptr)
{
return tolower(*(unsigned char *)ptr);
}
static inline int
toUpper(const char *ptr)
{
return toupper(*(unsigned char *)ptr);
}

View File

@@ -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

2087
io.c
View File

File diff suppressed because it is too large Load Diff

52
io.h
View File

@@ -1,52 +0,0 @@
/*
* Copyright (C) 2007-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
extern int protocol_version;
static inline int32
read_varint30(int f)
{
if (protocol_version < 30)
return read_int(f);
return read_varint(f);
}
static inline int64
read_varlong30(int f, uchar min_bytes)
{
if (protocol_version < 30)
return read_longint(f);
return read_varlong(f, min_bytes);
}
static inline void
write_varint30(int f, int32 x)
{
if (protocol_version < 30)
write_int(f, x);
else
write_varint(f, x);
}
static inline void
write_varlong30(int f, int64 x, uchar min_bytes)
{
if (protocol_version < 30)
write_longint(f, x);
else
write_varlong(f, x, min_bytes);
}

49
lib/.cvsignore Normal file
View File

@@ -0,0 +1,49 @@
.cvsignore
Makefile
a
b
config.cache
config.h
config.log
config.status
dist.tar.gz
dummy
rsync
rsync-0.1
rsync-0.1
rsync-0.1
rsync-0.1.tar.gz
rsync-0.2
rsync-0.2
rsync-0.2.tar.gz
rsync-0.3
rsync-0.3
rsync-0.3.tar.gz
rsync-0.4
rsync-0.4
rsync-0.4.tar.gz
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5
rsync-0.5.tar.gz
rsync-0.6
rsync-0.7
rsync-0.7
rsync-0.8
rsync-0.8
rsync-0.8
rsync-0.8
rsync-ERSION
rsync.aux
rsync.dvi
rsync.log
tech_report.aux
tech_report.dvi
tech_report.log
tech_report.ps
test

View File

@@ -1,180 +0,0 @@
/*
PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this paragraph
and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS
TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*-------------------------------------------------------------------------
*
* getaddrinfo.h
* Support getaddrinfo() on platforms that don't have it.
*
* Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO,
* whether or not the library routine getaddrinfo() can be found. This
* policy is needed because on some platforms a manually installed libbind.a
* may provide getaddrinfo(), yet the system headers may not provide the
* struct definitions needed to call it. To avoid conflict with the libbind
* definition in such cases, we rename our routines to pg_xxx() via macros.
*
* This code will also work on platforms where struct addrinfo is defined
* in the system headers but no getaddrinfo() can be located.
*
* Copyright (c) 2003-2007, PostgreSQL Global Development Group
*
*-------------------------------------------------------------------------
*/
#ifndef ADDRINFO_H
#define ADDRINFO_H
/* Various macros that ought to be in <netdb.h>, but might not be */
#ifndef EAI_FAIL
#define EAI_BADFLAGS (-1)
#define EAI_NONAME (-2)
#define EAI_AGAIN (-3)
#define EAI_FAIL (-4)
#define EAI_FAMILY (-6)
#define EAI_SOCKTYPE (-7)
#define EAI_SERVICE (-8)
#define EAI_MEMORY (-10)
#define EAI_SYSTEM (-11)
#endif /* !EAI_FAIL */
#ifndef AI_PASSIVE
#define AI_PASSIVE 0x0001
#endif
#ifndef AI_NUMERICHOST
/*
* some platforms don't support AI_NUMERICHOST; define as zero if using
* the system version of getaddrinfo...
*/
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
#define AI_NUMERICHOST 0
#else
#define AI_NUMERICHOST 0x0004
#endif
#endif
#ifndef AI_CANONNAME
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
#define AI_CANONNAME 0
#else
#define AI_CANONNAME 0x0008
#endif
#endif
#ifndef AI_NUMERICSERV
#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO)
#define AI_NUMERICSERV 0
#else
#define AI_NUMERICSERV 0x0010
#endif
#endif
#ifndef NI_NUMERICHOST
#define NI_NUMERICHOST 1
#endif
#ifndef NI_NUMERICSERV
#define NI_NUMERICSERV 2
#endif
#ifndef NI_NOFQDN
#define NI_NOFQDN 4
#endif
#ifndef NI_NAMEREQD
#define NI_NAMEREQD 8
#endif
#ifndef NI_DGRAM
#define NI_DGRAM 16
#endif
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
#ifndef NI_MAXSERV
#define NI_MAXSERV 32
#endif
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo
{
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
size_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};
#endif /* !HAVE_STRUCT_ADDRINFO */
#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
struct sockaddr_storage {
unsigned short ss_family;
unsigned long ss_align;
char ss_padding[128 - sizeof (unsigned long)];
};
#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
#ifndef HAVE_GETADDRINFO
/* Rename private copies per comments above */
#ifdef getaddrinfo
#undef getaddrinfo
#endif
#define getaddrinfo pg_getaddrinfo
#ifdef freeaddrinfo
#undef freeaddrinfo
#endif
#define freeaddrinfo pg_freeaddrinfo
#ifdef gai_strerror
#undef gai_strerror
#endif
#define gai_strerror pg_gai_strerror
#ifdef getnameinfo
#undef getnameinfo
#endif
#define getnameinfo pg_getnameinfo
extern int getaddrinfo(const char *node, const char *service,
const struct addrinfo * hints, struct addrinfo ** res);
extern void freeaddrinfo(struct addrinfo * res);
extern const char *gai_strerror(int errcode);
extern int getnameinfo(const struct sockaddr * sa, socklen_t salen,
char *node, size_t nodelen,
char *service, size_t servicelen, int flags);
#endif /* !HAVE_GETADDRINFO */
#endif /* ADDRINFO_H */

View File

@@ -1,34 +1,37 @@
/*
* Reimplementations of standard functions for platforms that don't have them.
*
* Copyright (C) 1998 Andrew Tridgell
* Copyright (C) 2002 Martin Pool
* Copyright (C) 2004, 2005, 2006 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1998
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.
*/
/*
compatibility functions - replacing functions for platforms that don't
have them.
*/
#include "rsync.h"
#ifndef HAVE_STRDUP
char *strdup(char *s)
{
int len = strlen(s) + 1;
char *ret = (char *)malloc(len);
if (ret)
memcpy(ret, s, len);
return ret;
int l = strlen(s) + 1;
char *ret = (char *)malloc(l);
if (ret)
strcpy(ret,s);
return ret;
}
#endif
@@ -75,11 +78,9 @@
#endif
#ifndef HAVE_STRPBRK
/**
* Find the first ocurrence in @p s of any character in @p accept.
*
* Derived from glibc
**/
/* Find the first ocurrence in S of any character in ACCEPT.
derived from glibc
*/
char *strpbrk(const char *s, const char *accept)
{
while (*s != '\0') {
@@ -96,45 +97,36 @@
#ifndef HAVE_STRLCPY
/**
* Like strncpy but does not 0 fill the buffer and always null
* terminates.
/* Like strncpy but does not 0 fill the buffer and always null
* terminates. bufsize is the size of the destination buffer.
*
* @param bufsize is the size of the destination buffer.
*
* @return index of the terminating byte.
**/
* Returns the index of the terminating byte. */
size_t strlcpy(char *d, const char *s, size_t bufsize)
{
size_t len = strlen(s);
size_t ret = len;
if (bufsize > 0) {
if (len >= bufsize)
len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
}
if (bufsize <= 0) return 0;
if (len >= bufsize) len = bufsize-1;
memcpy(d, s, len);
d[len] = 0;
return ret;
}
#endif
#ifndef HAVE_STRLCAT
/**
* 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.
**/
/* 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 */
size_t strlcat(char *d, const char *s, size_t bufsize)
{
size_t len1 = strlen(d);
size_t len2 = strlen(s);
size_t ret = len1 + len2;
if (len1 < bufsize - 1) {
if (len2 >= bufsize - len1)
len2 = bufsize - len1 - 1;
if (len1+len2 >= bufsize) {
len2 = bufsize - (len1+1);
}
if (len2 > 0) {
memcpy(d+len1, s, len2);
d[len1+len2] = 0;
}
@@ -142,10 +134,53 @@
}
#endif
#ifdef REPLACE_INET_NTOA
char *rep_inet_ntoa(struct in_addr ip)
{
unsigned char *p = (unsigned char *)&ip.s_addr;
static char buf[18];
#if WORDS_BIGENDIAN
snprintf(buf, 18, "%d.%d.%d.%d",
(int)p[0], (int)p[1], (int)p[2], (int)p[3]);
#else
snprintf(buf, 18, "%d.%d.%d.%d",
(int)p[3], (int)p[2], (int)p[1], (int)p[0]);
#endif
return buf;
}
#endif
#ifdef REPLACE_INET_ATON
int inet_aton(const char *cp, struct in_addr *inp)
{
unsigned int a1, a2, a3, a4;
unsigned long ret;
if (strcmp(cp, "255.255.255.255") == 0) {
inp->s_addr = (unsigned) -1;
return 0;
}
if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 ||
a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) {
return 0;
}
ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;
inp->s_addr = htonl(ret);
if (inp->s_addr == (unsigned) -1) {
return 0;
}
return 1;
}
#endif
/* some systems don't take the 2nd argument */
int sys_gettimeofday(struct timeval *tv)
{
#ifdef HAVE_GETTIMEOFDAY_TZ
#if HAVE_GETTIMEOFDAY_TZ
return gettimeofday(tv, NULL);
#else
return gettimeofday(tv);

482
lib/fnmatch.c Normal file
View File

@@ -0,0 +1,482 @@
#include "../rsync.h"
#ifndef HAVE_FNMATCH
/* ----- THE FOLLOWING UP TO 'END' is glibc-2.1.2 posix/fnmatch.c
except for the parts with '#if 0' */
/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
This file is part of the GNU C Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#if 0 /* header files included better by ../rsync.h */
#if HAVE_CONFIG_H
# include <config.h>
#endif
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
#include <errno.h>
#include <fnmatch.h>
#include <ctype.h>
#if HAVE_STRING_H || defined _LIBC
# include <string.h>
#else
# include <strings.h>
#endif
#if defined STDC_HEADERS || defined _LIBC
# include <stdlib.h>
#endif
#endif /* 0 */
/* For platform which support the ISO C amendement 1 functionality we
support user defined character classes. */
#if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
# include <wchar.h>
# include <wctype.h>
#endif
/* Comment out all this code if we are using the GNU C Library, and are not
actually compiling the library itself. This code is part of the GNU C
Library, but also included in many other GNU distributions. Compiling
and linking in this code is a waste when using the GNU C library
(especially if it is a shared library). Rather than having every GNU
program understand `configure --with-gnu-libc' and omit the object files,
it is simpler to just do this in the source for each such file. */
#if 1
# if defined STDC_HEADERS || !defined isascii
# define ISASCII(c) 1
# else
# define ISASCII(c) isascii(c)
# endif
#ifdef isblank
# define ISBLANK(c) (ISASCII (c) && isblank (c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
#else
# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
#endif
#define ISPRINT(c) (ISASCII (c) && isprint (c))
#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
#define ISALNUM(c) (ISASCII (c) && isalnum (c))
#define ISALPHA(c) (ISASCII (c) && isalpha (c))
#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
#define ISLOWER(c) (ISASCII (c) && islower (c))
#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
#define ISSPACE(c) (ISASCII (c) && isspace (c))
#define ISUPPER(c) (ISASCII (c) && isupper (c))
#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
# define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
/* The GNU C library provides support for user-defined character classes
and the functions from ISO C amendement 1. */
# ifdef CHARCLASS_NAME_MAX
# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
# else
/* This shouldn't happen but some implementation might still have this
problem. Use a reasonable default value. */
# define CHAR_CLASS_MAX_LENGTH 256
# endif
# ifdef _LIBC
# define IS_CHAR_CLASS(string) __wctype (string)
# else
# define IS_CHAR_CLASS(string) wctype (string)
# endif
# else
# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
# define IS_CHAR_CLASS(string) \
(STREQ (string, "alpha") || STREQ (string, "upper") \
|| STREQ (string, "lower") || STREQ (string, "digit") \
|| STREQ (string, "alnum") || STREQ (string, "xdigit") \
|| STREQ (string, "space") || STREQ (string, "print") \
|| STREQ (string, "punct") || STREQ (string, "graph") \
|| STREQ (string, "cntrl") || STREQ (string, "blank"))
# endif
/* Avoid depending on library functions or files
whose names are inconsistent. */
# if !defined _LIBC && !defined getenv
extern char *getenv ();
# endif
# ifndef errno
extern int errno;
# endif
/* Match STRING against the filename pattern PATTERN, returning zero if
it matches, nonzero if not. */
static int
#ifdef _LIBC
internal_function
#endif
internal_fnmatch (const char *pattern, const char *string,
int no_leading_period, int flags)
{
register const char *p = pattern, *n = string;
register unsigned char c;
/* Note that this evaluates C many times. */
# ifdef _LIBC
# define FOLD(c) ((flags & FNM_CASEFOLD) ? tolower (c) : (c))
# else
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
# endif
while ((c = *p++) != '\0')
{
c = FOLD (c);
switch (c)
{
case '?':
if (*n == '\0')
return FNM_NOMATCH;
else if (*n == '/' && (flags & FNM_FILE_NAME))
return FNM_NOMATCH;
else if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
break;
case '\\':
if (!(flags & FNM_NOESCAPE))
{
c = *p++;
if (c == '\0')
/* Trailing \ loses. */
return FNM_NOMATCH;
c = FOLD (c);
}
if (FOLD ((unsigned char) *n) != c)
return FNM_NOMATCH;
break;
case '*':
if (*n == '.' && no_leading_period
&& (n == string
|| (n[-1] == '/' && (flags & FNM_FILE_NAME))))
return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
if (*n == '/' && (flags & FNM_FILE_NAME))
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return FNM_NOMATCH;
else if (c == '?')
{
/* A ? needs to match one character. */
if (*n == '\0')
/* There isn't another character; no match. */
return FNM_NOMATCH;
else
/* One character of the string is consumed in matching
this ? wildcard, so *??? won't match if there are
less than three characters. */
++n;
}
}
if (c == '\0')
/* The wildcard(s) is/are the last element of the pattern.
If the name is a file name and contains another slash
this does mean it cannot match. */
return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
? FNM_NOMATCH : 0);
else
{
const char *endp;
#if 0
endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
#else
/* replace call to internal glibc function with equivalent */
if (!(flags & FNM_FILE_NAME) || ((endp = strchr(n, '/')) == NULL))
endp = n + strlen(n);
#endif
if (c == '[')
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
for (--p; n < endp; ++n)
if (internal_fnmatch (p, n,
(no_leading_period
&& (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME)))),
flags2)
== 0)
return 0;
}
else if (c == '/' && (flags & FNM_FILE_NAME))
{
while (*n != '\0' && *n != '/')
++n;
if (*n == '/'
&& (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
flags) == 0))
return 0;
}
else
{
int flags2 = ((flags & FNM_FILE_NAME)
? flags : (flags & ~FNM_PERIOD));
if (c == '\\' && !(flags & FNM_NOESCAPE))
c = *p;
c = FOLD (c);
for (--p; n < endp; ++n)
if (FOLD ((unsigned char) *n) == c
&& (internal_fnmatch (p, n,
(no_leading_period
&& (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME)))),
flags2) == 0))
return 0;
}
}
/* If we come here no match is possible with the wildcard. */
return FNM_NOMATCH;
case '[':
{
/* Nonzero if the sense of the character class is inverted. */
static int posixly_correct;
register int not;
char cold;
if (posixly_correct == 0)
posixly_correct = getenv ("POSIXLY_CORRECT") != NULL ? 1 : -1;
if (*n == '\0')
return FNM_NOMATCH;
if (*n == '.' && no_leading_period && (n == string
|| (n[-1] == '/'
&& (flags
& FNM_FILE_NAME))))
return FNM_NOMATCH;
if (*n == '/' && (flags & FNM_FILE_NAME))
/* `/' cannot be matched. */
return FNM_NOMATCH;
not = (*p == '!' || (posixly_correct < 0 && *p == '^'));
if (not)
++p;
c = *p++;
for (;;)
{
unsigned char fn = FOLD ((unsigned char) *n);
if (!(flags & FNM_NOESCAPE) && c == '\\')
{
if (*p == '\0')
return FNM_NOMATCH;
c = FOLD ((unsigned char) *p);
++p;
if (c == fn)
goto matched;
}
else if (c == '[' && *p == ':')
{
/* Leave room for the null. */
char str[CHAR_CLASS_MAX_LENGTH + 1];
size_t c1 = 0;
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
wctype_t wt;
# endif
const char *startp = p;
for (;;)
{
if (c1 == CHAR_CLASS_MAX_LENGTH)
/* The name is too long and therefore the pattern
is ill-formed. */
return FNM_NOMATCH;
c = *++p;
if (c == ':' && p[1] == ']')
{
p += 2;
break;
}
if (c < 'a' || c >= 'z')
{
/* This cannot possibly be a character class name.
Match it as a normal range. */
p = startp;
c = '[';
goto normal_bracket;
}
str[c1++] = c;
}
str[c1] = '\0';
# if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
wt = IS_CHAR_CLASS (str);
if (wt == 0)
/* Invalid character class name. */
return FNM_NOMATCH;
if (__iswctype (__btowc ((unsigned char) *n), wt))
goto matched;
# else
if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
|| (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
|| (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
|| (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
|| (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
|| (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
|| (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
|| (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
|| (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
|| (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
|| (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
|| (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
goto matched;
# endif
}
else if (c == '\0')
/* [ (unterminated) loses. */
return FNM_NOMATCH;
else
{
normal_bracket:
if (FOLD (c) == fn)
goto matched;
cold = c;
c = *p++;
if (c == '-' && *p != ']')
{
/* It is a range. */
unsigned char cend = *p++;
if (!(flags & FNM_NOESCAPE) && cend == '\\')
cend = *p++;
if (cend == '\0')
return FNM_NOMATCH;
if (cold <= fn && fn <= FOLD (cend))
goto matched;
c = *p++;
}
}
if (c == ']')
break;
}
if (!not)
return FNM_NOMATCH;
break;
matched:
/* Skip the rest of the [...] that already matched. */
while (c != ']')
{
if (c == '\0')
/* [... (unterminated) loses. */
return FNM_NOMATCH;
c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\')
{
if (*p == '\0')
return FNM_NOMATCH;
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
else if (c == '[' && *p == ':')
{
do
if (*++p == '\0')
return FNM_NOMATCH;
while (*p != ':' || p[1] == ']');
p += 2;
c = *p;
}
}
if (not)
return FNM_NOMATCH;
}
break;
default:
if (c != FOLD ((unsigned char) *n))
return FNM_NOMATCH;
}
++n;
}
if (*n == '\0')
return 0;
if ((flags & FNM_LEADING_DIR) && *n == '/')
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
return 0;
return FNM_NOMATCH;
# undef FOLD
}
int
fnmatch (pattern, string, flags)
const char *pattern;
const char *string;
int flags;
{
return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
}
#endif /* _LIBC or not __GNU_LIBRARY__. */
/* ----- END glibc-2.1.2 posix/fnmatch.c */
#else /* HAVE_FNMATCH */
void fnmatch_dummy(void) {}
#endif

88
lib/fnmatch.h Normal file
View File

@@ -0,0 +1,88 @@
/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C Library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#ifndef _FNMATCH_H
#define _FNMATCH_H 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
# if !defined __GLIBC__ || !defined __P
# undef __P
# define __P(protos) protos
# endif
#else /* Not C++ or ANSI C. */
# undef __P
# define __P(protos) ()
/* We can get away without defining `const' here only because in this file
it is used only inside the prototype for `fnmatch', which is elided in
non-ANSI C where `const' is problematical. */
#endif /* C++ or ANSI C. */
#ifndef const
# if (defined __STDC__ && __STDC__) || defined __cplusplus
# define __const const
# else
# define __const
# endif
#endif
/* We #undef these before defining them because some losing systems
(HP-UX A.08.07 for example) define these in <unistd.h>. */
#undef FNM_PATHNAME
#undef FNM_NOESCAPE
#undef FNM_PERIOD
/* Bits set in the FLAGS argument to `fnmatch'. */
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
#ifndef FNM_FILE_NAME
# define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
#endif
#ifndef FNM_LEADING_DIR
# define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
#endif
#ifndef FNM_CASEFOLD
# define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
#endif
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
#define FNM_NOMATCH 1
/* This value is returned if the implementation does not support
`fnmatch'. Since this is not the case here it will never be
returned but the conformance test suites still require the symbol
to be defined. */
#ifdef _XOPEN_SOURCE
# define FNM_NOSYS (-1)
#endif
/* Match STRING against the filename pattern PATTERN,
returning zero if it matches, FNM_NOMATCH if not. */
extern int fnmatch __P ((__const char *__pattern, __const char *__string,
int __flags));
#ifdef __cplusplus
}
#endif
#endif /* fnmatch.h */

View File

@@ -1,508 +0,0 @@
/*
PostgreSQL Database Management System
(formerly known as Postgres, then as Postgres95)
Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group
Portions Copyright (c) 1994, The Regents of the University of California
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose, without fee, and without a written agreement
is hereby granted, provided that the above copyright notice and this paragraph
and the following two paragraphs appear in all copies.
IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS
TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*-------------------------------------------------------------------------
*
* getaddrinfo.c
* Support getaddrinfo() on platforms that don't have it.
*
* We also supply getnameinfo() here, assuming that the platform will have
* it if and only if it has getaddrinfo(). If this proves false on some
* platform, we'll need to split this file and provide a separate configure
* test for getnameinfo().
*
* Copyright (c) 2003-2007, PostgreSQL Global Development Group
*
* Copyright (C) 2007 Jeremy Allison.
* Modified to return multiple IPv4 addresses for Samba.
*
*-------------------------------------------------------------------------
*/
#include "rsync.h"
#ifndef SMB_MALLOC
#define SMB_MALLOC(s) malloc(s)
#endif
#ifndef SMB_STRDUP
#define SMB_STRDUP(s) strdup(s)
#endif
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif
static int check_hostent_err(struct hostent *hp)
{
#ifndef INET6
extern int h_errno;
#endif
if (!hp) {
switch (h_errno) {
case HOST_NOT_FOUND:
case NO_DATA:
return EAI_NONAME;
case TRY_AGAIN:
return EAI_AGAIN;
case NO_RECOVERY:
default:
return EAI_FAIL;
}
}
if (!hp->h_name || hp->h_addrtype != AF_INET) {
return EAI_FAIL;
}
return 0;
}
static char *canon_name_from_hostent(struct hostent *hp,
int *perr)
{
char *ret = NULL;
*perr = check_hostent_err(hp);
if (*perr) {
return NULL;
}
ret = SMB_STRDUP(hp->h_name);
if (!ret) {
*perr = EAI_MEMORY;
}
return ret;
}
static char *get_my_canon_name(int *perr)
{
char name[HOST_NAME_MAX+1];
if (gethostname(name, HOST_NAME_MAX) == -1) {
*perr = EAI_FAIL;
return NULL;
}
/* Ensure null termination. */
name[HOST_NAME_MAX] = '\0';
return canon_name_from_hostent(gethostbyname(name), perr);
}
static char *get_canon_name_from_addr(struct in_addr ip,
int *perr)
{
return canon_name_from_hostent(
gethostbyaddr((void *)&ip, sizeof ip, AF_INET),
perr);
}
static struct addrinfo *alloc_entry(const struct addrinfo *hints,
struct in_addr ip,
unsigned short port)
{
struct sockaddr_in *psin = NULL;
struct addrinfo *ai = SMB_MALLOC(sizeof(*ai));
if (!ai) {
return NULL;
}
memset(ai, '\0', sizeof(*ai));
psin = SMB_MALLOC(sizeof(*psin));
if (!psin) {
free(ai);
return NULL;
}
memset(psin, '\0', sizeof(*psin));
psin->sin_family = AF_INET;
psin->sin_port = htons(port);
psin->sin_addr = ip;
ai->ai_flags = 0;
ai->ai_family = AF_INET;
ai->ai_socktype = hints->ai_socktype;
ai->ai_protocol = hints->ai_protocol;
ai->ai_addrlen = sizeof(*psin);
ai->ai_addr = (struct sockaddr *) psin;
ai->ai_canonname = NULL;
ai->ai_next = NULL;
return ai;
}
/*
* get address info for a single ipv4 address.
*
* Bugs: - servname can only be a number, not text.
*/
static int getaddr_info_single_addr(const char *service,
uint32 addr,
const struct addrinfo *hints,
struct addrinfo **res)
{
struct addrinfo *ai = NULL;
struct in_addr ip;
unsigned short port = 0;
if (service) {
port = (unsigned short)atoi(service);
}
ip.s_addr = htonl(addr);
ai = alloc_entry(hints, ip, port);
if (!ai) {
return EAI_MEMORY;
}
/* If we're asked for the canonical name,
* make sure it returns correctly. */
if (!(hints->ai_flags & AI_NUMERICSERV) &&
hints->ai_flags & AI_CANONNAME) {
int err;
if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) {
ai->ai_canonname = get_my_canon_name(&err);
} else {
ai->ai_canonname =
get_canon_name_from_addr(ip,&err);
}
if (ai->ai_canonname == NULL) {
freeaddrinfo(ai);
return err;
}
}
*res = ai;
return 0;
}
/*
* get address info for multiple ipv4 addresses.
*
* Bugs: - servname can only be a number, not text.
*/
static int getaddr_info_name(const char *node,
const char *service,
const struct addrinfo *hints,
struct addrinfo **res)
{
struct addrinfo *listp = NULL, *prevp = NULL;
char **pptr = NULL;
int err;
struct hostent *hp = NULL;
unsigned short port = 0;
if (service) {
port = (unsigned short)atoi(service);
}
hp = gethostbyname(node);
err = check_hostent_err(hp);
if (err) {
return err;
}
for(pptr = hp->h_addr_list; *pptr; pptr++) {
struct in_addr ip = *(struct in_addr *)*pptr;
struct addrinfo *ai = alloc_entry(hints, ip, port);
if (!ai) {
freeaddrinfo(listp);
return EAI_MEMORY;
}
if (!listp) {
listp = ai;
prevp = ai;
ai->ai_canonname = SMB_STRDUP(hp->h_name);
if (!ai->ai_canonname) {
freeaddrinfo(listp);
return EAI_MEMORY;
}
} else {
prevp->ai_next = ai;
prevp = ai;
}
}
*res = listp;
return 0;
}
/*
* get address info for ipv4 sockets.
*
* Bugs: - servname can only be a number, not text.
*/
int getaddrinfo(const char *node,
const char *service,
const struct addrinfo * hintp,
struct addrinfo ** res)
{
struct addrinfo hints;
/* Setup the hints struct. */
if (hintp == NULL) {
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
} else {
memcpy(&hints, hintp, sizeof(hints));
}
if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) {
return EAI_FAMILY;
}
if (hints.ai_socktype == 0) {
hints.ai_socktype = SOCK_STREAM;
}
if (!node && !service) {
return EAI_NONAME;
}
if (node) {
if (node[0] == '\0') {
return getaddr_info_single_addr(service,
INADDR_ANY,
&hints,
res);
} else if (hints.ai_flags & AI_NUMERICHOST) {
struct in_addr ip;
if (!inet_aton(node, &ip)) {
return EAI_FAIL;
}
return getaddr_info_single_addr(service,
ntohl(ip.s_addr),
&hints,
res);
} else {
return getaddr_info_name(node,
service,
&hints,
res);
}
} else if (hints.ai_flags & AI_PASSIVE) {
return getaddr_info_single_addr(service,
INADDR_ANY,
&hints,
res);
}
return getaddr_info_single_addr(service,
INADDR_LOOPBACK,
&hints,
res);
}
void freeaddrinfo(struct addrinfo *res)
{
struct addrinfo *next = NULL;
for (;res; res = next) {
next = res->ai_next;
if (res->ai_canonname) {
free(res->ai_canonname);
}
if (res->ai_addr) {
free(res->ai_addr);
}
free(res);
}
}
const char *gai_strerror(int errcode)
{
#ifdef HAVE_HSTRERROR
int hcode;
switch (errcode)
{
case EAI_NONAME:
hcode = HOST_NOT_FOUND;
break;
case EAI_AGAIN:
hcode = TRY_AGAIN;
break;
case EAI_FAIL:
default:
hcode = NO_RECOVERY;
break;
}
return hstrerror(hcode);
#else /* !HAVE_HSTRERROR */
switch (errcode)
{
case EAI_NONAME:
return "Unknown host";
case EAI_AGAIN:
return "Host name lookup failure";
#ifdef EAI_BADFLAGS
case EAI_BADFLAGS:
return "Invalid argument";
#endif
#ifdef EAI_FAMILY
case EAI_FAMILY:
return "Address family not supported";
#endif
#ifdef EAI_MEMORY
case EAI_MEMORY:
return "Not enough memory";
#endif
#ifdef EAI_NODATA
case EAI_NODATA:
return "No host data of that type was found";
#endif
#ifdef EAI_SERVICE
case EAI_SERVICE:
return "Class type not found";
#endif
#ifdef EAI_SOCKTYPE
case EAI_SOCKTYPE:
return "Socket type not supported";
#endif
default:
return "Unknown server error";
}
#endif /* HAVE_HSTRERROR */
}
static int gethostnameinfo(const struct sockaddr *sa,
char *node,
size_t nodelen,
int flags)
{
int ret = -1;
char *p = NULL;
if (!(flags & NI_NUMERICHOST)) {
struct hostent *hp = gethostbyaddr(
(void *)&((struct sockaddr_in *)sa)->sin_addr,
sizeof (struct in_addr),
sa->sa_family);
ret = check_hostent_err(hp);
if (ret == 0) {
/* Name looked up successfully. */
ret = snprintf(node, nodelen, "%s", hp->h_name);
if (ret < 0 || (size_t)ret >= nodelen) {
return EAI_MEMORY;
}
if (flags & NI_NOFQDN) {
p = strchr(node,'.');
if (p) {
*p = '\0';
}
}
return 0;
}
if (flags & NI_NAMEREQD) {
/* If we require a name and didn't get one,
* automatically fail. */
return ret;
}
/* Otherwise just fall into the numeric host code... */
}
p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr);
ret = snprintf(node, nodelen, "%s", p);
if (ret < 0 || (size_t)ret >= nodelen) {
return EAI_MEMORY;
}
return 0;
}
static int getservicenameinfo(const struct sockaddr *sa,
char *service,
size_t servicelen,
int flags)
{
int ret = -1;
int port = ntohs(((struct sockaddr_in *)sa)->sin_port);
if (!(flags & NI_NUMERICSERV)) {
struct servent *se = getservbyport(
port,
(flags & NI_DGRAM) ? "udp" : "tcp");
if (se && se->s_name) {
/* Service name looked up successfully. */
ret = snprintf(service, servicelen, "%s", se->s_name);
if (ret < 0 || (size_t)ret >= servicelen) {
return EAI_MEMORY;
}
return 0;
}
/* Otherwise just fall into the numeric service code... */
}
ret = snprintf(service, servicelen, "%d", port);
if (ret < 0 || (size_t)ret >= servicelen) {
return EAI_MEMORY;
}
return 0;
}
/*
* Convert an ipv4 address to a hostname.
*
* Bugs: - No IPv6 support.
*/
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *node, size_t nodelen,
char *service, size_t servicelen, int flags)
{
/* Invalid arguments. */
if (sa == NULL || (node == NULL && service == NULL)) {
return EAI_FAIL;
}
if (sa->sa_family != AF_INET) {
return EAI_FAIL;
}
if (salen < (socklen_t)sizeof (struct sockaddr_in)) {
return EAI_FAIL;
}
/* We don't support those. */
if ((node && !(flags & NI_NUMERICHOST))
|| (service && !(flags & NI_NUMERICSERV)))
return EAI_FAIL;
if (node) {
return gethostnameinfo(sa, node, nodelen, flags);
}
if (service) {
return getservicenameinfo(sa, service, servicelen, flags);
}
return 0;
}

View File

@@ -75,14 +75,13 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size)
{
static const char *fmt = "%u.%u.%u.%u";
char tmp[sizeof "255.255.255.255"];
size_t len;
len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]);
if (len >= size) {
if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
{
errno = ENOSPC;
return (NULL);
}
memcpy(dst, tmp, len + 1);
strcpy(dst, tmp);
return (dst);
}
@@ -107,7 +106,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best, cur;
unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
int i, inc;
int i;
/*
* Preprocess:
@@ -158,14 +157,13 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
if (!inet_ntop4(src+12, tp,
sizeof tmp - (tp - tmp)))
return (NULL);
tp += strlen(tp);
break;
}
inc = snprintf(tp, 5, "%x", words[i]);
assert(inc < 5);
tp += inc;
tp += sprintf(tp, "%x", words[i]);
}
/* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) ==
@@ -180,7 +178,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
errno = ENOSPC;
return (NULL);
}
memcpy(dst, tmp, tp - tmp);
strcpy(dst, tmp);
return (dst);
}
#endif /* AF_INET6 */

View File

@@ -27,12 +27,10 @@
*/
static int inet_pton4(const char *src, unsigned char *dst);
#ifdef INET6
static int inet_pton6(const char *src, unsigned char *dst);
#endif
/* int
* inet_pton(af, src, dst)
* isc_net_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:

304
lib/md5.c
View File

@@ -1,304 +0,0 @@
/*
* RFC 1321 compliant MD5 implementation
*
* Copyright (C) 2001-2003 Christophe Devine
*
* 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 3 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, visit the http://fsf.org website.
*/
#include "rsync.h"
void md5_begin(md_context *ctx)
{
ctx->A = 0x67452301;
ctx->B = 0xEFCDAB89;
ctx->C = 0x98BADCFE;
ctx->D = 0x10325476;
ctx->totalN = ctx->totalN2 = 0;
}
static void md5_process(md_context *ctx, const uchar data[CSUM_CHUNK])
{
uint32 X[16], A, B, C, D;
A = ctx->A;
B = ctx->B;
C = ctx->C;
D = ctx->D;
X[0] = IVAL(data, 0);
X[1] = IVAL(data, 4);
X[2] = IVAL(data, 8);
X[3] = IVAL(data, 12);
X[4] = IVAL(data, 16);
X[5] = IVAL(data, 20);
X[6] = IVAL(data, 24);
X[7] = IVAL(data, 28);
X[8] = IVAL(data, 32);
X[9] = IVAL(data, 36);
X[10] = IVAL(data, 40);
X[11] = IVAL(data, 44);
X[12] = IVAL(data, 48);
X[13] = IVAL(data, 52);
X[14] = IVAL(data, 56);
X[15] = IVAL(data, 60);
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
#define P(a,b,c,d,k,s,t) a += F(b,c,d) + X[k] + t, a = S(a,s) + b
#define F(x,y,z) (z ^ (x & (y ^ z)))
P(A, B, C, D, 0, 7, 0xD76AA478);
P(D, A, B, C, 1, 12, 0xE8C7B756);
P(C, D, A, B, 2, 17, 0x242070DB);
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
P(A, B, C, D, 4, 7, 0xF57C0FAF);
P(D, A, B, C, 5, 12, 0x4787C62A);
P(C, D, A, B, 6, 17, 0xA8304613);
P(B, C, D, A, 7, 22, 0xFD469501);
P(A, B, C, D, 8, 7, 0x698098D8);
P(D, A, B, C, 9, 12, 0x8B44F7AF);
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
P(B, C, D, A, 11, 22, 0x895CD7BE);
P(A, B, C, D, 12, 7, 0x6B901122);
P(D, A, B, C, 13, 12, 0xFD987193);
P(C, D, A, B, 14, 17, 0xA679438E);
P(B, C, D, A, 15, 22, 0x49B40821);
#undef F
#define F(x,y,z) (y ^ (z & (x ^ y)))
P(A, B, C, D, 1, 5, 0xF61E2562);
P(D, A, B, C, 6, 9, 0xC040B340);
P(C, D, A, B, 11, 14, 0x265E5A51);
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
P(A, B, C, D, 5, 5, 0xD62F105D);
P(D, A, B, C, 10, 9, 0x02441453);
P(C, D, A, B, 15, 14, 0xD8A1E681);
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
P(A, B, C, D, 9, 5, 0x21E1CDE6);
P(D, A, B, C, 14, 9, 0xC33707D6);
P(C, D, A, B, 3, 14, 0xF4D50D87);
P(B, C, D, A, 8, 20, 0x455A14ED);
P(A, B, C, D, 13, 5, 0xA9E3E905);
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
P(C, D, A, B, 7, 14, 0x676F02D9);
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
#undef F
#define F(x,y,z) (x ^ y ^ z)
P(A, B, C, D, 5, 4, 0xFFFA3942);
P(D, A, B, C, 8, 11, 0x8771F681);
P(C, D, A, B, 11, 16, 0x6D9D6122);
P(B, C, D, A, 14, 23, 0xFDE5380C);
P(A, B, C, D, 1, 4, 0xA4BEEA44);
P(D, A, B, C, 4, 11, 0x4BDECFA9);
P(C, D, A, B, 7, 16, 0xF6BB4B60);
P(B, C, D, A, 10, 23, 0xBEBFBC70);
P(A, B, C, D, 13, 4, 0x289B7EC6);
P(D, A, B, C, 0, 11, 0xEAA127FA);
P(C, D, A, B, 3, 16, 0xD4EF3085);
P(B, C, D, A, 6, 23, 0x04881D05);
P(A, B, C, D, 9, 4, 0xD9D4D039);
P(D, A, B, C, 12, 11, 0xE6DB99E5);
P(C, D, A, B, 15, 16, 0x1FA27CF8);
P(B, C, D, A, 2, 23, 0xC4AC5665);
#undef F
#define F(x,y,z) (y ^ (x | ~z))
P(A, B, C, D, 0, 6, 0xF4292244);
P(D, A, B, C, 7, 10, 0x432AFF97);
P(C, D, A, B, 14, 15, 0xAB9423A7);
P(B, C, D, A, 5, 21, 0xFC93A039);
P(A, B, C, D, 12, 6, 0x655B59C3);
P(D, A, B, C, 3, 10, 0x8F0CCC92);
P(C, D, A, B, 10, 15, 0xFFEFF47D);
P(B, C, D, A, 1, 21, 0x85845DD1);
P(A, B, C, D, 8, 6, 0x6FA87E4F);
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
P(C, D, A, B, 6, 15, 0xA3014314);
P(B, C, D, A, 13, 21, 0x4E0811A1);
P(A, B, C, D, 4, 6, 0xF7537E82);
P(D, A, B, C, 11, 10, 0xBD3AF235);
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
P(B, C, D, A, 9, 21, 0xEB86D391);
#undef F
ctx->A += A;
ctx->B += B;
ctx->C += C;
ctx->D += D;
}
void md5_update(md_context *ctx, const uchar *input, uint32 length)
{
uint32 left, fill;
if (!length)
return;
left = ctx->totalN & 0x3F;
fill = CSUM_CHUNK - left;
ctx->totalN += length;
ctx->totalN &= 0xFFFFFFFF;
if (ctx->totalN < length)
ctx->totalN2++;
if (left && length >= fill) {
memcpy(ctx->buffer + left, input, fill);
md5_process(ctx, ctx->buffer);
length -= fill;
input += fill;
left = 0;
}
while (length >= CSUM_CHUNK) {
md5_process(ctx, input);
length -= CSUM_CHUNK;
input += CSUM_CHUNK;
}
if (length)
memcpy(ctx->buffer + left, input, length);
}
static uchar md5_padding[CSUM_CHUNK] = { 0x80 };
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN])
{
uint32 last, padn;
uint32 high, low;
uchar msglen[8];
high = (ctx->totalN >> 29)
| (ctx->totalN2 << 3);
low = (ctx->totalN << 3);
SIVAL(msglen, 0, low);
SIVAL(msglen, 4, high);
last = ctx->totalN & 0x3F;
padn = last < 56 ? 56 - last : 120 - last;
md5_update(ctx, md5_padding, padn);
md5_update(ctx, msglen, 8);
SIVAL(digest, 0, ctx->A);
SIVAL(digest, 4, ctx->B);
SIVAL(digest, 8, ctx->C);
SIVAL(digest, 12, ctx->D);
}
void get_md5(uchar *out, const uchar *input, int n)
{
md_context ctx;
md5_begin(&ctx);
md5_update(&ctx, input, n);
md5_result(&ctx, out);
}
#ifdef TEST_MD5
#include <stdlib.h>
#include <stdio.h>
/*
* those are the standard RFC 1321 test vectors
*/
static struct {
char *str, *md5;
} tests[] = {
{ "",
"d41d8cd98f00b204e9800998ecf8427e" },
{ "a",
"0cc175b9c0f1b6a831c399e269772661" },
{ "abc",
"900150983cd24fb0d6963f7d28e17f72" },
{ "message digest",
"f96b697d7cb7938d525a2f31aaf161d0" },
{ "abcdefghijklmnopqrstuvwxyz",
"c3fcd3d76192e4007dfb496cca67e13b" },
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"d174ab98d277d9f5a5611c2c9f419d9f" },
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"57edf4a22be3c955ac49da2e2107b67a" },
{ NULL, NULL }
};
int main(int argc, char *argv[])
{
FILE *f;
int i, j;
char output[33];
md_context ctx;
uchar buf[1000];
uchar md5sum[MD5_DIGEST_LEN];
if (argc < 2) {
printf("\nMD5 Validation Tests:\n\n");
for (i = 0; tests[i].str; i++) {
char *str = tests[i].str;
char *chk = tests[i].md5;
printf(" Test %d ", i + 1);
get_md5(md5sum, str, strlen(str));
for (j = 0; j < MD5_DIGEST_LEN; j++)
sprintf(output + j * 2, "%02x", md5sum[j]);
if (memcmp(output, chk, 32)) {
printf("failed!\n");
return 1;
}
printf("passed.\n");
}
printf("\n");
return 0;
}
while (--argc) {
if (!(f = fopen(*++argv, "rb"))) {
perror("fopen");
return 1;
}
md5_begin(&ctx);
while ((i = fread(buf, 1, sizeof buf, f)) > 0)
md5_update(&ctx, buf, i);
md5_result(&ctx, md5sum);
for (j = 0; j < MD5_DIGEST_LEN; j++)
printf("%02x", md5sum[j]);
printf(" %s\n", *argv);
}
return 0;
}
#endif

View File

@@ -1,32 +1,32 @@
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
* An implementation of MD4 designed for use in the SMB authentication protocol.
*
* Copyright (C) 1997-1998 Andrew Tridgell
* Copyright (C) 2005-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
Unix SMB/Netbios implementation.
Version 1.9.
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
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"
/* NOTE: This code makes no attempt to be fast!
*
* It assumes that a int is at least 32 bits long. */
static md_context *m;
It assumes that a int is at least 32 bits long
*/
static struct mdfour *m;
#define MASK32 (0xffffffff)
@@ -48,31 +48,32 @@ static void mdfour64(uint32 *M)
A = m->A; B = m->B; C = m->C; D = m->D;
AA = A; BB = B; CC = C; DD = D;
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7);
ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19);
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7);
ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19);
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7);
ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19);
ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7);
ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19);
ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5);
ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13);
ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5);
ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13);
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5);
ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13);
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5);
ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13);
ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9);
ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15);
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9);
ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15);
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9);
ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15);
ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9);
ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15);
A += AA; B += BB;
@@ -84,17 +85,16 @@ static void mdfour64(uint32 *M)
m->A = A; m->B = B; m->C = C; m->D = D;
}
static void copy64(uint32 *M, const uchar *in)
static void copy64(uint32 *M, unsigned char *in)
{
int i;
for (i = 0; i < MD4_DIGEST_LEN; i++) {
M[i] = (in[i*4+3] << 24) | (in[i*4+2] << 16)
| (in[i*4+1] << 8) | (in[i*4+0] << 0);
}
for (i=0;i<16;i++)
M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
(in[i*4+1]<<8) | (in[i*4+0]<<0);
}
static void copy4(uchar *out,uint32 x)
static void copy4(unsigned char *out,uint32 x)
{
out[0] = x&0xFF;
out[1] = (x>>8)&0xFF;
@@ -102,57 +102,36 @@ static void copy4(uchar *out,uint32 x)
out[3] = (x>>24)&0xFF;
}
void mdfour_begin(md_context *md)
void mdfour_begin(struct mdfour *md)
{
md->A = 0x67452301;
md->B = 0xefcdab89;
md->C = 0x98badcfe;
md->D = 0x10325476;
md->totalN = 0;
md->totalN2 = 0;
}
static void mdfour_tail(const uchar *in, uint32 length)
{
uchar buf[128];
uint32 M[16];
extern int protocol_version;
/*
* Count total number of bits, modulo 2^64
*/
m->totalN += length << 3;
if (m->totalN < (length << 3))
m->totalN2++;
m->totalN2 += length >> 29;
static void mdfour_tail(unsigned char *in, int n)
{
unsigned char buf[128];
uint32 M[16];
uint32 b;
m->totalN += n;
b = m->totalN * 8;
memset(buf, 0, 128);
if (length)
memcpy(buf, in, length);
buf[length] = 0x80;
if (n) memcpy(buf, in, n);
buf[n] = 0x80;
if (length <= 55) {
copy4(buf+56, m->totalN);
/*
* Prior to protocol version 27 only the number of bits
* modulo 2^32 was included. MD4 requires the number
* of bits modulo 2^64, which was fixed starting with
* protocol version 27.
*/
if (protocol_version >= 27)
copy4(buf+60, m->totalN2);
if (n <= 55) {
copy4(buf+56, b);
copy64(M, buf);
mdfour64(M);
} else {
copy4(buf+120, m->totalN);
/*
* Prior to protocol version 27 only the number of bits
* modulo 2^32 was included. MD4 requires the number
* of bits modulo 2^64, which was fixed starting with
* protocol version 27.
*/
if (protocol_version >= 27)
copy4(buf+124, m->totalN2);
copy4(buf+120, b);
copy64(M, buf);
mdfour64(M);
copy64(M, buf+64);
@@ -160,55 +139,51 @@ static void mdfour_tail(const uchar *in, uint32 length)
}
}
void mdfour_update(md_context *md, const uchar *in, uint32 length)
void mdfour_update(struct mdfour *md, unsigned char *in, int n)
{
uint32 M[16];
if (n == 0) mdfour_tail(in, n);
m = md;
if (length == 0)
mdfour_tail(in, length);
while (length >= 64) {
while (n >= 64) {
copy64(M, in);
mdfour64(M);
in += 64;
length -= 64;
m->totalN += 64 << 3;
if (m->totalN < 64 << 3)
m->totalN2++;
n -= 64;
m->totalN += 64;
}
if (length)
mdfour_tail(in, length);
if (n) mdfour_tail(in, n);
}
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN])
void mdfour_result(struct mdfour *md, unsigned char *out)
{
m = md;
copy4(digest, m->A);
copy4(digest+4, m->B);
copy4(digest+8, m->C);
copy4(digest+12, m->D);
copy4(out, m->A);
copy4(out+4, m->B);
copy4(out+8, m->C);
copy4(out+12, m->D);
}
void mdfour(uchar digest[MD4_DIGEST_LEN], uchar *in, int length)
void mdfour(unsigned char *out, unsigned char *in, int n)
{
md_context md;
struct mdfour md;
mdfour_begin(&md);
mdfour_update(&md, in, length);
mdfour_result(&md, digest);
mdfour_update(&md, in, n);
mdfour_result(&md, out);
}
#ifdef TEST_MDFOUR
int protocol_version = 28;
static void file_checksum1(char *fname)
{
int fd, i, was_multiple_of_64 = 1;
md_context md;
uchar buf[64*1024], sum[MD4_DIGEST_LEN];
int fd, i;
struct mdfour md;
unsigned char buf[64*1024], sum[16];
fd = open(fname,O_RDONLY);
if (fd == -1) {
@@ -219,28 +194,63 @@ static void file_checksum1(char *fname)
mdfour_begin(&md);
while (1) {
int n = read(fd, buf, sizeof buf);
if (n <= 0)
break;
was_multiple_of_64 = !(n % 64);
int n = read(fd, buf, sizeof(buf));
if (n <= 0) break;
mdfour_update(&md, buf, n);
}
if (was_multiple_of_64 && protocol_version >= 27)
mdfour_update(&md, buf, 0);
close(fd);
mdfour_result(&md, sum);
for (i = 0; i < MD4_DIGEST_LEN; i++)
for (i=0;i<16;i++)
printf("%02X", sum[i]);
printf("\n");
}
#if 0
#include "../md4.h"
static void file_checksum2(char *fname)
{
int fd, i;
MDstruct md;
unsigned char buf[64], sum[16];
fd = open(fname,O_RDONLY);
if (fd == -1) {
perror("fname");
exit(1);
}
MDbegin(&md);
while (1) {
int n = read(fd, buf, sizeof(buf));
if (n <= 0) break;
MDupdate(&md, buf, n*8);
}
if (!md.done) {
MDupdate(&md, buf, 0);
}
close(fd);
memcpy(sum, md.buffer, 16);
for (i=0;i<16;i++)
printf("%02X", sum[i]);
printf("\n");
}
#endif
int main(int argc, char *argv[])
{
while (--argc)
file_checksum1(*++argv);
file_checksum1(argv[1]);
#if 0
file_checksum2(argv[1]);
#endif
return 0;
}
#endif

34
lib/mdfour.h Normal file
View File

@@ -0,0 +1,34 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
a implementation of MD4 designed for use in the SMB authentication protocol
Copyright (C) Andrew Tridgell 1997-1998.
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.
*/
struct mdfour {
uint32 A, B, C, D;
uint32 totalN;
};
void mdfour_begin(struct mdfour *md);
void mdfour_update(struct mdfour *md, unsigned char *in, int n);
void mdfour_result(struct mdfour *md, unsigned char *out);
void mdfour(unsigned char *out, unsigned char *in, int n);

View File

@@ -1,26 +0,0 @@
/* The include file for both the MD4 and MD5 routines. */
#define MD4_DIGEST_LEN 16
#define MD5_DIGEST_LEN 16
#define MAX_DIGEST_LEN MD5_DIGEST_LEN
#define CSUM_CHUNK 64
typedef struct {
uint32 A, B, C, D;
uint32 totalN; /* bit count, lower 32 bits */
uint32 totalN2; /* bit count, upper 32 bits */
uchar buffer[CSUM_CHUNK];
} md_context;
void mdfour_begin(md_context *md);
void mdfour_update(md_context *md, const uchar *in, uint32 length);
void mdfour_result(md_context *md, uchar digest[MD4_DIGEST_LEN]);
void get_mdfour(uchar digest[MD4_DIGEST_LEN], const uchar *in, int length);
void md5_begin(md_context *ctx);
void md5_update(md_context *ctx, const uchar *input, uint32 length);
void md5_result(md_context *ctx, uchar digest[MD5_DIGEST_LEN]);
void get_md5(uchar digest[MD5_DIGEST_LEN], const uchar *input, int n);

View File

@@ -1,39 +1,41 @@
/*
* A single utility routine.
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001 Martin Pool <mbp@samba.org>
* Copyright (C) 2003, 2006 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1996
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.
*/
#include "rsync.h"
/* Produce a string representation of Unix mode bits like that used by ls(1).
* The "buf" buffer must be at least 11 characters. */
void permstring(char *perms, mode_t mode)
/**
* Produce a string representation of Unix mode bits like that used by
* ls(1).
*
* @param buf buffer of at least 11 characters
**/
void permstring(char *perms,
int mode)
{
static const char *perm_map = "rwxrwxrwx";
int i;
strlcpy(perms, "----------", 11);
for (i = 0; i < 9; i++) {
if (mode & (1 << i))
perms[9-i] = perm_map[8-i];
strcpy(perms, "----------");
for (i=0;i<9;i++) {
if (mode & (1<<i)) perms[9-i] = perm_map[8-i];
}
/* Handle setuid/sticky bits. You might think the indices are
@@ -44,22 +46,16 @@ void permstring(char *perms, mode_t mode)
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_ISDIR(mode))
perms[0] = 'd';
else if (S_ISLNK(mode))
perms[0] = 'l';
else if (S_ISBLK(mode))
perms[0] = 'b';
else if (S_ISCHR(mode))
perms[0] = 'c';
else if (S_ISSOCK(mode))
perms[0] = 's';
else if (S_ISFIFO(mode))
perms[0] = 'p';
if (S_ISLNK(mode)) perms[0] = 'l';
if (S_ISDIR(mode)) perms[0] = 'd';
if (S_ISBLK(mode)) perms[0] = 'b';
if (S_ISCHR(mode)) perms[0] = 'c';
if (S_ISSOCK(mode)) perms[0] = 's';
if (S_ISFIFO(mode)) perms[0] = 'p';
}

View File

@@ -1,3 +1,3 @@
#define PERMSTRING_SIZE 11
void permstring(char *perms, mode_t mode);
void permstring(char *perms, int mode);

View File

@@ -1,254 +0,0 @@
.ds d \-\^\-
.ds o \fR[\fP
.ds c \fR]\fP
.ds | \fR|\fP
.de D
\\.B \*d\\$1
..
.de DI
\\.BI \*d\\$1 \\$2
..
.de DR
\\.BR \*d\\$1 \\$2
..
.de Di
\\.BI \*d\\$1 " \\$2"
..
.de Db
\\.B \*d\\$1 " \\$2"
..
.de Df
\\.B \*d\*ono\*c\\$1
..
.de See
See \fB\\$1\fP for details.
..
.de SeeIn
See \fB\\$1\fP in \fB\\$2\fP for details.
..
.TH POOL_ALLOC 3
.SH NAME
pool_alloc, pool_free, pool_free_old, pool_talloc, pool_tfree, pool_create, pool_destroy, pool_boundary
\- Allocate and free memory in managed allocation pools.
.SH SYNOPSIS
.B #include "pool_alloc.h"
\fBstruct alloc_pool *pool_create(size_t \fIsize\fB, size_t \fIquantum\fB, void (*\fIbomb\fB)(char *), int \fIflags\fB);
\fBvoid pool_destroy(struct alloc_pool *\fIpool\fB);
\fBvoid *pool_alloc(struct alloc_pool *\fIpool\fB, size_t \fIsize\fB, char *\fImsg\fB);
\fBvoid pool_free(struct alloc_pool *\fIpool\fB, size_t \fIsize\fB, void *\fIaddr\fB);
\fBvoid pool_free_old(struct alloc_pool *\fIpool\fB, void *\fIaddr\fB);
\fBvoid *pool_talloc(struct alloc_pool *\fIpool\fB, \fItype\fB), int \fIcount\fB, char *\fImsg\fB);
\fBvoid pool_tfree(struct alloc_pool *\fIpool\fB, \fItype\fB, int \fIcount\fB, void *\fIaddr\fB);
\fBvoid pool_boundary(struct alloc_pool *\fIpool\fB, sise_t \fIsize\fB);
.SH DESCRIPTION
.P
The pool allocation routines use
.B malloc()
for underlying memory management.
What allocation pools do is cause memory within a given pool
to be allocated in large contiguous blocks
(called extents) that will be reusable when freed. Unlike
.BR malloc() ,
the allocations are not managed individually.
Instead, each extent tracks the total free memory within the
extent. Each extent can either be used to allocate memory
or to manage the freeing of memory within that extent.
When an extent has less free memory than a given
allocation request, the current extent ceases to be used
for allocation. See also the
.B pool_boundary()
function.
.P
This form of memory management is suited to large numbers of small
related allocations that are held for a while
and then freed as a group.
Because the
underlying allocations are done in large contiguous extents,
when an extent is freed, it can release a large enough
contiguous block of memory to allow the memory to be returned
to the OS for use by whatever program needs it.
You can allocate from one or more memory pools and/or
.B malloc()
all at the same time without interfering with how pools work.
.P
.B pool_create()
Creates an allocation pool for subsequent calls to the pool
allocation functions.
When an extent is created for allocations it will be
.I size
bytes.
Allocations from the pool have their sizes rounded up to a
multiple of
.I quantum
bytes in length.
Specifying
.B 0
for
.I quantum
will produce a quantum that should meet maximal alignment
on most platforms.
If
.B POOL_QALIGN
is set in the
.IR flags ,
allocations will be aligned to addresses that are a
multiple of
.IR quantum .
If
.B POOL_CLEAR
is set in the
.IR flags ,
all allocations from the pool will be initialized to zeros.
You may specify a
.B NULL
for the
.I bomb
function pointer if you don't wish to use it. (See the
.B pool_alloc()
function for how it is used.)
.P
.B pool_destroy()
destroys an allocation
.I pool
and frees all its associated memory.
.P
.B pool_alloc()
allocates
.I size
bytes from the specified
.IR pool .
If
.I size
is
.BR 0 ,
.I quantum
bytes will be allocated.
If the pool has been created with
.BR POOL_QALIGN ,
every chunk of memory that is returned will be suitably aligned.
You can use this with the default
.I quantum
size to ensure that all memory can store a variable of any type.
If the requested memory cannot be allocated, the
.I bomb()
function will be called with
.I msg
as its sole argument (if the function was defined at the time
the pool was created), and then a
.B NULL
address is returned (assuming that the bomb function didn't exit).
.P
.B pool_free()
frees
.I size
bytes pointed to by an
.I addr
that was previously allocated in the specified
.IR pool .
If
.I size
is
.BR 0 ,
.I quantum
bytes will be freed.
The memory freed within an extent will not be reusable until
all of the memory in that extent has been freed with one
exception: the most recent pool allocation may be freed back
into the pool prior to making any further allocations.
If enough free calls are made to indicate that an extent has no
remaining allocated objects (as computed by the total freed size for
an extent), its memory will be completely freed back to the system.
If
.I addr
is
.BR 0 ,
no memory will be freed, but subsequent allocations will come
from a new extent.
.P
.B pool_free_old()
takes a boundary
.I addr
value that was returned by
.B pool_boundary()
and frees up any extents in the
.I pool
that have data allocated from that point backward in time.
NOTE: you must NOT mix calls to both
.B pool_free
and
.B pool_free_old
on the same pool!
.P
.B pool_boundary()
asks for a boundary value that can be sent to
.B pool_free_old()
at a later time to free up all memory allocated prior to a particular
moment in time.
If the extent that holds the boundary point has allocations from after the
boundary point, it will not be freed until a future
.B pool_free_old()
call encompasses the entirety of the extent's data.
If
.I len
is non-zero, the call will also check if the active extent has at least
that much free memory available in it, and if not, it will mark the
extent as inactive, forcing a new extent to be used for future allocations.
(You can specify -1 for
.I len
if you want to force a new extent to start.)
.P
.B pool_talloc()
is a macro that takes a
.I type
and a
.I count
instead of a
.IR size .
It casts the return value to the correct pointer type.
.P
.B pool_tfree
is a macro that calls
.B pool_free
on memory that was allocated by
.BR pool_talloc() .
.SH RETURN VALUE
.B pool_create()
returns a pointer to
.BR "struct alloc_pool" .
.P
.B pool_alloc()
and
.B pool_talloc()
return pointers to the allocated memory,
or NULL if the request fails.
The return type of
.B pool_alloc()
will normally require casting to the desired type but
.B pool_talloc()
will returns a pointer of the requested
.IR type .
.P
.B pool_boundary()
returns a pointer that should only be used in a call to
.BR pool_free_old() .
.P
.BR pool_free() ,
.BR pool_free_old() ,
.B pool_tfree()
and
.B pool_destroy()
return no value.
.SH SEE ALSO
.nf
malloc(3)
.SH AUTHOR
pool_alloc was created by J.W. Schultz of Pegasystems Technologies.
.SH BUGS AND ISSUES

View File

@@ -1,336 +0,0 @@
#include "rsync.h"
#define POOL_DEF_EXTENT (32 * 1024)
struct alloc_pool
{
size_t size; /* extent size */
size_t quantum; /* allocation quantum */
struct pool_extent *extents; /* top extent is "live" */
void (*bomb)(); /* function to call if
* malloc fails */
int flags;
/* statistical data */
unsigned long e_created; /* extents created */
unsigned long e_freed; /* extents detroyed */
int64 n_allocated; /* calls to alloc */
int64 n_freed; /* calls to free */
int64 b_allocated; /* cum. bytes allocated */
int64 b_freed; /* cum. bytes freed */
};
struct pool_extent
{
void *start; /* starting address */
size_t free; /* free bytecount */
size_t bound; /* bytes bound by padding,
* overhead and freed */
struct pool_extent *next;
};
struct align_test {
void *foo;
int64 bar;
};
#define MINALIGN offsetof(struct align_test, bar)
/* Temporarily cast a void* var into a char* var when adding an offset (to
* keep some compilers from complaining about the pointer arithmetic). */
#define PTR_ADD(b,o) ( (void*) ((char*)(b) + (o)) )
alloc_pool_t
pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags)
{
struct alloc_pool *pool;
if (!(pool = new(struct alloc_pool)))
return pool;
memset(pool, 0, sizeof (struct alloc_pool));
pool->size = size /* round extent size to min alignment reqs */
? (size + MINALIGN - 1) & ~(MINALIGN - 1)
: POOL_DEF_EXTENT;
if (flags & POOL_INTERN) {
pool->size -= sizeof (struct pool_extent);
flags |= POOL_APPEND;
}
pool->quantum = quantum ? quantum : MINALIGN;
pool->bomb = bomb;
pool->flags = flags;
return pool;
}
void
pool_destroy(alloc_pool_t p)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur, *next;
if (!pool)
return;
for (cur = pool->extents; cur; cur = next) {
next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
}
free(pool);
}
void *
pool_alloc(alloc_pool_t p, size_t len, const char *bomb_msg)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
if (!pool)
return NULL;
if (!len)
len = pool->quantum;
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
if (len > pool->size)
goto bomb_out;
if (!pool->extents || len > pool->extents->free) {
void *start;
size_t free;
size_t bound;
size_t skew;
size_t asize;
struct pool_extent *ext;
free = pool->size;
bound = 0;
asize = pool->size;
if (pool->flags & POOL_APPEND)
asize += sizeof (struct pool_extent);
if (!(start = new_array(char, asize)))
goto bomb_out;
if (pool->flags & POOL_CLEAR)
memset(start, 0, free);
if (pool->flags & POOL_APPEND)
ext = PTR_ADD(start, free);
else if (!(ext = new(struct pool_extent)))
goto bomb_out;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (skew = (size_t)PTR_ADD(start, free) % pool->quantum)) {
bound += skew;
free -= skew;
}
ext->start = start;
ext->free = free;
ext->bound = bound;
ext->next = pool->extents;
pool->extents = ext;
pool->e_created++;
}
pool->n_allocated++;
pool->b_allocated += len;
pool->extents->free -= len;
return PTR_ADD(pool->extents->start, pool->extents->free);
bomb_out:
if (pool->bomb)
(*pool->bomb)(bomb_msg);
return NULL;
}
/* This function allows you to declare memory in the pool that you are done
* using. If you free all the memory in a pool's extent, that extent will
* be freed. */
void
pool_free(alloc_pool_t p, size_t len, void *addr)
{
struct alloc_pool *pool = (struct alloc_pool *)p;
struct pool_extent *cur, *prev;
if (!pool)
return;
if (!len)
len = pool->quantum;
else if (pool->quantum > 1 && len % pool->quantum)
len += pool->quantum - len % pool->quantum;
pool->n_freed++;
pool->b_freed += len;
for (prev = NULL, cur = pool->extents; cur; prev = cur, cur = cur->next) {
if (addr >= cur->start
&& addr < PTR_ADD(cur->start, pool->size))
break;
}
if (!cur)
return;
if (!prev) {
/* The "live" extent is kept ready for more allocations. */
if (cur->free + cur->bound + len >= pool->size) {
size_t skew;
if (pool->flags & POOL_CLEAR) {
memset(PTR_ADD(cur->start, cur->free), 0,
pool->size - cur->free);
}
cur->free = pool->size;
cur->bound = 0;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (skew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
cur->bound += skew;
cur->free -= skew;
}
} else if (addr == PTR_ADD(cur->start, cur->free)) {
if (pool->flags & POOL_CLEAR)
memset(addr, 0, len);
cur->free += len;
} else
cur->bound += len;
} else {
cur->bound += len;
if (cur->free + cur->bound >= pool->size) {
prev->next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
pool->e_freed++;
} else if (prev != pool->extents) {
/* Move the extent to be the first non-live extent. */
prev->next = cur->next;
cur->next = pool->extents->next;
pool->extents->next = cur;
}
}
}
/* This allows you to declare that the given address marks the edge of some
* pool memory that is no longer needed. Any extents that hold only data
* older than the boundary address are freed. NOTE: You MUST NOT USE BOTH
* pool_free() and pool_free_old() on the same pool!! */
void
pool_free_old(alloc_pool_t p, void *addr)
{
struct alloc_pool *pool = (struct alloc_pool *)p;
struct pool_extent *cur, *prev, *next;
if (!pool || !addr)
return;
for (prev = NULL, cur = pool->extents; cur; prev = cur, cur = cur->next) {
if (addr >= cur->start
&& addr < PTR_ADD(cur->start, pool->size))
break;
}
if (!cur)
return;
if (addr == PTR_ADD(cur->start, cur->free)) {
if (prev) {
prev->next = NULL;
next = cur;
} else {
size_t skew;
/* The most recent live extent can just be reset. */
if (pool->flags & POOL_CLEAR)
memset(addr, 0, pool->size - cur->free);
cur->free = pool->size;
cur->bound = 0;
if (pool->flags & POOL_QALIGN && pool->quantum > 1
&& (skew = (size_t)PTR_ADD(cur->start, cur->free) % pool->quantum)) {
cur->bound += skew;
cur->free -= skew;
}
next = cur->next;
cur->next = NULL;
}
} else {
next = cur->next;
cur->next = NULL;
}
while ((cur = next) != NULL) {
next = cur->next;
free(cur->start);
if (!(pool->flags & POOL_APPEND))
free(cur);
pool->e_freed++;
}
}
/* If the current extent doesn't have "len" free space in it, mark it as full
* so that the next alloc will start a new extent. If len is (size_t)-1, this
* bump will always occur. The function returns a boundary address that can
* be used with pool_free_old(), or a NULL if no memory is allocated. */
void *
pool_boundary(alloc_pool_t p, size_t len)
{
struct alloc_pool *pool = (struct alloc_pool *)p;
struct pool_extent *cur;
if (!pool || !pool->extents)
return NULL;
cur = pool->extents;
if (cur->free < len) {
cur->bound += cur->free;
cur->free = 0;
}
return PTR_ADD(cur->start, cur->free);
}
#define FDPRINT(label, value) \
snprintf(buf, sizeof buf, label, value), \
write(fd, buf, strlen(buf))
#define FDEXTSTAT(ext) \
snprintf(buf, sizeof buf, " %12ld %5ld\n", \
(long) ext->free, \
(long) ext->bound), \
write(fd, buf, strlen(buf))
void
pool_stats(alloc_pool_t p, int fd, int summarize)
{
struct alloc_pool *pool = (struct alloc_pool *) p;
struct pool_extent *cur;
char buf[BUFSIZ];
if (!pool)
return;
FDPRINT(" Extent size: %12ld\n", (long) pool->size);
FDPRINT(" Alloc quantum: %12ld\n", (long) pool->quantum);
FDPRINT(" Extents created: %12ld\n", pool->e_created);
FDPRINT(" Extents freed: %12ld\n", pool->e_freed);
FDPRINT(" Alloc count: %12.0f\n", (double) pool->n_allocated);
FDPRINT(" Free Count: %12.0f\n", (double) pool->n_freed);
FDPRINT(" Bytes allocated: %12.0f\n", (double) pool->b_allocated);
FDPRINT(" Bytes freed: %12.0f\n", (double) pool->b_freed);
if (summarize)
return;
if (!pool->extents)
return;
write(fd, "\n", 1);
for (cur = pool->extents; cur; cur = cur->next)
FDEXTSTAT(cur);
}

View File

@@ -1,21 +0,0 @@
#include <stddef.h>
#define POOL_CLEAR (1<<0) /* zero fill allocations */
#define POOL_QALIGN (1<<1) /* align data to quanta */
#define POOL_INTERN (1<<2) /* Allocate extent structures */
#define POOL_APPEND (1<<3) /* or appended to extent data */
typedef void *alloc_pool_t;
alloc_pool_t pool_create(size_t size, size_t quantum, void (*bomb)(const char *), int flags);
void pool_destroy(alloc_pool_t pool);
void *pool_alloc(alloc_pool_t pool, size_t size, const char *bomb_msg);
void pool_free(alloc_pool_t pool, size_t size, void *addr);
void pool_free_old(alloc_pool_t pool, void *addr);
void *pool_boundary(alloc_pool_t pool, size_t size);
#define pool_talloc(pool, type, count, bomb_msg) \
((type *)pool_alloc(pool, sizeof(type) * count, bomb_msg))
#define pool_tfree(pool, type, count, addr) \
(pool_free(pool, sizeof(type) * count, addr))

View File

@@ -1,7 +1,3 @@
/*
* NOTE: If you change this file, please merge it into rsync, samba, etc.
*/
/*
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell (papowell@astart.com)
@@ -57,57 +53,11 @@
* got rid of fcvt code (twas buggy and made testing harder)
* added C99 semantics
*
* date: 2002/12/19 19:56:31; author: herb; state: Exp; lines: +2 -0
* actually print args for %g and %e
*
* date: 2002/06/03 13:37:52; author: jmcd; state: Exp; lines: +8 -0
* Since includes.h isn't included here, VA_COPY has to be defined here. I don't
* see any include file that is guaranteed to be here, so I'm defining it
* locally. Fixes AIX and Solaris builds.
*
* date: 2002/06/03 03:07:24; author: tridge; state: Exp; lines: +5 -13
* put the ifdef for HAVE_VA_COPY in one place rather than in lots of
* functions
*
* date: 2002/05/17 14:51:22; author: jmcd; state: Exp; lines: +21 -4
* Fix usage of va_list passed as an arg. Use __va_copy before using it
* when it exists.
*
* date: 2002/04/16 22:38:04; author: idra; state: Exp; lines: +20 -14
* Fix incorrect zpadlen handling in fmtfp.
* Thanks to Ollie Oldham <ollie.oldham@metro-optix.com> for spotting it.
* few mods to make it easier to compile the tests.
* addedd the "Ollie" test to the floating point ones.
*
* Martin Pool (mbp@samba.org) April 2003
* Remove NO_CONFIG_H so that the test case can be built within a source
* tree with less trouble.
* Remove unnecessary SAFE_FREE() definition.
*
* Martin Pool (mbp@samba.org) May 2003
* Put in a prototype for dummy_snprintf() to quiet compiler warnings.
*
* Move #endif to make sure VA_COPY, LDOUBLE, etc are defined even
* if the C library has some snprintf functions already.
**************************************************************/
#ifndef NO_CONFIG_H
#ifndef NO_CONFIG_H /* for some tests */
#include "config.h"
#else
#define NULL 0
#endif
#ifdef TEST_SNPRINTF /* need math library headers for testing */
/* In test mode, we pretend that this system doesn't have any snprintf
* functions, regardless of what config.h says. */
# undef HAVE_SNPRINTF
# undef HAVE_VSNPRINTF
# undef HAVE_C99_VSNPRINTF
# undef HAVE_ASPRINTF
# undef HAVE_VASPRINTF
# include <math.h>
#endif /* TEST_SNPRINTF */
#endif
#ifdef HAVE_STRING_H
#include <string.h>
@@ -129,9 +79,8 @@
/* only include stdio.h if we are not re-defining snprintf or vsnprintf */
#include <stdio.h>
/* make the compiler happy with an empty file */
void dummy_snprintf(void);
void dummy_snprintf(void) {}
#endif /* HAVE_SNPRINTF, etc */
#else
#ifdef HAVE_LONG_DOUBLE
#define LDOUBLE long double
@@ -139,22 +88,21 @@
#define LDOUBLE double
#endif
#if SIZEOF_LONG_LONG
#ifdef HAVE_LONG_LONG
#define LLONG long long
#else
#define LLONG long
#endif
#ifndef VA_COPY
#if defined HAVE_VA_COPY || defined va_copy
#define VA_COPY(dest, src) va_copy(dest, src)
#else
#ifdef HAVE___VA_COPY
#define VA_COPY(dest, src) __va_copy(dest, src)
#else
#define VA_COPY(dest, src) (dest) = (src)
#endif
#endif
static size_t dopr(char *buffer, size_t maxlen, const char *format,
va_list args);
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
/*
* dopr(): poor man's version of doprintf
@@ -190,20 +138,7 @@
#define MAX(p,q) (((p) >= (q)) ? (p) : (q))
#endif
/* yes this really must be a ||. Don't muck with this (tridge) */
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
static size_t dopr(char *buffer, size_t maxlen, const char *format,
va_list args_in);
static void fmtstr(char *buffer, size_t *currlen, size_t maxlen,
char *value, int flags, int min, int max);
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
long value, int base, int min, int max, int flags);
static void fmtfp(char *buffer, size_t *currlen, size_t maxlen,
LDOUBLE fvalue, int min, int max, int flags);
static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c);
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args_in)
static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args)
{
char ch;
LLONG value;
@@ -215,9 +150,6 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
int flags;
int cflags;
size_t currlen;
va_list args;
VA_COPY(args, args_in);
state = DP_S_DEFAULT;
currlen = flags = cflags = min = 0;
@@ -387,7 +319,6 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'G':
flags |= DP_F_UP;
@@ -396,14 +327,12 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args
fvalue = va_arg (args, LDOUBLE);
else
fvalue = va_arg (args, double);
fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags);
break;
case 'c':
dopr_outch (buffer, &currlen, maxlen, va_arg (args, int));
break;
case 's':
strvalue = va_arg (args, char *);
if (!strvalue) strvalue = "(NULL)";
if (max == -1) {
max = strlen(strvalue);
}
@@ -632,26 +561,28 @@ static double my_modf(double x0, double *iptr)
for (i=0;i<100;i++) {
l = (long)x;
if (l <= (x+1) && l >= (x-1)) {
if (i != 0) {
double i2;
double ret;
ret = my_modf(x0-l*f, &i2);
(*iptr) = l*f + i2;
return ret;
}
(*iptr) = l;
return x - (*iptr);
}
if (l <= (x+1) && l >= (x-1)) break;
x *= 0.1;
f *= 10.0;
}
/* yikes! the number is beyond what we can handle. What do we do? */
(*iptr) = 0;
return 0;
if (i == 100) {
/* yikes! the number is beyond what we can handle. What do we do? */
(*iptr) = 0;
return 0;
}
if (i != 0) {
double i2;
double ret;
ret = my_modf(x0-l*f, &i2);
(*iptr) = l*f + i2;
return ret;
}
(*iptr) = l;
return x - (*iptr);
}
@@ -667,7 +598,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
int padlen = 0; /* amount to pad */
int zpadlen = 0;
int caps = 0;
int idx;
int index;
double intpart;
double fracpart;
double temp;
@@ -724,13 +655,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
/* Convert integer part */
do {
temp = intpart*0.1;
my_modf(temp, &intpart);
idx = (int) ((temp -intpart +0.05)* 10.0);
/* idx = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
/* printf ("%llf, %f, %x\n", temp, intpart, idx); */
temp = intpart;
my_modf(intpart*0.1, &intpart);
temp = temp*0.1;
index = (int) ((temp -intpart +0.05)* 10.0);
/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
/* printf ("%llf, %f, %x\n", temp, intpart, index); */
iconvert[iplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[idx];
(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
} while (intpart && (iplace < 311));
if (iplace == 311) iplace--;
iconvert[iplace] = 0;
@@ -739,13 +671,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (fracpart)
{
do {
temp = fracpart*0.1;
my_modf(temp, &fracpart);
idx = (int) ((temp -fracpart +0.05)* 10.0);
/* idx = (int) ((((temp/10) -fracpart) +0.05) *10); */
/* printf ("%lf, %lf, %ld\n", temp, fracpart, idx ); */
temp = fracpart;
my_modf(fracpart*0.1, &fracpart);
temp = temp*0.1;
index = (int) ((temp -fracpart +0.05)* 10.0);
/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
fconvert[fplace++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")[idx];
(caps? "0123456789ABCDEF":"0123456789abcdef")[index];
} while(fracpart && (fplace < 311));
if (fplace == 311) fplace--;
}
@@ -792,14 +725,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (max > 0) {
dopr_outch (buffer, currlen, maxlen, '.');
while (zpadlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
}
while (zpadlen > 0) {
dopr_outch (buffer, currlen, maxlen, '0');
--zpadlen;
}
while (padlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
@@ -815,21 +748,15 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
(*currlen)++;
}
int rsync_vsnprintf (char *str, size_t count, const char *fmt, va_list args)
#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
int vsnprintf (char *str, size_t count, const char *fmt, va_list args)
{
return dopr(str, count, fmt, args);
}
#define vsnprintf rsync_vsnprintf
#endif
/* yes this really must be a ||. Don't muck with this (tridge)
*
* The logic for these two is that we need our own definition if the
* OS *either* has no definition of *sprintf, or if it does have one
* that doesn't work properly according to the autoconf test.
*/
#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF)
int rsync_snprintf(char *str,size_t count,const char *fmt,...)
int snprintf(char *str,size_t count,const char *fmt,...)
{
size_t ret;
va_list ap;
@@ -839,7 +766,6 @@ int rsync_snprintf(char *str,size_t count,const char *fmt,...)
va_end(ap);
return ret;
}
#define snprintf rsync_snprintf
#endif
#endif
@@ -848,19 +774,13 @@ int rsync_snprintf(char *str,size_t count,const char *fmt,...)
int vasprintf(char **ptr, const char *format, va_list ap)
{
int ret;
va_list ap2;
VA_COPY(ap2, ap);
ret = vsnprintf(NULL, 0, format, ap2);
ret = vsnprintf(NULL, 0, format, ap);
if (ret <= 0) return ret;
(*ptr) = (char *)malloc(ret+1);
if (!*ptr) return -1;
VA_COPY(ap2, ap);
ret = vsnprintf(*ptr, ret+1, format, ap2);
ret = vsnprintf(*ptr, ret+1, format, ap);
return ret;
}
@@ -873,7 +793,6 @@ int rsync_snprintf(char *str,size_t count,const char *fmt,...)
va_list ap;
int ret;
*ptr = NULL;
va_start(ap, format);
ret = vasprintf(ptr, format, ap);
va_end(ap);
@@ -908,9 +827,8 @@ int rsync_snprintf(char *str,size_t count,const char *fmt,...)
"-16.16f",
NULL
};
double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 5.030201, 0.00205,
/* END LIST */ 0};
double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
0.9996, 1.996, 4.136, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
@@ -1005,10 +923,8 @@ int rsync_snprintf(char *str,size_t count,const char *fmt,...)
{
double v0 = 0.12345678901234567890123456789012345678901;
for (x=0; x<100; x++) {
double p = pow(10, x);
double r = v0*p;
snprintf(buf1, sizeof(buf1), "%1.1f", r);
sprintf(buf2, "%1.1f", r);
snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
sprintf(buf2, "%1.1f", v0*pow(10, x));
if (strcmp(buf1, buf2)) {
printf("we seem to support %d digits\n", x-1);
break;
@@ -1018,4 +934,4 @@ int rsync_snprintf(char *str,size_t count,const char *fmt,...)
return 0;
}
#endif /* TEST_SNPRINTF */
#endif /* SNPRINTF_TEST */

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,305 +0,0 @@
/*
* Unix SMB/Netbios implementation.
* Version 2.2.x
* Portable SMB ACL interface
* Copyright (C) Jeremy Allison 2000
* Copyright (C) 2007-2008 Wayne Davison
*
* 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 3 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
* with this program; if not, visit the http://fsf.org website.
*/
#ifdef SUPPORT_ACLS
#ifdef HAVE_SYS_ACL_H
#include <sys/acl.h>
#endif
#ifdef HAVE_ACL_LIBACL_H
#include <acl/libacl.h>
#endif
#define SMB_MALLOC(cnt) new_array(char, cnt)
#define SMB_MALLOC_P(obj) new_array(obj, 1)
#define SMB_MALLOC_ARRAY(obj, cnt) new_array(obj, cnt)
#define SMB_REALLOC(mem, cnt) realloc_array(mem, char, cnt)
#define slprintf snprintf
#if defined HAVE_POSIX_ACLS /*-----------------------------------------------*/
/* This is an identity mapping (just remove the SMB_). */
#define SMB_ACL_TAG_T acl_tag_t
#define SMB_ACL_TYPE_T acl_type_t
/* Types of ACLs. */
#define SMB_ACL_USER ACL_USER
#define SMB_ACL_USER_OBJ ACL_USER_OBJ
#define SMB_ACL_GROUP ACL_GROUP
#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
#define SMB_ACL_OTHER ACL_OTHER
#define SMB_ACL_MASK ACL_MASK
#define SMB_ACL_T acl_t
#define SMB_ACL_ENTRY_T acl_entry_t
#define SMB_ACL_FIRST_ENTRY ACL_FIRST_ENTRY
#define SMB_ACL_NEXT_ENTRY ACL_NEXT_ENTRY
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
#define SMB_ACL_NEED_SORT
#elif defined HAVE_TRU64_ACLS /*---------------------------------------------*/
/* This is for DEC/Compaq Tru64 UNIX */
#define SMB_ACL_TAG_T acl_tag_t
#define SMB_ACL_TYPE_T acl_type_t
/* Types of ACLs. */
#define SMB_ACL_USER ACL_USER
#define SMB_ACL_USER_OBJ ACL_USER_OBJ
#define SMB_ACL_GROUP ACL_GROUP
#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
#define SMB_ACL_OTHER ACL_OTHER
#define SMB_ACL_MASK ACL_MASK
#define SMB_ACL_T acl_t
#define SMB_ACL_ENTRY_T acl_entry_t
#define SMB_ACL_FIRST_ENTRY 0
#define SMB_ACL_NEXT_ENTRY 1
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
#define SMB_ACL_NEED_SORT
#elif defined HAVE_UNIXWARE_ACLS || defined HAVE_SOLARIS_ACLS /*-------------*/
/* Donated by Michael Davidson <md@sco.COM> for UnixWare / OpenUNIX.
* Modified by Toomas Soome <tsoome@ut.ee> for Solaris. */
/* SVR4.2 ES/MP ACLs */
typedef int SMB_ACL_TAG_T;
typedef int SMB_ACL_TYPE_T;
/* Types of ACLs. */
#define SMB_ACL_USER USER
#define SMB_ACL_USER_OBJ USER_OBJ
#define SMB_ACL_GROUP GROUP
#define SMB_ACL_GROUP_OBJ GROUP_OBJ
#define SMB_ACL_OTHER OTHER_OBJ
#define SMB_ACL_MASK CLASS_OBJ
typedef struct SMB_ACL_T {
int size;
int count;
int next;
struct acl acl[1];
} *SMB_ACL_T;
typedef struct acl *SMB_ACL_ENTRY_T;
#define SMB_ACL_FIRST_ENTRY 0
#define SMB_ACL_NEXT_ENTRY 1
#define SMB_ACL_TYPE_ACCESS 0
#define SMB_ACL_TYPE_DEFAULT 1
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
#define SMB_ACL_NEED_SORT
#ifdef __CYGWIN__
#define SMB_ACL_LOSES_SPECIAL_MODE_BITS
#endif
#elif defined HAVE_HPUX_ACLS /*----------------------------------------------*/
/* Based on the Solaris & UnixWare code. */
#undef GROUP
#include <sys/aclv.h>
/* SVR4.2 ES/MP ACLs */
typedef int SMB_ACL_TAG_T;
typedef int SMB_ACL_TYPE_T;
/* Types of ACLs. */
#define SMB_ACL_USER USER
#define SMB_ACL_USER_OBJ USER_OBJ
#define SMB_ACL_GROUP GROUP
#define SMB_ACL_GROUP_OBJ GROUP_OBJ
#define SMB_ACL_OTHER OTHER_OBJ
#define SMB_ACL_MASK CLASS_OBJ
typedef struct SMB_ACL_T {
int size;
int count;
int next;
struct acl acl[1];
} *SMB_ACL_T;
typedef struct acl *SMB_ACL_ENTRY_T;
#define SMB_ACL_FIRST_ENTRY 0
#define SMB_ACL_NEXT_ENTRY 1
#define SMB_ACL_TYPE_ACCESS 0
#define SMB_ACL_TYPE_DEFAULT 1
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
#define SMB_ACL_NEED_SORT
#elif defined HAVE_IRIX_ACLS /*----------------------------------------------*/
/* IRIX ACLs */
#define SMB_ACL_TAG_T acl_tag_t
#define SMB_ACL_TYPE_T acl_type_t
/* Types of ACLs. */
#define SMB_ACL_USER ACL_USER
#define SMB_ACL_USER_OBJ ACL_USER_OBJ
#define SMB_ACL_GROUP ACL_GROUP
#define SMB_ACL_GROUP_OBJ ACL_GROUP_OBJ
#define SMB_ACL_OTHER ACL_OTHER_OBJ
#define SMB_ACL_MASK ACL_MASK
typedef struct SMB_ACL_T {
int next;
BOOL freeaclp;
struct acl *aclp;
} *SMB_ACL_T;
#define SMB_ACL_ENTRY_T acl_entry_t
#define SMB_ACL_FIRST_ENTRY 0
#define SMB_ACL_NEXT_ENTRY 1
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_ACCESS
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
#define SMB_ACL_NEED_SORT
#elif defined HAVE_AIX_ACLS /*-----------------------------------------------*/
/* Donated by Medha Date, mdate@austin.ibm.com, for IBM */
#include "/usr/include/acl.h"
struct acl_entry_link{
struct acl_entry_link *prevp;
struct new_acl_entry *entryp;
struct acl_entry_link *nextp;
int count;
};
struct new_acl_entry{
unsigned short ace_len;
unsigned short ace_type;
unsigned int ace_access;
struct ace_id ace_id[1];
};
#define SMB_ACL_ENTRY_T struct new_acl_entry*
#define SMB_ACL_T struct acl_entry_link*
#define SMB_ACL_TAG_T unsigned short
#define SMB_ACL_TYPE_T int
/* Types of ACLs. */
#define SMB_ACL_USER ACEID_USER
#define SMB_ACL_USER_OBJ 3
#define SMB_ACL_GROUP ACEID_GROUP
#define SMB_ACL_GROUP_OBJ 4
#define SMB_ACL_OTHER 5
#define SMB_ACL_MASK 6
#define SMB_ACL_FIRST_ENTRY 1
#define SMB_ACL_NEXT_ENTRY 2
#define SMB_ACL_TYPE_ACCESS 0
#define SMB_ACL_TYPE_DEFAULT 1
#define SMB_ACL_VALID_NAME_BITS (4 | 2 | 1)
#define SMB_ACL_VALID_OBJ_BITS (4 | 2 | 1)
#define SMB_ACL_NEED_SORT
#elif defined(HAVE_OSX_ACLS) /*----------------------------------------------*/
/* Special handling for OS X ACLs */
#define SMB_ACL_TAG_T acl_tag_t
#define SMB_ACL_TYPE_T acl_type_t
#define SMB_ACL_T acl_t
#define SMB_ACL_ENTRY_T acl_entry_t
#define SMB_ACL_USER 1
#define SMB_ACL_GROUP 2
#define SMB_ACL_FIRST_ENTRY ACL_FIRST_ENTRY
#define SMB_ACL_NEXT_ENTRY ACL_NEXT_ENTRY
#define SMB_ACL_TYPE_ACCESS ACL_TYPE_EXTENDED
#define SMB_ACL_TYPE_DEFAULT ACL_TYPE_DEFAULT
#define SMB_ACL_VALID_NAME_BITS ((1<<25)-1)
#define SMB_ACL_VALID_OBJ_BITS 0
/*#undef SMB_ACL_NEED_SORT*/
#else /*---------------------------------------------------------------------*/
/* Unknown platform. */
#error Cannot handle ACLs on this platform!
#endif
int sys_acl_get_entry(SMB_ACL_T the_acl, int entry_id, SMB_ACL_ENTRY_T *entry_p);
int sys_acl_get_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p);
int sys_acl_get_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T *tag_type_p, uint32 *bits_p, id_t *u_g_id_p);
SMB_ACL_T sys_acl_get_file(const char *path_p, SMB_ACL_TYPE_T type);
SMB_ACL_T sys_acl_get_fd(int fd);
SMB_ACL_T sys_acl_init(int count);
int sys_acl_create_entry(SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry);
int sys_acl_set_info(SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype, uint32 bits, id_t u_g_id);
int sys_acl_set_access_bits(SMB_ACL_ENTRY_T entry, uint32 bits);
int sys_acl_valid(SMB_ACL_T theacl);
int sys_acl_set_file(const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl);
int sys_acl_set_fd(int fd, SMB_ACL_T theacl);
int sys_acl_delete_def_file(const char *name);
int sys_acl_free_acl(SMB_ACL_T the_acl);
int no_acl_syscall_error(int err);
#endif /* SUPPORT_ACLS */

View File

@@ -1,135 +0,0 @@
/*
* Extended attribute support for rsync.
*
* Copyright (C) 2004 Red Hat, Inc.
* Copyright (C) 2003-2008 Wayne Davison
* Written by Jay Fenlason.
*
* 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 3 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, visit the http://fsf.org website.
*/
#include "rsync.h"
#include "sysxattrs.h"
#ifdef SUPPORT_XATTRS
#if defined HAVE_LINUX_XATTRS
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
{
return lgetxattr(path, name, value, size);
}
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
{
return fgetxattr(filedes, name, value, size);
}
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
{
return lsetxattr(path, name, value, size, 0);
}
int sys_lremovexattr(const char *path, const char *name)
{
return lremovexattr(path, name);
}
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
{
return llistxattr(path, list, size);
}
#elif HAVE_OSX_XATTRS
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
{
return getxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
}
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
{
return fgetxattr(filedes, name, value, size, 0, 0);
}
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
{
return setxattr(path, name, value, size, 0, XATTR_NOFOLLOW);
}
int sys_lremovexattr(const char *path, const char *name)
{
return removexattr(path, name, XATTR_NOFOLLOW);
}
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
{
return listxattr(path, list, size, XATTR_NOFOLLOW);
}
#elif HAVE_FREEBSD_XATTRS
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size)
{
return extattr_get_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
}
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size)
{
return extattr_get_fd(filedes, EXTATTR_NAMESPACE_USER, name, value, size);
}
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size)
{
return extattr_set_link(path, EXTATTR_NAMESPACE_USER, name, value, size);
}
int sys_lremovexattr(const char *path, const char *name)
{
return extattr_delete_link(path, EXTATTR_NAMESPACE_USER, name);
}
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
{
unsigned char keylen;
ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);
if (len <= 0 || (size_t)len > size)
return len;
/* FreeBSD puts a single-byte length before each string, with no '\0'
* terminator. We need to change this into a series of null-terminted
* strings. Since the size is the same, we can simply transform the
* output in place. */
for (off = 0; off < len; off += keylen + 1) {
keylen = ((unsigned char*)list)[off];
if (off + keylen >= len) {
/* Should be impossible, but kernel bugs happen! */
errno = EINVAL;
return -1;
}
memmove(list+off, list+off+1, keylen);
list[off+keylen] = '\0';
}
return len;
}
#else
#error You need to create xattr compatibility functions.
#endif
#endif /* SUPPORT_XATTRS */

View File

@@ -1,26 +0,0 @@
#ifdef SUPPORT_XATTRS
#if defined HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#elif defined HAVE_SYS_XATTR_H
#include <sys/xattr.h>
#elif defined HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
/* Linux 2.4 does not define this as a distinct errno value: */
#ifndef ENOATTR
#define ENOATTR ENODATA
#endif
ssize_t sys_lgetxattr(const char *path, const char *name, void *value, size_t size);
ssize_t sys_fgetxattr(int filedes, const char *name, void *value, size_t size);
int sys_lsetxattr(const char *path, const char *name, const void *value, size_t size);
int sys_lremovexattr(const char *path, const char *name);
ssize_t sys_llistxattr(const char *path, char *list, size_t size);
#else
/* No xattrs available */
#endif

View File

@@ -1,368 +0,0 @@
/*
** Do shell-style pattern matching for ?, \, [], and * characters.
** It is 8bit clean.
**
** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
** Rich $alz is now <rsalz@bbn.com>.
**
** Modified by Wayne Davison to special-case '/' matching, to make '**'
** work differently than '*', and to fix the character-class code.
*/
#include "rsync.h"
/* What character marks an inverted character class? */
#define NEGATE_CLASS '!'
#define NEGATE_CLASS2 '^'
#define FALSE 0
#define TRUE 1
#define ABORT_ALL -1
#define ABORT_TO_STARSTAR -2
#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \
&& *(class) == *(litmatch) \
&& strncmp((char*)class, litmatch, len) == 0)
#if defined STDC_HEADERS || !defined isascii
# define ISASCII(c) 1
#else
# define ISASCII(c) isascii(c)
#endif
#ifdef isblank
# define ISBLANK(c) (ISASCII(c) && isblank(c))
#else
# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
# define ISGRAPH(c) (ISASCII(c) && isgraph(c))
#else
# define ISGRAPH(c) (ISASCII(c) && isprint(c) && !isspace(c))
#endif
#define ISPRINT(c) (ISASCII(c) && isprint(c))
#define ISDIGIT(c) (ISASCII(c) && isdigit(c))
#define ISALNUM(c) (ISASCII(c) && isalnum(c))
#define ISALPHA(c) (ISASCII(c) && isalpha(c))
#define ISCNTRL(c) (ISASCII(c) && iscntrl(c))
#define ISLOWER(c) (ISASCII(c) && islower(c))
#define ISPUNCT(c) (ISASCII(c) && ispunct(c))
#define ISSPACE(c) (ISASCII(c) && isspace(c))
#define ISUPPER(c) (ISASCII(c) && isupper(c))
#define ISXDIGIT(c) (ISASCII(c) && isxdigit(c))
#ifdef WILD_TEST_ITERATIONS
int wildmatch_iteration_count;
#endif
static int force_lower_case = 0;
/* Match pattern "p" against the a virtually-joined string consisting
* of "text" and any strings in array "a". */
static int dowild(const uchar *p, const uchar *text, const uchar*const *a)
{
uchar p_ch;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count++;
#endif
for ( ; (p_ch = *p) != '\0'; text++, p++) {
int matched, special;
uchar t_ch, prev_ch;
while ((t_ch = *text) == '\0') {
if (*a == NULL) {
if (p_ch != '*')
return ABORT_ALL;
break;
}
text = *a++;
}
if (force_lower_case && ISUPPER(t_ch))
t_ch = tolower(t_ch);
switch (p_ch) {
case '\\':
/* Literal match with following character. Note that the test
* in "default" handles the p[1] == '\0' failure case. */
p_ch = *++p;
/* FALLTHROUGH */
default:
if (t_ch != p_ch)
return FALSE;
continue;
case '?':
/* Match anything but '/'. */
if (t_ch == '/')
return FALSE;
continue;
case '*':
if (*++p == '*') {
while (*++p == '*') {}
special = TRUE;
} else
special = FALSE;
if (*p == '\0') {
/* Trailing "**" matches everything. Trailing "*" matches
* only if there are no more slash characters. */
if (!special) {
do {
if (strchr((char*)text, '/') != NULL)
return FALSE;
} while ((text = *a++) != NULL);
}
return TRUE;
}
while (1) {
if (t_ch == '\0') {
if ((text = *a++) == NULL)
break;
t_ch = *text;
continue;
}
if ((matched = dowild(p, text, a)) != FALSE) {
if (!special || matched != ABORT_TO_STARSTAR)
return matched;
} else if (!special && t_ch == '/')
return ABORT_TO_STARSTAR;
t_ch = *++text;
}
return ABORT_ALL;
case '[':
p_ch = *++p;
#ifdef NEGATE_CLASS2
if (p_ch == NEGATE_CLASS2)
p_ch = NEGATE_CLASS;
#endif
/* Assign literal TRUE/FALSE because of "matched" comparison. */
special = p_ch == NEGATE_CLASS? TRUE : FALSE;
if (special) {
/* Inverted character class. */
p_ch = *++p;
}
prev_ch = 0;
matched = FALSE;
do {
if (!p_ch)
return ABORT_ALL;
if (p_ch == '\\') {
p_ch = *++p;
if (!p_ch)
return ABORT_ALL;
if (t_ch == p_ch)
matched = TRUE;
} else if (p_ch == '-' && prev_ch && p[1] && p[1] != ']') {
p_ch = *++p;
if (p_ch == '\\') {
p_ch = *++p;
if (!p_ch)
return ABORT_ALL;
}
if (t_ch <= p_ch && t_ch >= prev_ch)
matched = TRUE;
p_ch = 0; /* This makes "prev_ch" get set to 0. */
} else if (p_ch == '[' && p[1] == ':') {
const uchar *s;
int i;
for (s = p += 2; (p_ch = *p) && p_ch != ']'; p++) {} /*SHARED ITERATOR*/
if (!p_ch)
return ABORT_ALL;
i = p - s - 1;
if (i < 0 || p[-1] != ':') {
/* Didn't find ":]", so treat like a normal set. */
p = s - 2;
p_ch = '[';
if (t_ch == p_ch)
matched = TRUE;
continue;
}
if (CC_EQ(s,i, "alnum")) {
if (ISALNUM(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "alpha")) {
if (ISALPHA(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "blank")) {
if (ISBLANK(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "cntrl")) {
if (ISCNTRL(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "digit")) {
if (ISDIGIT(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "graph")) {
if (ISGRAPH(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "lower")) {
if (ISLOWER(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "print")) {
if (ISPRINT(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "punct")) {
if (ISPUNCT(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "space")) {
if (ISSPACE(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "upper")) {
if (ISUPPER(t_ch))
matched = TRUE;
} else if (CC_EQ(s,i, "xdigit")) {
if (ISXDIGIT(t_ch))
matched = TRUE;
} else /* malformed [:class:] string */
return ABORT_ALL;
p_ch = 0; /* This makes "prev_ch" get set to 0. */
} else if (t_ch == p_ch)
matched = TRUE;
} while (prev_ch = p_ch, (p_ch = *++p) != ']');
if (matched == special || t_ch == '/')
return FALSE;
continue;
}
}
do {
if (*text)
return FALSE;
} while ((text = *a++) != NULL);
return TRUE;
}
/* Match literal string "s" against the a virtually-joined string consisting
* of "text" and any strings in array "a". */
static int doliteral(const uchar *s, const uchar *text, const uchar*const *a)
{
for ( ; *s != '\0'; text++, s++) {
while (*text == '\0') {
if ((text = *a++) == NULL)
return FALSE;
}
if (*text != *s)
return FALSE;
}
do {
if (*text)
return FALSE;
} while ((text = *a++) != NULL);
return TRUE;
}
/* Return the last "count" path elements from the concatenated string.
* We return a string pointer to the start of the string, and update the
* array pointer-pointer to point to any remaining string elements. */
static const uchar *trailing_N_elements(const uchar*const **a_ptr, int count)
{
const uchar*const *a = *a_ptr;
const uchar*const *first_a = a;
while (*a)
a++;
while (a != first_a) {
const uchar *s = *--a;
s += strlen((char*)s);
while (--s >= *a) {
if (*s == '/' && !--count) {
*a_ptr = a+1;
return s+1;
}
}
}
if (count == 1) {
*a_ptr = a+1;
return *a;
}
return NULL;
}
/* Match the "pattern" against the "text" string. */
int wildmatch(const char *pattern, const char *text)
{
static const uchar *nomore[1]; /* A NULL pointer. */
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
return dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
}
/* Match the "pattern" against the forced-to-lower-case "text" string. */
int iwildmatch(const char *pattern, const char *text)
{
static const uchar *nomore[1]; /* A NULL pointer. */
int ret;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
force_lower_case = 1;
ret = dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
force_lower_case = 0;
return ret;
}
/* Match pattern "p" against the a virtually-joined string consisting
* of all the pointers in array "texts" (which has a NULL pointer at the
* end). The int "where" can be 0 (normal matching), > 0 (match only
* the trailing N slash-separated filename components of "texts"), or < 0
* (match the "pattern" at the start or after any slash in "texts"). */
int wildmatch_array(const char *pattern, const char*const *texts, int where)
{
const uchar *p = (const uchar*)pattern;
const uchar*const *a = (const uchar*const*)texts;
const uchar *text;
int matched;
#ifdef WILD_TEST_ITERATIONS
wildmatch_iteration_count = 0;
#endif
if (where > 0)
text = trailing_N_elements(&a, where);
else
text = *a++;
if (!text)
return FALSE;
if ((matched = dowild(p, text, a)) != TRUE && where < 0
&& matched != ABORT_ALL) {
while (1) {
if (*text == '\0') {
if ((text = (uchar*)*a++) == NULL)
return FALSE;
continue;
}
if (*text++ == '/' && (matched = dowild(p, text, a)) != FALSE
&& matched != ABORT_TO_STARSTAR)
break;
}
}
return matched == TRUE;
}
/* Match literal string "s" against the a virtually-joined string consisting
* of all the pointers in array "texts" (which has a NULL pointer at the
* end). The int "where" can be 0 (normal matching), or > 0 (match
* only the trailing N slash-separated filename components of "texts"). */
int litmatch_array(const char *string, const char*const *texts, int where)
{
const uchar *s = (const uchar*)string;
const uchar*const *a = (const uchar* const*)texts;
const uchar *text;
if (where > 0)
text = trailing_N_elements(&a, where);
else
text = *a++;
if (!text)
return FALSE;
return doliteral(s, text, a) == TRUE;
}

View File

@@ -1,6 +0,0 @@
/* wildmatch.h */
int wildmatch(const char *pattern, const char *text);
int iwildmatch(const char *pattern, const char *text);
int wildmatch_array(const char *pattern, const char*const *texts, int where);
int litmatch_array(const char *string, const char*const *texts, int where);

View File

@@ -1,26 +1,27 @@
/* This is based on loadparm.c from Samba, written by Andrew Tridgell
and Karl Auer */
/*
* 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 3 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, visit the http://fsf.org website.
*/
/* some fixes
*
* Copyright (C) 2001, 2002 Martin Pool <mbp@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.
*/
/*
* Load parameters.
*
@@ -35,7 +36,7 @@
* 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
* 4) If it's a global then initialise it in init_globals. If a local
* (ie. service) parameter then initialise it in the sDefault structure
*
*
*
* Notes:
* The configuration file is processed sequentially for speed. It is NOT
@@ -47,28 +48,18 @@
*
*/
/* TODO: Parameter to set debug level on server. */
#include "rsync.h"
#include "ifuncs.h"
#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
#define strequal(a,b) (strcasecmp(a,b)==0)
#define BOOLSTR(b) ((b) ? "Yes" : "No")
typedef char pstring[1024];
#define pstrcpy(a,b) strlcpy(a,b,sizeof(pstring))
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
#define DEFAULT_DONT_COMPRESS "*.gz *.zip *.z *.rpm *.deb *.iso *.bz2" \
" *.t[gb]z *.7z *.mp[34] *.mov *.avi *.ogg *.jpg *.jpeg"
/* the following are used by loadparm for option lists */
typedef enum
{
P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
P_PATH,P_STRING,P_GSTRING,P_ENUM,P_SEP
P_STRING,P_GSTRING,P_ENUM,P_SEP
} parm_type;
typedef enum
@@ -100,122 +91,85 @@ struct parm_struct
#define iSERVICE(i) (*pSERVICE(i))
#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices))
/*
/*
* This structure describes global (ie., server-wide) parameters.
*/
typedef struct
{
char *bind_address;
char *motd_file;
char *log_file;
char *pid_file;
int syslog_facility;
char *socket_options;
int rsync_port;
} global;
static global Globals;
/*
* This structure describes a single service. Their order must match the
* initializers below, which you can accomplish by keeping each sub-section
* sorted. (e.g. in vim, just visually select each subsection and use !sort.)
/*
* This structure describes a single service.
*/
typedef struct
{
char *auth_users;
char *charset;
char *name;
char *path;
char *comment;
char *dont_compress;
char *exclude;
char *exclude_from;
char *filter;
char *lock_file;
BOOL read_only;
BOOL list;
BOOL use_chroot;
BOOL transfer_logging;
BOOL ignore_errors;
char *uid;
char *gid;
char *hosts_allow;
char *hosts_deny;
char *auth_users;
char *secrets_file;
BOOL strict_modes;
char *exclude;
char *exclude_from;
char *include;
char *include_from;
char *incoming_chmod;
char *lock_file;
char *log_file;
char *log_format;
char *name;
char *outgoing_chmod;
char *path;
char *postxfer_exec;
char *prexfer_exec;
char *refuse_options;
char *secrets_file;
char *temp_dir;
char *uid;
int max_connections;
int max_verbosity;
int syslog_facility;
char *dont_compress;
int timeout;
BOOL fake_super;
BOOL ignore_errors;
int max_connections;
BOOL ignore_nonreadable;
BOOL list;
BOOL munge_symlinks;
BOOL numeric_ids;
BOOL read_only;
BOOL strict_modes;
BOOL transfer_logging;
BOOL use_chroot;
BOOL write_only;
} service;
/* This is a default service used to prime a services structure. In order
* to make these easy to keep sorted in the same way as the variables
* above, use the variable name in the leading comment, including a
* trailing ';' (to avoid a sorting problem with trailing digits). */
static service sDefault =
/* This is a default service used to prime a services structure */
static service sDefault =
{
/* auth_users; */ NULL,
/* charset; */ NULL,
/* comment; */ NULL,
/* dont_compress; */ DEFAULT_DONT_COMPRESS,
/* exclude; */ NULL,
/* exclude_from; */ NULL,
/* filter; */ NULL,
/* gid; */ NOBODY_GROUP,
/* hosts_allow; */ NULL,
/* hosts_deny; */ NULL,
/* include; */ NULL,
/* include_from; */ NULL,
/* incoming_chmod; */ NULL,
/* lock_file; */ DEFAULT_LOCK_FILE,
/* log_file; */ NULL,
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
/* name; */ NULL,
/* outgoing_chmod; */ NULL,
/* path; */ NULL,
/* postxfer_exec; */ NULL,
/* prexfer_exec; */ NULL,
/* refuse_options; */ NULL,
/* secrets_file; */ NULL,
/* temp_dir; */ NULL,
/* uid; */ NOBODY_USER,
/* max_connections; */ 0,
/* max_verbosity; */ 1,
/* syslog_facility; */ LOG_DAEMON,
/* timeout; */ 0,
/* fake_super; */ False,
/* ignore_errors; */ False,
/* ignore_nonreadable; */ False,
/* list; */ True,
/* munge_symlinks; */ (BOOL)-1,
/* numeric_ids; */ (BOOL)-1,
/* read_only; */ True,
/* strict_modes; */ True,
/* transfer_logging; */ False,
/* use_chroot; */ True,
/* write_only; */ False,
NULL, /* name */
NULL, /* path */
NULL, /* comment */
DEFAULT_LOCK_FILE, /* lock file */
True, /* read only */
True, /* list */
True, /* use chroot */
False, /* transfer logging */
False, /* ignore errors */
"nobody",/* uid */
"nobody",/* gid */
NULL, /* hosts allow */
NULL, /* hosts deny */
NULL, /* auth users */
NULL, /* secrets file */
True, /* strict modes */
NULL, /* exclude */
NULL, /* exclude from */
NULL, /* include */
NULL, /* include from */
"%o %h [%a] %m (%u) %f %l", /* log format */
NULL, /* refuse options */
"*.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz", /* dont compress */
0, /* timeout */
0, /* max connections */
False /* ignore nonreadable */
};
@@ -257,7 +211,7 @@ static struct enum_list enum_facilities[] = {
{ LOG_NEWS, "news" },
#endif
#ifdef LOG_AUTH
{ LOG_AUTH, "security" },
{ LOG_AUTH, "security" },
#endif
#ifdef LOG_SYSLOG
{ LOG_SYSLOG, "syslog" },
@@ -298,68 +252,55 @@ static struct enum_list enum_facilities[] = {
/* note that we do not initialise the defaults union - it is not allowed in ANSI C */
static struct parm_struct parm_table[] =
{
{"address", P_STRING, P_GLOBAL,&Globals.bind_address, NULL,0},
{"motd file", P_STRING, P_GLOBAL,&Globals.motd_file, NULL,0},
{"pid file", P_STRING, P_GLOBAL,&Globals.pid_file, NULL,0},
{"port", P_INTEGER,P_GLOBAL,&Globals.rsync_port, NULL,0},
{"socket options", P_STRING, P_GLOBAL,&Globals.socket_options, NULL,0},
{"motd file", P_STRING, P_GLOBAL, &Globals.motd_file, NULL, 0},
{"syslog facility", P_ENUM, P_GLOBAL, &Globals.syslog_facility, enum_facilities,0},
{"socket options", P_STRING, P_GLOBAL, &Globals.socket_options,NULL, 0},
{"log file", P_STRING, P_GLOBAL, &Globals.log_file, NULL, 0},
{"pid file", P_STRING, P_GLOBAL, &Globals.pid_file, NULL, 0},
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL,0},
{"charset", P_STRING, P_LOCAL, &sDefault.charset, NULL,0},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL,0},
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress, NULL,0},
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from, NULL,0},
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL,0},
{"fake super", P_BOOL, P_LOCAL, &sDefault.fake_super, NULL,0},
{"filter", P_STRING, P_LOCAL, &sDefault.filter, NULL,0},
{"gid", P_STRING, P_LOCAL, &sDefault.gid, NULL,0},
{"hosts allow", P_STRING, P_LOCAL, &sDefault.hosts_allow, NULL,0},
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors, NULL,0},
{"ignore nonreadable",P_BOOL, P_LOCAL, &sDefault.ignore_nonreadable,NULL,0},
{"include from", P_STRING, P_LOCAL, &sDefault.include_from, NULL,0},
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL,0},
{"incoming chmod", P_STRING, P_LOCAL, &sDefault.incoming_chmod, NULL,0},
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL,0},
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL,0},
{"log file", P_STRING, P_LOCAL, &sDefault.log_file, NULL,0},
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL,0},
{"max connections", P_INTEGER,P_LOCAL, &sDefault.max_connections, NULL,0},
{"max verbosity", P_INTEGER,P_LOCAL, &sDefault.max_verbosity, NULL,0},
{"munge symlinks", P_BOOL, P_LOCAL, &sDefault.munge_symlinks, NULL,0},
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL,0},
{"numeric ids", P_BOOL, P_LOCAL, &sDefault.numeric_ids, NULL,0},
{"outgoing chmod", P_STRING, P_LOCAL, &sDefault.outgoing_chmod, NULL,0},
{"path", P_PATH, P_LOCAL, &sDefault.path, NULL,0},
#ifdef HAVE_PUTENV
{"post-xfer exec", P_STRING, P_LOCAL, &sDefault.postxfer_exec, NULL,0},
{"pre-xfer exec", P_STRING, P_LOCAL, &sDefault.prexfer_exec, NULL,0},
#endif
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL,0},
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options, NULL,0},
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file, NULL,0},
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes, NULL,0},
{"syslog facility", P_ENUM, P_LOCAL, &sDefault.syslog_facility,enum_facilities,0},
{"temp dir", P_PATH, P_LOCAL, &sDefault.temp_dir, NULL,0},
{"timeout", P_INTEGER,P_LOCAL, &sDefault.timeout, NULL,0},
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging, NULL,0},
{"uid", P_STRING, P_LOCAL, &sDefault.uid, NULL,0},
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL,0},
{"write only", P_BOOL, P_LOCAL, &sDefault.write_only, NULL,0},
{NULL, P_BOOL, P_NONE, NULL, NULL,0}
{"timeout", P_INTEGER, P_LOCAL, &sDefault.timeout, NULL, 0},
{"max connections", P_INTEGER, P_LOCAL, &sDefault.max_connections,NULL, 0},
{"name", P_STRING, P_LOCAL, &sDefault.name, NULL, 0},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, 0},
{"lock file", P_STRING, P_LOCAL, &sDefault.lock_file, NULL, 0},
{"path", P_STRING, P_LOCAL, &sDefault.path, NULL, 0},
{"read only", P_BOOL, P_LOCAL, &sDefault.read_only, NULL, 0},
{"list", P_BOOL, P_LOCAL, &sDefault.list, NULL, 0},
{"use chroot", P_BOOL, P_LOCAL, &sDefault.use_chroot, NULL, 0},
{"ignore nonreadable",P_BOOL, P_LOCAL, &sDefault.ignore_nonreadable, NULL, 0},
{"uid", P_STRING, P_LOCAL, &sDefault.uid, NULL, 0},
{"gid", P_STRING, P_LOCAL, &sDefault.gid, NULL, 0},
{"hosts allow", P_STRING, P_LOCAL, &sDefault.hosts_allow, NULL, 0},
{"hosts deny", P_STRING, P_LOCAL, &sDefault.hosts_deny, NULL, 0},
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL, 0},
{"secrets file", P_STRING, P_LOCAL, &sDefault.secrets_file,NULL, 0},
{"strict modes", P_BOOL, P_LOCAL, &sDefault.strict_modes,NULL, 0},
{"exclude", P_STRING, P_LOCAL, &sDefault.exclude, NULL, 0},
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from,NULL, 0},
{"include", P_STRING, P_LOCAL, &sDefault.include, NULL, 0},
{"include from", P_STRING, P_LOCAL, &sDefault.include_from,NULL, 0},
{"transfer logging", P_BOOL, P_LOCAL, &sDefault.transfer_logging,NULL,0},
{"ignore errors", P_BOOL, P_LOCAL, &sDefault.ignore_errors,NULL,0},
{"log format", P_STRING, P_LOCAL, &sDefault.log_format, NULL, 0},
{"refuse options", P_STRING, P_LOCAL, &sDefault.refuse_options,NULL, 0},
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress,NULL, 0},
{NULL, P_BOOL, P_NONE, NULL, NULL, 0}
};
/***************************************************************************
* Initialise the global parameter structure.
Initialise the global parameter structure.
***************************************************************************/
static void init_globals(void)
{
memset(&Globals, 0, sizeof Globals);
memset(&Globals, 0, sizeof(Globals));
#ifdef LOG_DAEMON
Globals.syslog_facility = LOG_DAEMON;
#endif
}
/***************************************************************************
* Initialise the sDefault parameter structure.
Initialise the sDefault parameter structure.
***************************************************************************/
static void init_locals(void)
{
@@ -367,8 +308,8 @@ static void init_locals(void)
/*
In this section all the functions that are used to access the
parameters from the rest of the program are defined
In this section all the functions that are used to access the
parameters from the rest of the program are defined
*/
#define FN_GLOBAL_STRING(fn_name,ptr) \
@@ -390,68 +331,52 @@ static void init_locals(void)
int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
FN_GLOBAL_STRING(lp_bind_address, &Globals.bind_address)
FN_GLOBAL_STRING(lp_motd_file, &Globals.motd_file)
FN_GLOBAL_STRING(lp_log_file, &Globals.log_file)
FN_GLOBAL_STRING(lp_pid_file, &Globals.pid_file)
FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
FN_GLOBAL_INTEGER(lp_syslog_facility, &Globals.syslog_facility)
FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_charset, charset)
FN_LOCAL_STRING(lp_name, name)
FN_LOCAL_STRING(lp_comment, comment)
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
FN_LOCAL_STRING(lp_filter, filter)
FN_LOCAL_STRING(lp_path, path)
FN_LOCAL_STRING(lp_lock_file, lock_file)
FN_LOCAL_BOOL(lp_read_only, read_only)
FN_LOCAL_BOOL(lp_list, list)
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
FN_LOCAL_STRING(lp_uid, uid)
FN_LOCAL_STRING(lp_gid, gid)
FN_LOCAL_STRING(lp_hosts_allow, hosts_allow)
FN_LOCAL_STRING(lp_hosts_deny, hosts_deny)
FN_LOCAL_STRING(lp_auth_users, auth_users)
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
FN_LOCAL_STRING(lp_exclude, exclude)
FN_LOCAL_STRING(lp_exclude_from, exclude_from)
FN_LOCAL_STRING(lp_include, include)
FN_LOCAL_STRING(lp_include_from, include_from)
FN_LOCAL_STRING(lp_incoming_chmod, incoming_chmod)
FN_LOCAL_STRING(lp_lock_file, lock_file)
FN_LOCAL_STRING(lp_log_file, log_file)
FN_LOCAL_STRING(lp_log_format, log_format)
FN_LOCAL_STRING(lp_name, name)
FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
FN_LOCAL_STRING(lp_path, path)
FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
FN_LOCAL_STRING(lp_refuse_options, refuse_options)
FN_LOCAL_STRING(lp_secrets_file, secrets_file)
FN_LOCAL_STRING(lp_temp_dir, temp_dir)
FN_LOCAL_STRING(lp_uid, uid)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
FN_LOCAL_STRING(lp_dont_compress, dont_compress)
FN_LOCAL_INTEGER(lp_timeout, timeout)
FN_LOCAL_BOOL(lp_fake_super, fake_super)
FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
FN_LOCAL_BOOL(lp_list, list)
FN_LOCAL_BOOL(lp_munge_symlinks, munge_symlinks)
FN_LOCAL_BOOL(lp_numeric_ids, numeric_ids)
FN_LOCAL_BOOL(lp_read_only, read_only)
FN_LOCAL_BOOL(lp_strict_modes, strict_modes)
FN_LOCAL_BOOL(lp_transfer_logging, transfer_logging)
FN_LOCAL_BOOL(lp_use_chroot, use_chroot)
FN_LOCAL_BOOL(lp_write_only, write_only)
FN_LOCAL_INTEGER(lp_max_connections, max_connections)
/* local prototypes */
static int strwicmp(char *psz1, char *psz2);
static int map_parameter(char *parmname);
static BOOL set_boolean(BOOL *pb, char *parmvalue);
static int strwicmp( char *psz1, char *psz2 );
static int map_parameter( char *parmname);
static BOOL set_boolean( BOOL *pb, char *parmvalue );
static int getservicebyname(char *name, service *pserviceDest);
static void copy_service(service *pserviceDest, service *pserviceSource);
static void copy_service( service *pserviceDest,
service *pserviceSource);
static BOOL do_parameter(char *parmname, char *parmvalue);
static BOOL do_section(char *sectionname);
/***************************************************************************
* initialise a service to the defaults
initialise a service to the defaults
***************************************************************************/
static void init_service(service *pservice)
{
@@ -485,8 +410,8 @@ static void string_set(char **s, const char *v)
/***************************************************************************
* add a new service to the services array initialising it with the given
* service
add a new service to the services array initialising it with the given
service
***************************************************************************/
static int add_a_service(service *pservice, char *name)
{
@@ -497,7 +422,7 @@ static int add_a_service(service *pservice, char *name)
tservice = *pservice;
/* it might already exist */
if (name)
if (name)
{
i = getservicebyname(name,NULL);
if (i >= 0)
@@ -506,10 +431,10 @@ static int add_a_service(service *pservice, char *name)
i = iNumServices;
ServicePtrs = realloc_array(ServicePtrs, service *, num_to_alloc);
ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
if (ServicePtrs)
pSERVICE(iNumServices) = new(service);
pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
if (!ServicePtrs || !pSERVICE(iNumServices))
return(-1);
@@ -519,13 +444,13 @@ static int add_a_service(service *pservice, char *name)
init_service(pSERVICE(i));
copy_service(pSERVICE(i),&tservice);
if (name)
string_set(&iSERVICE(i).name,name);
string_set(&iSERVICE(i).name,name);
return(i);
}
/***************************************************************************
* Do a case-insensitive, whitespace-ignoring string compare.
Do a case-insensitive, whitespace-ignoring string compare.
***************************************************************************/
static int strwicmp(char *psz1, char *psz2)
{
@@ -543,11 +468,11 @@ static int strwicmp(char *psz1, char *psz2)
/* sync the strings on first non-whitespace */
while (1)
{
while (isSpace(psz1))
while (isspace(*psz1))
psz1++;
while (isSpace(psz2))
while (isspace(*psz2))
psz2++;
if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0')
if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
break;
psz1++;
psz2++;
@@ -556,8 +481,8 @@ static int strwicmp(char *psz1, char *psz2)
}
/***************************************************************************
* Map a parameter's string representation to something we can use.
* Returns False if the parameter string is not recognised, else TRUE.
Map a parameter's string representation to something we can use.
Returns False if the parameter string is not recognised, else TRUE.
***************************************************************************/
static int map_parameter(char *parmname)
{
@@ -566,19 +491,19 @@ static int map_parameter(char *parmname)
if (*parmname == '-')
return(-1);
for (iIndex = 0; parm_table[iIndex].label; iIndex++)
for (iIndex = 0; parm_table[iIndex].label; iIndex++)
if (strwicmp(parm_table[iIndex].label, parmname) == 0)
return(iIndex);
rprintf(FLOG, "Unknown Parameter encountered: \"%s\"\n", parmname);
rprintf(FERROR, "Unknown Parameter encountered: \"%s\"\n", parmname);
return(-1);
}
/***************************************************************************
* Set a boolean variable from the text value stored in the passed string.
* Returns True in success, False if the passed string does not correctly
* represent a boolean.
Set a boolean variable from the text value stored in the passed string.
Returns True in success, False if the passed string does not correctly
represent a boolean.
***************************************************************************/
static BOOL set_boolean(BOOL *pb, char *parmvalue)
{
@@ -596,7 +521,7 @@ static BOOL set_boolean(BOOL *pb, char *parmvalue)
*pb = False;
else
{
rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n",
rprintf(FERROR, "Badly formed boolean in configuration file: \"%s\".\n",
parmvalue);
bRetval = False;
}
@@ -604,14 +529,14 @@ static BOOL set_boolean(BOOL *pb, char *parmvalue)
}
/***************************************************************************
* Find a service by name. Otherwise works like get_service.
Find a service by name. Otherwise works like get_service.
***************************************************************************/
static int getservicebyname(char *name, service *pserviceDest)
{
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
if (strwicmp(iSERVICE(iService).name, name) == 0)
if (strwicmp(iSERVICE(iService).name, name) == 0)
{
if (pserviceDest != NULL)
copy_service(pserviceDest, pSERVICE(iService));
@@ -624,9 +549,10 @@ static int getservicebyname(char *name, service *pserviceDest)
/***************************************************************************
* Copy a service structure to another
Copy a service structure to another
***************************************************************************/
static void copy_service(service *pserviceDest,
static void copy_service(service *pserviceDest,
service *pserviceSource)
{
int i;
@@ -634,9 +560,9 @@ static void copy_service(service *pserviceDest,
for (i=0;parm_table[i].label;i++)
if (parm_table[i].ptr && parm_table[i].class == P_LOCAL) {
void *def_ptr = parm_table[i].ptr;
void *src_ptr =
void *src_ptr =
((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
void *dest_ptr =
void *dest_ptr =
((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
switch (parm_table[i].type)
@@ -656,7 +582,6 @@ static void copy_service(service *pserviceDest,
*(char *)dest_ptr = *(char *)src_ptr;
break;
case P_PATH:
case P_STRING:
string_set(dest_ptr,*(char **)src_ptr);
break;
@@ -669,21 +594,20 @@ static void copy_service(service *pserviceDest,
/***************************************************************************
* Process a parameter for a particular service number. If snum < 0
* then assume we are in the globals
Process a parameter for a particular service number. If snum < 0
then assume we are in the globals
***************************************************************************/
static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
{
int parmnum, i;
void *parm_ptr=NULL; /* where we are going to store the result */
void *def_ptr=NULL;
char *cp;
parmnum = map_parameter(parmname);
if (parmnum < 0)
{
rprintf(FLOG, "IGNORING unknown parameter \"%s\"\n", parmname);
rprintf(FERROR, "IGNORING unknown parameter \"%s\"\n", parmname);
return(True);
}
@@ -694,7 +618,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
parm_ptr = def_ptr;
} else {
if (parm_table[parmnum].class == P_GLOBAL) {
rprintf(FLOG, "Global parameter %s found in service section!\n",parmname);
rprintf(FERROR, "Global parameter %s found in service section!\n",parmname);
return(True);
}
parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
@@ -724,15 +648,6 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
sscanf(parmvalue,"%o",(int *)parm_ptr);
break;
case P_PATH:
string_set(parm_ptr,parmvalue);
if ((cp = *(char**)parm_ptr) != NULL) {
int len = strlen(cp);
while (len > 1 && cp[len-1] == '/') len--;
cp[len] = '\0';
}
break;
case P_STRING:
string_set(parm_ptr,parmvalue);
break;
@@ -761,7 +676,7 @@ static BOOL lp_do_parameter(int snum, char *parmname, char *parmvalue)
}
/***************************************************************************
* Process a parameter.
Process a parameter.
***************************************************************************/
static BOOL do_parameter(char *parmname, char *parmvalue)
{
@@ -769,9 +684,9 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
}
/***************************************************************************
* Process a new section (service). At this stage all sections are services.
* Later we'll have special sections that permit server parameters to be set.
* Returns True on success, False on failure.
Process a new section (service). At this stage all sections are services.
Later we'll have special sections that permit server parameters to be set.
Returns True on success, False on failure.
***************************************************************************/
static BOOL do_section(char *sectionname)
{
@@ -784,7 +699,7 @@ static BOOL do_section(char *sectionname)
init_locals();
/* if we've just struck a global section, note the fact. */
bInGlobalSection = isglobal;
bInGlobalSection = isglobal;
/* check for multiple global sections */
if (bInGlobalSection)
@@ -792,11 +707,6 @@ static BOOL do_section(char *sectionname)
return(True);
}
if (strchr(sectionname, '/') != NULL) {
rprintf(FLOG, "Warning: invalid section name in configuration file: %s\n", sectionname);
return False;
}
/* if we have a current service, tidy it up before moving on */
bRetval = True;
@@ -811,7 +721,7 @@ static BOOL do_section(char *sectionname)
if ((iServiceIndex=add_a_service(&sDefault,sectionname)) < 0)
{
rprintf(FLOG, "Failed to add a new service\n");
rprintf(FERROR,"Failed to add a new service\n");
return(False);
}
}
@@ -821,32 +731,32 @@ static BOOL do_section(char *sectionname)
/***************************************************************************
* Load the services array from the services file. Return True on success,
* False on failure.
Load the services array from the services file. Return True on success,
False on failure.
***************************************************************************/
BOOL lp_load(char *pszFname, int globals_only)
{
pstring n2;
BOOL bRetval;
bRetval = False;
bInGlobalSection = True;
init_globals();
pstrcpy(n2, pszFname);
pstrcpy(n2,pszFname);
/* We get sections first, so have to start 'behind' to make up */
iServiceIndex = -1;
bRetval = pm_process(n2, globals_only?NULL:do_section, do_parameter);
return (bRetval);
}
/***************************************************************************
* return the max number of services
return the max number of services
***************************************************************************/
int lp_numservices(void)
{
@@ -854,17 +764,17 @@ int lp_numservices(void)
}
/***************************************************************************
* Return the number of the service with the given name, or -1 if it doesn't
* exist. Note that this is a DIFFERENT ANIMAL from the internal function
* getservicebyname()! This works ONLY if all services have been loaded, and
* does not copy the found service.
Return the number of the service with the given name, or -1 if it doesn't
exist. Note that this is a DIFFERENT ANIMAL from the internal function
getservicebyname()! This works ONLY if all services have been loaded, and
does not copy the found service.
***************************************************************************/
int lp_number(char *name)
{
int iService;
for (iService = iNumServices - 1; iService >= 0; iService--)
if (strcmp(lp_name(iService), name) == 0)
if (strequal(lp_name(iService), name))
break;
return (iService);

955
log.c
View File

File diff suppressed because it is too large Load Diff

1707
main.c
View File

File diff suppressed because it is too large Load Diff

470
match.c
View File

@@ -1,302 +1,244 @@
/*
* Block matching used by the file-transfer code.
*
* Copyright (C) 1996 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2003-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
/*
Copyright (C) Andrew Tridgell 1996
Copyright (C) Paul Mackerras 1996
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"
extern int verbose;
extern int do_progress;
extern int checksum_seed;
extern int append_mode;
extern int csum_length;
int updating_basis_file;
extern int verbose;
extern int am_server;
extern int remote_version;
typedef unsigned short tag;
#define TABLESIZE (1<<16)
#define NULL_TAG (-1)
static int false_alarms;
static int hash_hits;
static int tag_hits;
static int matches;
static int64 data_transfer;
static int total_false_alarms;
static int total_hash_hits;
static int total_tag_hits;
static int total_matches;
extern struct stats stats;
#define TRADITIONAL_TABLESIZE (1<<16)
struct target {
tag t;
int i;
};
static uint32 tablesize;
static int32 *hash_table;
static struct target *targets;
#define SUM2HASH2(s1,s2) (((s1) + (s2)) & 0xFFFF)
#define SUM2HASH(sum) SUM2HASH2((sum)&0xFFFF,(sum)>>16)
static int *tag_table;
#define gettag2(s1,s2) (((s1) + (s2)) & 0xFFFF)
#define gettag(sum) gettag2((sum)&0xFFFF,(sum)>>16)
static int compare_targets(struct target *t1,struct target *t2)
{
return((int)t1->t - (int)t2->t);
}
#define BIG_SUM2HASH(sum) ((sum)%tablesize)
static void build_hash_table(struct sum_struct *s)
{
static uint32 alloc_size;
int32 i;
int i;
/* Dynamically calculate the hash table size so that the hash load
* for big files is about 80%. A number greater than the traditional
* size must be odd or s2 will not be able to span the entire set. */
tablesize = (uint32)(s->count/8) * 10 + 11;
if (tablesize < TRADITIONAL_TABLESIZE)
tablesize = TRADITIONAL_TABLESIZE;
if (tablesize > alloc_size || tablesize < alloc_size - 16*1024) {
if (hash_table)
free(hash_table);
hash_table = new_array(int32, tablesize);
if (!hash_table)
out_of_memory("build_hash_table");
alloc_size = tablesize;
}
if (!tag_table)
tag_table = (int *)malloc(sizeof(tag_table[0])*TABLESIZE);
memset(hash_table, 0xFF, tablesize * sizeof hash_table[0]);
targets = (struct target *)malloc(sizeof(targets[0])*s->count);
if (!tag_table || !targets)
out_of_memory("build_hash_table");
if (tablesize == TRADITIONAL_TABLESIZE) {
for (i = 0; i < s->count; i++) {
uint32 t = SUM2HASH(s->sums[i].sum1);
s->sums[i].chain = hash_table[t];
hash_table[t] = i;
}
} else {
for (i = 0; i < s->count; i++) {
uint32 t = BIG_SUM2HASH(s->sums[i].sum1);
s->sums[i].chain = hash_table[t];
hash_table[t] = i;
}
}
for (i=0;i<s->count;i++) {
targets[i].i = i;
targets[i].t = gettag(s->sums[i].sum1);
}
qsort(targets,s->count,sizeof(targets[0]),(int (*)())compare_targets);
for (i=0;i<TABLESIZE;i++)
tag_table[i] = NULL_TAG;
for (i=s->count-1;i>=0;i--) {
tag_table[targets[i].t] = i;
}
}
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, int32 i)
static void matched(int f,struct sum_struct *s,struct map_struct *buf,
OFF_T offset,int i)
{
int32 n = (int32)(offset - last_match); /* max value: block_size (int32) */
int32 j;
OFF_T n = offset - last_match;
OFF_T j;
if (verbose > 2 && i >= 0) {
rprintf(FINFO,
"match at %.0f last_match=%.0f j=%d len=%ld n=%ld\n",
(double)offset, (double)last_match, i,
(long)s->sums[i].len, (long)n);
}
if (verbose > 2 && i >= 0)
rprintf(FINFO,"match at %.0f last_match=%.0f j=%d len=%d n=%.0f\n",
(double)offset,(double)last_match,i,s->sums[i].len,(double)n);
send_token(f, i, buf, last_match, n, i < 0 ? 0 : s->sums[i].len);
send_token(f,i,buf,last_match,n,i<0?0:s->sums[i].len);
data_transfer += n;
if (i >= 0) {
stats.matched_data += s->sums[i].len;
n += s->sums[i].len;
}
for (j = 0; j < n; j += CHUNK_SIZE) {
int32 n1 = MIN(CHUNK_SIZE, n - j);
sum_update(map_ptr(buf, last_match + j, n1), n1);
for (j=0;j<n;j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,n-j);
sum_update(map_ptr(buf,last_match+j,n1),n1);
}
if (i >= 0)
last_match = offset + s->sums[i].len;
else
last_match = offset;
if (buf && do_progress)
if (buf) {
show_progress(last_match, buf->file_size);
if (i == -1) end_progress(buf->file_size);
}
}
static void hash_search(int f,struct sum_struct *s,
struct map_struct *buf, OFF_T len)
struct map_struct *buf,OFF_T len)
{
OFF_T offset, end;
int32 k, want_i, backup;
int j,k, last_i;
char sum2[SUM_LENGTH];
uint32 s1, s2, sum;
int more;
uint32 s1, s2, sum;
schar *map;
/* want_i is used to encourage adjacent matches, allowing the RLL
* coding of the output to work more efficiently. */
want_i = 0;
/* last_i is used to encourage adjacent matches, allowing the RLL coding of the
output to work more efficiently */
last_i = -1;
if (verbose > 2) {
rprintf(FINFO, "hash search b=%ld len=%.0f\n",
(long)s->blength, (double)len);
}
k = (int32)MIN(len, (OFF_T)s->blength);
map = (schar *)map_ptr(buf, 0, k);
if (verbose > 2)
rprintf(FINFO,"hash search b=%d len=%.0f\n",s->n,(double)len);
k = MIN(len, s->n);
map = (schar *)map_ptr(buf,0,k);
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
if (verbose > 3)
rprintf(FINFO, "sum=%.8x k=%ld\n", sum, (long)k);
rprintf(FINFO, "sum=%.8x k=%d\n", sum, k);
offset = 0;
end = len + 1 - s->sums[s->count-1].len;
if (verbose > 3) {
rprintf(FINFO, "hash search s->blength=%ld len=%.0f count=%.0f\n",
(long)s->blength, (double)len, (double)s->count);
}
if (verbose > 3)
rprintf(FINFO,"hash search s->n=%d len=%.0f count=%d\n",
s->n,(double)len,s->count);
do {
tag t = gettag2(s1,s2);
int done_csum2 = 0;
int32 i;
if (verbose > 4) {
rprintf(FINFO, "offset=%.0f sum=%04x%04x\n",
(double)offset, s2 & 0xFFFF, s1 & 0xFFFF);
j = tag_table[t];
if (verbose > 4)
rprintf(FINFO,"offset=%.0f sum=%08x\n",(double)offset,sum);
if (j == NULL_TAG) {
goto null_tag;
}
if (tablesize == TRADITIONAL_TABLESIZE) {
if ((i = hash_table[SUM2HASH2(s1,s2)]) < 0)
goto null_hash;
sum = (s1 & 0xffff) | (s2 << 16);
} else {
sum = (s1 & 0xffff) | (s2 << 16);
if ((i = hash_table[BIG_SUM2HASH(sum)]) < 0)
goto null_hash;
}
hash_hits++;
do {
int32 l;
if (sum != s->sums[i].sum1)
continue;
sum = (s1 & 0xffff) | (s2 << 16);
tag_hits++;
for (; j<s->count && targets[j].t == t; j++) {
int l, i = targets[j].i;
if (sum != s->sums[i].sum1) continue;
/* also make sure the two blocks are the same length */
l = (int32)MIN((OFF_T)s->blength, len-offset);
if (l != s->sums[i].len)
continue;
/* in-place: ensure chunk's offset is either >= our
* offset or that the data didn't move. */
if (updating_basis_file && s->sums[i].offset < offset
&& !(s->sums[i].flags & SUMFLG_SAME_OFFSET))
continue;
if (verbose > 3) {
rprintf(FINFO,
"potential match at %.0f i=%ld sum=%08x\n",
(double)offset, (long)i, sum);
}
l = MIN(s->n,len-offset);
if (l != s->sums[i].len) continue;
if (verbose > 3)
rprintf(FINFO,"potential match at %.0f target=%d %d sum=%08x\n",
(double)offset,j,i,sum);
if (!done_csum2) {
map = (schar *)map_ptr(buf,offset,l);
get_checksum2((char *)map,l,sum2);
done_csum2 = 1;
}
if (memcmp(sum2,s->sums[i].sum2,s->s2length) != 0) {
if (memcmp(sum2,s->sums[i].sum2,csum_length) != 0) {
false_alarms++;
continue;
}
/* When updating in-place, the best possible match is
* one with an identical offset, so we prefer that over
* the following want_i optimization. */
if (updating_basis_file) {
int32 i2;
for (i2 = i; i2 >= 0; i2 = s->sums[i2].chain) {
if (s->sums[i2].offset != offset)
continue;
if (i2 != i) {
if (sum != s->sums[i2].sum1)
break;
if (memcmp(sum2, s->sums[i2].sum2,
s->s2length) != 0)
break;
i = i2;
}
/* This chunk was at the same offset on
* both the sender and the receiver. */
s->sums[i].flags |= SUMFLG_SAME_OFFSET;
goto set_want_i;
/* we've found a match, but now check to see
if last_i can hint at a better match */
for (j++; j<s->count && targets[j].t == t; j++) {
int i2 = targets[j].i;
if (i2 == last_i + 1) {
if (sum != s->sums[i2].sum1) break;
if (memcmp(sum2,s->sums[i2].sum2,csum_length) != 0) break;
/* we've found an adjacent match - the RLL coder
will be happy */
i = i2;
break;
}
}
/* we've found a match, but now check to see
* if want_i can hint at a better match. */
if (i != want_i && want_i < s->count
&& (!updating_basis_file || s->sums[want_i].offset >= offset
|| s->sums[want_i].flags & SUMFLG_SAME_OFFSET)
&& sum == s->sums[want_i].sum1
&& memcmp(sum2, s->sums[want_i].sum2, s->s2length) == 0) {
/* we've found an adjacent match - the RLL coder
* will be happy */
i = want_i;
}
set_want_i:
want_i = i + 1;
last_i = i;
matched(f,s,buf,offset,i);
offset += s->sums[i].len - 1;
k = (int32)MIN((OFF_T)s->blength, len-offset);
map = (schar *)map_ptr(buf, offset, k);
k = MIN((len-offset), s->n);
map = (schar *)map_ptr(buf,offset,k);
sum = get_checksum1((char *)map, k);
s1 = sum & 0xFFFF;
s2 = sum >> 16;
matches++;
break;
} while ((i = s->sums[i].chain) >= 0);
null_hash:
backup = (int32)(offset - last_match);
/* We sometimes read 1 byte prior to last_match... */
if (backup < 0)
backup = 0;
}
null_tag:
/* Trim off the first byte from the checksum */
more = offset + k < len;
map = (schar *)map_ptr(buf, offset - backup, k + more + backup)
+ backup;
map = (schar *)map_ptr(buf,offset,k+1);
s1 -= map[0] + CHAR_OFFSET;
s2 -= k * (map[0]+CHAR_OFFSET);
/* Add on the next byte (if there is one) to the checksum */
if (more) {
s1 += map[k] + CHAR_OFFSET;
if (k < (len-offset)) {
s1 += (map[k]+CHAR_OFFSET);
s2 += s1;
} else
} else {
--k;
}
/* By matching early we avoid re-reading the
data 3 times in the case where a token
@@ -304,95 +246,70 @@ static void hash_search(int f,struct sum_struct *s,
match. The 3 reads are caused by the
running match, the checksum update and the
literal send. */
if (backup >= s->blength+CHUNK_SIZE && end-offset > CHUNK_SIZE)
matched(f, s, buf, offset - s->blength, -2);
if (offset-last_match >= CHUNK_SIZE+s->n &&
(end-offset > CHUNK_SIZE)) {
matched(f,s,buf,offset - s->n, -2);
}
} while (++offset < end);
matched(f, s, buf, len, -1);
map_ptr(buf, len-1, 1);
matched(f,s,buf,len,-1);
map_ptr(buf,len-1,1);
}
/**
* 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)
void match_sums(int f,struct sum_struct *s,struct map_struct *buf,OFF_T len)
{
char file_sum[MAX_DIGEST_LEN];
int sum_len;
char file_sum[MD4_SUM_LENGTH];
extern int write_batch; /* dw */
last_match = 0;
false_alarms = 0;
hash_hits = 0;
matches = 0;
data_transfer = 0;
tag_hits = 0;
matches=0;
data_transfer=0;
sum_init(checksum_seed);
sum_init();
if (append_mode > 0) {
if (append_mode == 2) {
OFF_T j = 0;
for (j = CHUNK_SIZE; j < s->flength; j += CHUNK_SIZE) {
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, CHUNK_SIZE),
CHUNK_SIZE);
last_match = j;
}
if (last_match < s->flength) {
int32 n = (int32)(s->flength - last_match);
if (buf && do_progress)
show_progress(last_match, buf->file_size);
sum_update(map_ptr(buf, last_match, n), n);
}
}
last_match = s->flength;
s->count = 0;
}
if (len > 0 && s->count > 0) {
if (len > 0 && s->count>0) {
build_hash_table(s);
if (verbose > 2)
if (verbose > 2)
rprintf(FINFO,"built hash table\n");
hash_search(f, s, buf, len);
if (verbose > 2)
hash_search(f,s,buf,len);
if (verbose > 2)
rprintf(FINFO,"done hash search\n");
} else {
OFF_T j;
/* by doing this in pieces we avoid too many seeks */
for (j = last_match + CHUNK_SIZE; j < len; j += CHUNK_SIZE)
matched(f, s, buf, j, -2);
matched(f, s, buf, len, -1);
for (j=0;j<(len-CHUNK_SIZE);j+=CHUNK_SIZE) {
int n1 = MIN(CHUNK_SIZE,(len-CHUNK_SIZE)-j);
matched(f,s,buf,j+n1,-2);
}
matched(f,s,buf,len,-1);
}
sum_len = sum_end(file_sum);
/* If we had a read error, send a bad checksum. */
if (buf && buf->status != 0)
file_sum[0]++;
sum_end(file_sum);
if (remote_version >= 14) {
if (verbose > 2)
rprintf(FINFO,"sending file_sum\n");
write_buf(f,file_sum,MD4_SUM_LENGTH);
if (write_batch) /* dw */
write_batch_delta_file(file_sum, MD4_SUM_LENGTH);
}
if (targets) {
free(targets);
targets=NULL;
}
if (verbose > 2)
rprintf(FINFO,"sending file_sum\n");
write_buf(f, file_sum, sum_len);
if (verbose > 2)
rprintf(FINFO, "false_alarms=%d hash_hits=%d matches=%d\n",
false_alarms, hash_hits, matches);
total_hash_hits += hash_hits;
rprintf(FINFO, "false_alarms=%d tag_hits=%d matches=%d\n",
false_alarms, tag_hits, matches);
total_tag_hits += tag_hits;
total_false_alarms += false_alarms;
total_matches += matches;
stats.literal_data += data_transfer;
@@ -404,7 +321,8 @@ void match_report(void)
return;
rprintf(FINFO,
"total: matches=%d hash_hits=%d false_alarms=%d data=%.0f\n",
total_matches, total_hash_hits, total_false_alarms,
"total: matches=%d tag_hits=%d false_alarms=%d data=%.0f\n",
total_matches,total_tag_hits,
total_false_alarms,
(double)stats.literal_data);
}

76
mkproto.awk Normal file
View File

@@ -0,0 +1,76 @@
# generate prototypes for Samba C code
# tridge, June 1996
BEGIN {
inheader=0;
print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
print ""
}
{
if (inheader) {
if (match($0,"[)][ \t]*$")) {
inheader = 0;
printf "%s;\n",$0;
} else {
printf "%s\n",$0;
}
next;
}
}
/^FN_LOCAL_BOOL/ {
split($0,a,"[,()]")
printf "BOOL %s(int );\n", a[2]
}
/^FN_LOCAL_STRING/ {
split($0,a,"[,()]")
printf "char *%s(int );\n", a[2]
}
/^FN_LOCAL_INT/ {
split($0,a,"[,()]")
printf "int %s(int );\n", a[2]
}
/^FN_LOCAL_CHAR/ {
split($0,a,"[,()]")
printf "char %s(int );\n", a[2]
}
/^FN_GLOBAL_BOOL/ {
split($0,a,"[,()]")
printf "BOOL %s(void);\n", a[2]
}
/^FN_GLOBAL_STRING/ {
split($0,a,"[,()]")
printf "char *%s(void);\n", a[2]
}
/^FN_GLOBAL_INT/ {
split($0,a,"[,()]")
printf "int %s(void);\n", a[2]
}
/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
next;
}
!/^OFF_T|^size_t|^off_t|^pid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time/ {
next;
}
/[(].*[)][ \t]*$/ {
printf "%s;\n",$0;
next;
}
/[(]/ {
inheader=1;
printf "%s\n",$0;
next;
}

View File

@@ -1,48 +0,0 @@
# generate prototypes for rsync
$old_protos = '';
if (open(IN, 'proto.h')) {
$old_protos = join('', <IN>);
close IN;
}
%FN_MAP = (
BOOL => 'BOOL ',
CHAR => 'char ',
INTEGER => 'int ',
STRING => 'char *',
);
$inheader = 0;
$protos = qq|/* This file is automatically generated with "make proto". DO NOT EDIT */\n\n|;
while (<>) {
if ($inheader) {
if (/[)][ \t]*$/) {
$inheader = 0;
s/$/;/;
}
$protos .= $_;
} elsif (/^FN_(LOCAL|GLOBAL)_([^(]+)\(([^,()]+)/) {
$ret = $FN_MAP{$2};
$func = $3;
$arg = $1 eq 'LOCAL' ? 'int module_id' : 'void';
$protos .= "$ret$func($arg);\n";
} elsif (/^static|^extern/ || /[;]/ || !/^[A-Za-z][A-Za-z0-9_]* /) {
;
} elsif (/[(].*[)][ \t]*$/) {
s/$/;/;
$protos .= $_;
} elsif (/[(]/) {
$inheader = 1;
$protos .= $_;
}
}
if ($old_protos ne $protos) {
open(OUT, '>proto.h') or die $!;
print OUT $protos;
close OUT;
}
open(OUT, '>proto.h-tstamp') and close OUT;

2350
options.c
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +0,0 @@
#!/bin/sh -e
# This script gets git to run gpg with a --passphrase-file option.
PATH=`echo $PATH | sed 's/^[^:]*://'`
gpg --batch --passphrase-file=$GPG_PASSFILE "${@}"

View File

@@ -1,70 +0,0 @@
#!/usr/bin/perl
# This script outputs some perl code that parses all possible options
# that the code in options.c might send to the server. This perl code
# is included in the rrsync script.
use strict;
our %short_no_arg;
our %short_with_num;
our %long_opt = (
'no-i-r' => 0,
'fake-super' => 0,
'log-file' => 3,
);
our $last_long_opt;
open(IN, '../options.c') or die "Unable to open ../options.c: $!\n";
while (<IN>) {
if (/\Qargstr[x++]\E = '([^.ie])'/) {
$short_no_arg{$1} = 1;
undef $last_long_opt;
} elsif (/\Qasprintf(\E[^,]+, "-([a-zA-Z0-9])\%l?[ud]"/) {
$short_with_num{$1} = 1;
undef $last_long_opt;
} elsif (/\Qargs[ac++]\E = "--([^"=]+)"/) {
$last_long_opt = $1;
$long_opt{$1} = 0;
} elsif (defined($last_long_opt)
&& /\Qargs[ac++]\E = ([^["\s]+);/ && $1 ne 'dest_option') {
$long_opt{$last_long_opt} = 2;
undef $last_long_opt;
} elsif (/dest_option = "--([^"]+)"/) {
$long_opt{$1} = 2;
undef $last_long_opt;
} elsif (/\Qasprintf(\E[^,]+, "--([^"=]+)=/ || /\Qargs[ac++]\E = "--([^"=]+)=/) {
$long_opt{$1} = 1;
undef $last_long_opt;
}
}
close IN;
my $short_no_arg = join('', sort keys %short_no_arg);
my $short_with_num = join('', sort keys %short_with_num);
print <<EOT;
# These options are the only options that rsync might send to the server,
# and only in the option format that the stock rsync produces.
# To disable a short-named option, add its letter to this string:
our \$short_disabled = 's';
our \$short_no_arg = '$short_no_arg'; # DO NOT REMOVE ANY
our \$short_with_num = '$short_with_num'; # DO NOT REMOVE ANY
# To disable a long-named option, change its value to a -1. The values mean:
# 0 = the option has no arg; 1 = the arg doesn't need any checking; 2 = only
# check the arg when receiving; and 3 = always check the arg.
our \%long_opt = (
EOT
foreach my $opt (sort keys %long_opt) {
my $val = $long_opt{$opt};
$val = 1 if $opt =~ /^(max-|min-)/;
$val = 3 if $opt eq 'files-from';
$val = '$ro ? -1 : ' . $val if $opt =~ /^remove-/;
print " '$opt' => $val,\n";
}
print ");\n\n";

View File

@@ -1,18 +0,0 @@
#!/usr/bin/perl
# This script finds extraneous "extern" variables in the *.c files.
# Run it from inside the main rsync directory.
use strict;
my @files = glob('*.c');
foreach my $fn (@files) {
open(IN, '<', $fn) or die;
undef $/; $_ = <IN>; $/ = "\n";
close IN;
my @externs = /^extern .*?([^[\s(*;&.]+)(?:\[.*?\])?;/mg;
foreach my $find (@externs) {
my @matches = /(?<!\sstruct )\b(\Q$find\E)\b/g;
print $fn, ': ', $find, "\n" if @matches == 1;
}
}

View File

@@ -1,74 +1,84 @@
Summary: A fast, versatile, remote (and local) file-copying tool
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 3.0.2
%define fullversion %{version}
Version: 2.5.1
Release: 1
%define srcdir src
Group: Applications/Internet
Source0: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-%{fullversion}.tar.gz
#Source1: http://rsync.samba.org/ftp/rsync/%{srcdir}/rsync-patches-%{fullversion}.tar.gz
URL: http://rsync.samba.org/
Prefix: %{_prefix}
BuildRoot: /var/tmp/%{name}-root
License: GPL
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
Rsync is a fast and extraordinarily versatile file copying tool. It can
copy locally, to/from another host over any remote shell, or to/from a
remote rsync daemon. It offers a large number of options that control
every aspect of its behavior and permit very flexible specification of the
set of files to be copied. It is famous for its delta-transfer algorithm,
which reduces the amount of data sent over the network by sending only the
differences between the source files and the existing files in the
destination. Rsync is widely used for backups and mirroring and as an
improved copy command for everyday use.
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
Changed target paths to be Linux Standards Base compliant
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
# Choose one -- setup source only, or setup source + rsync-patches:
%setup -q -n rsync-%{fullversion}
#%setup -q -b1 -n rsync-%{fullversion}
# If you you used "%setup -q -b1", choose the patches you wish to apply:
#patch -p1 <patches/acls.diff
#patch -p1 <patches/xattrs.diff
#patch -p1 <patches/remote-option.diff
#patch -p1 <patches/db.diff
# Avoid extra perl dependencies for scripts going into doc dir.
chmod -x support/*
%setup
%build
#./prepare-source
%configure
make
./configure --prefix=/usr --mandir=/usr/share/man
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
rm -rf $RPM_BUILD_ROOT
%makeinstall
mkdir -p $RPM_BUILD_ROOT/etc/xinetd.d
install -m 644 packaging/lsb/rsync.xinetd $RPM_BUILD_ROOT/etc/xinetd.d/rsync
#install -p -m 755 support/rsyncdb $RPM_BUILD_ROOT/usr/bin/rsyncdb
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc COPYING NEWS OLDNEWS README support/ tech_report.tex
%config(noreplace) /etc/xinetd.d/rsync
%{_prefix}/bin/rsync*
%{_mandir}/man1/rsync.1*
%{_mandir}/man5/rsyncd.conf.5*
%changelog
* Tue Apr 08 2008 Wayne Davison <wayned@samba.org>
Released 3.0.2.
* Fri Mar 21 2008 Wayne Davison <wayned@samba.org>
Added installation of /etc/xinetd.d/rsync file and some commented-out
lines that demonstrate how to use the rsync-patches tar file.
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/share/man/man1/rsync.1
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -0,0 +1,84 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Sept 11 2000 John H Terpstra <jht@turbolinux.com>
Changed target paths to be Linux Standards Base compliant
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr --mandir=/usr/share/man
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,share/man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/share/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/share/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/share/man/man1/rsync.1
%attr(-,root,root) /usr/share/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -1,13 +0,0 @@
# default: off
# description: The rsync server is a good addition to an ftp server, as it
# allows crc checksumming etc.
service rsync
{
disable = yes
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
log_on_failure += USERID
}

View File

@@ -1,121 +0,0 @@
#!/usr/bin/perl
use strict;
# This script expects the directory ~/samba-rsync-ftp to exist and to be a
# copy of the /home/ftp/pub/rsync dir on samba.org. It also requires a
# pristine CVS checkout of rsync (don't use your normal rsync build dir
# unless you're 100% sure that there are not unchecked-in changes).
#
# If this is run with -ctu, it will make an updated "nightly" tar file in
# the nightly dir. It will also remove any old tar files, regenerate the
# HTML man pages in the nightly dir, and then rsync the changes to the
# samba.org server.
use Getopt::Long;
use Date::Format;
# Where the local copy of /home/ftp/pub/rsync/dev/nightly should be updated.
our $dest = $ENV{HOME} . '/samba-rsync-ftp/dev/nightly';
our $nightly_symlink = "$dest/rsync-HEAD.tar.gz";
our($make_tar, $upload, $help_opt);
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'make-tar|t' => \$make_tar,
'upload|u' => \$upload,
'help|h' => \$help_opt,
) || $help_opt;
our $name = time2str('rsync-HEAD-%Y%m%d-%H%M%Z', time, 'GMT');
our $ztoday = time2str('%d %b %Y', time);
our $today = $ztoday;
our $gen_target = $upload ? 'gensend' : 'gen';
die "$dest does not exist\n" unless -d $dest;
die "There is no .git dir in the current directory.\n" unless -d '.git';
die "There is no rsync checkout in the current directory.\n" unless -f 'rsyncd.conf.yo';
if ($make_tar) {
open(IN, '-|', 'git status') or die $!;
my $status = join('', <IN>);
close IN;
die "The checkout is not clean:\n", $status unless $status =~ /\nnothing to commit \(working directory clean\)/;
die "The checkout is not on the master branch.\n" unless $status =~ /^# On branch master\n/;
system "make $gen_target" and die "make $gen_target failed!\n";
my @extra_files;
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
while (<IN>) {
if (s/^GENFILES=//) {
while (s/\\$//) {
$_ .= <IN>;
}
@extra_files = split(' ', $_);
last;
}
}
close IN;
print "Creating $name.tar.gz\n";
system "rsync -a @extra_files $name/";
system "git archive --format=tar --prefix=$name/ HEAD | tar xf -";
system "support/git-set-file-times --prefix=$name/";
system "fakeroot tar czf $dest/$name.tar.gz $name; rm -rf $name";
unlink($nightly_symlink);
symlink("$name.tar.gz", $nightly_symlink);
}
foreach my $fn (qw( rsync.yo rsyncd.conf.yo )) {
my $yo_tmp = "$dest/$fn";
(my $html_fn = "$dest/$fn") =~ s/\.yo/.html/;
open(IN, '<', $fn) or die $!;
undef $/; $_ = <IN>; $/ = "\n";
close IN;
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m;
#s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m;
open(OUT, '>', $yo_tmp) or die $!;
print OUT $_;
close OUT;
system 'yodl2html', '-o', $html_fn, $yo_tmp;
unlink($yo_tmp);
}
chdir($dest) or die $!;
my $cnt = 0;
open(PIPE, '-|', 'ls -1t rsync-HEAD-*') or die $!;
while (<PIPE>) {
chomp;
next if $cnt++ < 10;
unlink($_);
}
close PIPE;
system 'ls -ltr';
if ($upload) {
my $opt = '';
if (defined $ENV{RSYNC_PARTIAL_DIR}) {
$opt = " -f 'R $ENV{RSYNC_PARTIAL_DIR}'";
}
system "rsync$opt -aviHP --delete-after . samba.org:/home/ftp/pub/rsync/dev/nightly";
}
exit;
sub usage
{
die <<EOT;
Usage: nightly-rsync [OPTIONS]
-t, --make-tar create a new tar file in $dest
-u, --upload upload the revised nightly dir to samba.org
-h, --help display this help
EOT
}

View File

@@ -1,213 +0,0 @@
#!/usr/bin/perl -w
# This script is used to turn one or more of the "patch/*" branches
# into one or more diffs in the "patches" directory. Pass the option
# --gen if you want generated files in the diffs. Pass the name of
# one or more diffs if you want to just update a subset of all the
# diffs.
use strict;
use Getopt::Long;
my $patches_dir = 'patches';
my $tmp_dir = "patches.$$";
&Getopt::Long::Configure('bundling');
&usage if !&GetOptions(
'skip-check' => \( my $skip_branch_check ),
'shell|s' => \( my $launch_shell ),
'gen:s' => \( my $incl_generated_files ),
'help|h' => \( my $help_opt ),
);
&usage if $help_opt;
if (defined $incl_generated_files) {
$patches_dir = $incl_generated_files if $incl_generated_files ne '';
$incl_generated_files = 1;
}
die "No '$patches_dir' directory was found.\n" unless -d $patches_dir;
die "No '.git' directory present in the current dir.\n" unless -d '.git';
my($status, $is_clean, $starting_branch) = &check_git_status;
if (!$skip_branch_check && !$is_clean) {
die "The checkout is not clean:\n", $status;
}
my @extra_files;
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
while (<IN>) {
if (s/^GENFILES=//) {
while (s/\\$//) {
$_ .= <IN>;
}
@extra_files = split(' ', $_);
last;
}
}
close IN;
if ($incl_generated_files) {
die "'$tmp_dir' must not exist in the current directory.\n" if -e $tmp_dir;
mkdir($tmp_dir, 0700) or die "Unable to mkdir($tmp_dir): $!\n";
system "./config.status Makefile && make gen && rsync -a @extra_files $tmp_dir/master/" and exit 1;
}
my $last_touch = time;
my(%patches, %local_patch);
# Start by finding all patches so that we can load all possible parents.
open(PIPE, '-|', 'git', 'branch', '-a') or die $!;
while (<PIPE>) {
if (m# origin/patch/(.*)#) {
$patches{$1} = 1;
} elsif (m# patch/(.*)#) {
$patches{$1} = $local_patch{$1} = 1;
}
}
close PIPE;
my @patches = sort keys %patches;
my(%parent, %description);
foreach my $patch (@patches) {
my $branch = ($local_patch{$patch} ? '' : 'origin/') . "patch/$patch";
my $desc = '';
open(PIPE, '-|', 'git', 'diff', '-U1000', "master...$branch", '--', "PATCH.$patch") or die $!;
while (<PIPE>) {
last if /^@@ /;
}
while (<PIPE>) {
next unless s/^[ +]//;
if (m#patch -p1 <patches/(\S+)\.diff# && $1 ne $patch) {
$parent{$patch} = $1;
}
$desc .= $_;
}
$description{$patch} = $desc;
}
if (@ARGV) {
# Limit the list of patches to actually process based on @ARGV.
@patches = ( );
foreach (@ARGV) {
s{^(patches|patch|origin/patch)/} {};
s{\.diff$} {};
push(@patches, $_);
}
}
my %completed;
foreach my $patch (@patches) {
next if $completed{$patch}++;
last unless update_patch($patch);
}
if ($incl_generated_files) {
system "rm -rf $tmp_dir";
}
sleep 1 if $last_touch == time;
system "git checkout $starting_branch" and exit 1;
exit;
sub update_patch
{
my($patch) = @_;
my $parent = $parent{$patch};
if (defined $parent) {
unless ($completed{$parent}++) {
update_patch($parent);
}
$parent = "patch/$parent";
} else {
$parent = 'master';
}
print "======== $patch ========\n";
sleep 1 if $incl_generated_files && $last_touch == time;
if ($local_patch{$patch}) {
system "git checkout patch/$patch" and return 0;
} else {
system "git checkout --track -b patch/$patch origin/patch/$patch" and return 0;
}
my $ok = system("git merge $parent") == 0;
if (!$ok || $launch_shell) {
print qq|"git merge $parent" incomplete -- please fix.\n| if !$ok;
$ENV{PS1} = "[$parent] patch/$patch: ";
while (1) {
if (system($ENV{SHELL}) != 0) {
print "Abort? [n/y] ";
$_ = <STDIN>;
next unless /^y/i;
return 0;
}
($status, $is_clean) = &check_git_status;
last if $is_clean;
print $status;
}
}
open(OUT, '>', "$patches_dir/$patch.diff") or die $!;
print OUT $description{$patch}, "\n";
if ($incl_generated_files) {
system "./config.status Makefile && make gen && rsync -a @extra_files $tmp_dir/$patch/";
}
$last_touch = time;
open(PIPE, '-|', 'git', 'diff', $parent) or die $!;
DIFF: while (<PIPE>) {
while (m{^diff --git a/PATCH}) {
while (<PIPE>) {
last if m{^diff --git a/};
}
last DIFF if !defined $_;
}
next if /^index /;
print OUT $_;
}
close PIPE;
if ($incl_generated_files) {
$parent =~ s#.*/##;
open(PIPE, '-|', 'diff', '-up', "$tmp_dir/$parent", "$tmp_dir/$patch") or die $!;
while (<PIPE>) {
s#^(diff -up) $tmp_dir/[^/]+/(.*?) $tmp_dir/[^/]+/(.*)#$1 a/$2 b/$3#o;
s#^\Q---\E $tmp_dir/[^/]+/([^\t]+)\t.*#--- a/$1#o;
s#^\Q+++\E $tmp_dir/[^/]+/([^\t]+)\t.*#+++ b/$1#o;
print OUT $_;
}
close PIPE;
}
close OUT;
1;
}
exit;
sub check_git_status
{
open(IN, '-|', 'git status') or die $!;
my $status = join('', <IN>);
close IN;
my $is_clean = $status =~ /\nnothing to commit \(working directory clean\)/;
my($starting_branch) = $status =~ /^# On branch (.+)\n/;
($status, $is_clean, $starting_branch);
}
sub usage
{
die <<EOT;
Usage: patch-update [OPTIONS]
--gen[=DIR] Include generated files. Optional dest DIR overrides "patches".
--skip-check Skip the check that ensures starting with a clean branch.
EOT
}

View File

@@ -0,0 +1,81 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -0,0 +1,81 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1 $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5 $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -0,0 +1,81 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: 2.5.1
Release: 1
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-2.5.1.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1*
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -0,0 +1,81 @@
Summary: Program for efficient remote updates of files.
Name: rsync
Version: PVERSION
Release: PRELEASE
Copyright: GPL
Group: Applications/Networking
Source: ftp://samba.anu.edu.au/pub/rsync/rsync-PVERSION.tar.gz
URL: http://samba.anu.edu.au/rsync/
Packager: Andrew Tridgell <tridge@samba.anu.edu.au>
BuildRoot: /tmp/rsync
%description
rsync is a replacement for rcp that has many more features.
rsync uses the "rsync algorithm" which provides a very fast method for
bringing remote files into sync. It does this by sending just the
differences in the files across the link, without requiring that both
sets of files are present at one of the ends of the link beforehand.
A technical report describing the rsync algorithm is included with
this package.
%changelog
* Mon Jan 25 1999 Stefan Hornburg <racke@linuxia.de>
quoted RPM_OPT_FLAGS for the sake of robustness
* Mon May 18 1998 Andrew Tridgell <tridge@samba.anu.edu.au>
reworked for auto-building when I release rsync (tridge@samba.anu.edu.au)
* Sat May 16 1998 John H Terpstra <jht@aquasoft.com.au>
Upgraded to Rsync 2.0.6
-new feature anonymous rsync
* Mon Apr 6 1998 Douglas N. Arnold <dna@math.psu.edu>
Upgrade to rsync version 1.7.2.
* Sun Mar 1 1998 Douglas N. Arnold <dna@math.psu.edu>
Built 1.6.9-1 based on the 1.6.3-2 spec file of John A. Martin.
Changes from 1.6.3-2 packaging: added latex and dvips commands
to create tech_report.ps.
* Mon Aug 25 1997 John A. Martin <jam@jamux.com>
Built 1.6.3-2 after finding no rsync-1.6.3-1.src.rpm although there
was an ftp://ftp.redhat.com/pub/contrib/alpha/rsync-1.6.3-1.alpha.rpm
showing no packager nor signature but giving
"Source RPM: rsync-1.6.3-1.src.rpm".
Changes from 1.6.2-1 packaging: added '$RPM_OPT_FLAGS' to make, strip
to '%build', removed '%prefix'.
* Thu Apr 10 1997 Michael De La Rue <miked@ed.ac.uk>
rsync-1.6.2-1 packaged. (This entry by jam to credit Michael for the
previous package(s).)
%prep
%setup
%build
./configure --prefix=/usr
make CFLAGS="$RPM_OPT_FLAGS"
strip rsync
%install
mkdir -p $RPM_BUILD_ROOT/usr/{bin,man/{man1,man5}}
install -m755 rsync $RPM_BUILD_ROOT/usr/bin
install -m644 rsync.1* $RPM_BUILD_ROOT/usr/man/man1
install -m644 rsyncd.conf.5* $RPM_BUILD_ROOT/usr/man/man5
%clean
rm -rf $RPM_BUILD_ROOT
%files
%attr(-,root,root) /usr/bin/rsync
%attr(-,root,root) /usr/man/man1/rsync.1*
%attr(-,root,root) /usr/man/man5/rsyncd.conf.5*
%attr(-,root,root) %doc tech_report.tex
%attr(-,root,root) %doc README
%attr(-,root,root) %doc COPYING

View File

@@ -1,345 +0,0 @@
#!/usr/bin/perl
use strict;
# This script expects the directory ~/samba-rsync-ftp to exist and to be a
# copy of the /home/ftp/pub/rsync dir on samba.org. When the script is done,
# the git repository in the current directory will be updated, and the local
# ~/samba-rsync-ftp dir will be ready to be rsynced to samba.org.
use Cwd;
use Term::ReadKey;
use Date::Format;
my $dest = $ENV{HOME} . '/samba-rsync-ftp';
my $passfile = $ENV{HOME} . '/.rsyncpass';
my $path = $ENV{PATH};
my $now = time;
my $cl_today = time2str('* %a %b %d %Y', $now);
my $year = time2str('%Y', $now);
my $ztoday = time2str('%d %b %Y', $now);
(my $today = $ztoday) =~ s/^0//;
my $curdir = Cwd::cwd;
END {
unlink($passfile);
}
my @extra_files;
open(IN, '<', 'Makefile.in') or die "Couldn't open Makefile.in: $!\n";
while (<IN>) {
if (s/^GENFILES=//) {
while (s/\\$//) {
$_ .= <IN>;
}
@extra_files = split(' ', $_);
last;
}
}
close IN;
my $break = <<EOT;
==========================================================================
EOT
print $break, <<EOT, $break, "\n";
== This will release a new version of rsync onto an unsuspecting world. ==
EOT
die "$dest does not exist\n" unless -d $dest;
die "There is no .git dir in the current directory.\n" unless -d '.git';
die "'a' must not exist in the current directory.\n" if -e 'a';
die "'b' must not exist in the current directory.\n" if -e 'b';
open(IN, '-|', 'git status') or die $!;
my $status = join('', <IN>);
close IN;
die "The checkout is not clean:\n", $status unless $status =~ /\nnothing to commit \(working directory clean\)/;
die "The checkout is not on the master branch.\n" unless $status =~ /^# On branch master\n/;
my $confversion;
open(IN, '<', 'configure.in') or die $!;
while (<IN>) {
if (/^RSYNC_VERSION=(.*)/) {
$confversion = $1;
last;
}
}
close IN;
die "Unable to find RSYNC_VERSION in configure.in\n" unless defined $confversion;
open(IN, '<', 'OLDNEWS') or die $!;
$_ = <IN>;
close IN;
my($lastversion) = /(\d+\.\d+\.\d+)/;
my $version = $confversion;
$version =~ s/dev/pre1/ || $version =~ s/pre(\d+)/ 'pre' . ($1 + 1) /e;
print "Please enter the version number of this release: [$version] ";
chomp($_ = <STDIN>);
if ($_ eq '.') {
$version =~ s/pre\d+//;
} elsif ($_ ne '') {
$version = $_;
}
die "Invalid version: `$version'\n" unless $version =~ /^[\d.]+(pre\d+)?$/;
if (`git tag -l v$version` ne '') {
print "Tag v$version already exists.\n\nDelete tag or quit? [q/del] ";
$_ = <STDIN>;
exit 1 unless /^del/i;
system "git tag -d v$version";
}
if ($version =~ s/[-.]*pre[-.]*/pre/ && $confversion !~ /dev$/) {
$lastversion = $confversion;
}
print "Enter the previous version to produce a patch against: [$lastversion] ";
chomp($_ = <STDIN>);
$lastversion = $_ if $_ ne '';
$lastversion =~ s/[-.]*pre[-.]*/pre/;
my $pre = $version =~ /(pre\d+)/ ? $1 : '';
my $release = $pre ? '0.1' : '1';
print "Please enter the RPM release number of this release: [$release] ";
chomp($_ = <STDIN>);
$release = $_ if $_ ne '';
$release .= ".$pre" if $pre;
my($srcdir,$srcdiffdir,$lastsrcdir,$skipping);
if ($lastversion =~ /pre/) {
if (!$pre) {
die "You should not diff a release version against a pre-release version.\n";
}
$srcdir = $srcdiffdir = $lastsrcdir = 'src-previews';
$skipping = ' ** SKIPPING **';
} elsif ($pre) {
$srcdir = $srcdiffdir = 'src-previews';
$lastsrcdir = 'src';
$skipping = ' ** SKIPPING **';
} else {
$srcdir = $lastsrcdir = 'src';
$srcdiffdir = 'src-diffs';
$skipping = '';
}
print "\n", $break, <<EOT;
\$version is "$version"
\$lastversion is "$lastversion"
\$dest is "$dest"
\$curdir is "$curdir"
\$srcdir is "$srcdir"
\$srcdiffdir is "$srcdiffdir"
\$lastsrcdir is "$lastsrcdir"
\$release is "$release"
About to:
- make sure that SUBPROTOCOL_VERSION is 0$skipping
- tweak the version in configure.in and the spec files
- tweak NEWS and OLDNEWS to update the release date$skipping
- tweak the date in the *.yo files and generate the manpages
- generate configure.sh, config.h.in, and proto.h
- page through the differences
EOT
print "<Press Enter to continue> ";
$_ = <STDIN>;
(my $finalversion = $version) =~ s/pre\d+//;
my %specvars = ( 'Version:' => $finalversion, 'Release:' => $release,
'%define fullversion' => "\%{version}$pre", 'Released' => "$version.",
'%define srcdir' => $srcdir );
my @tweak_files = ( glob('packaging/*.spec'), glob('packaging/*/*.spec'), glob('*.yo'),
qw( configure.in rsync.h NEWS OLDNEWS options.c ) );
foreach my $fn (@tweak_files) {
open(IN, '<', $fn) or die $!;
undef $/; $_ = <IN>; $/ = "\n";
close IN;
if ($fn =~ /configure/) {
s/^RSYNC_VERSION=.*/RSYNC_VERSION=$version/m
or die "Unable to update RSYNC_VERSION in $fn\n";
} elsif ($fn =~ /\.spec/) {
while (my($str, $val) = each %specvars) {
s/^\Q$str\E .*/$str $val/m
or die "Unable to update $str in $fn\n";
}
s/^\* \w\w\w \w\w\w \d\d \d\d\d\d (.*)/$cl_today $1/m
or die "Unable to update ChangeLog header in $fn\n";
} elsif ($fn =~ /\.yo/) {
s/^(manpage\([^)]+\)\(\d+\)\()[^)]+(\).*)/$1$today$2/m
or die "Unable to update date in manpage() header in $fn\n";
s/^(This man ?page is current for version) \S+ (of rsync)/$1 $version $2/m
or die "Unable to update current version info in $fn\n";
} elsif ($fn eq 'rsync.h') {
s/(#define\s+SUBPROTOCOL_VERSION)\s+\d+/$1 0/
or die "Unable to find SUBPROTOCOL_VERSION define in $fn\n";
next if $pre;
} elsif ($fn eq 'NEWS') {
s/^(NEWS for rsync \Q$finalversion\E) \(UNRELEASED\)\s*\n/$1 ($today)\n/mi
or die "The first line of $fn is not in the right format. It must be:\n"
. "NEWS for rsync $finalversion (UNRELEASED)\n";
next if $pre;
} elsif ($fn eq 'OLDNEWS') {
s/^\t\S\S\s\S\S\S\s\d\d\d\d(\t\Q$finalversion\E)/\t$ztoday$1/m
or die "Unable to find \"?? ??? $year\t$finalversion\" line in $fn\n";
next if $pre;
} elsif ($fn eq 'options.c') {
if (s/(Copyright \(C\) 2002-)(\d+)( Wayne Davison)/$1$year$3/
&& $2 ne $year) {
die "Copyright comments need to be updated to $year in all files!\n";
}
# Adjust the year in the --version output.
s/(rprintf\(f, "Copyright \(C\) 1996-)(\d+)/$1$year/
or die "Unable to find Copyright string in --version output of $fn\n";
next if $2 eq $year;
} else {
die "Unrecognized file in \@tweak_files: $fn\n";
}
open(OUT, '>', $fn) or die $!;
print OUT $_;
close OUT;
}
print $break;
system "git diff --color | less -p '^diff .*'";
my $srctar_name = "rsync-$version.tar.gz";
my $pattar_name = "rsync-patches-$version.tar.gz";
my $diff_name = "rsync-$lastversion-$version.diffs.gz";
my $srctar_file = "$dest/$srcdir/$srctar_name";
my $pattar_file = "$dest/$srcdir/$pattar_name";
my $diff_file = "$dest/$srcdiffdir/$diff_name";
my $news_file = "$dest/$srcdir/rsync-$version-NEWS";
my $lasttar_file = "$dest/$lastsrcdir/rsync-$lastversion.tar.gz";
print $break, <<EOT;
About to:
- commit all version changes
- merge the master branch into the patch/* branches
- update the files in the "patches" dir and OPTIONALLY
(if you type 'y') to launch a shell for each patch
EOT
print "<Press Enter OR 'y' to continue> ";
my $ans = <STDIN>;
system "git commit -a -m 'Preparing for release of $version'" and exit 1;
print "Updating files in \"patches\" dir ...\n";
system "packaging/patch-update";
if ($ans =~ /^y/i) {
print "\nVisiting all \"patch/*\" branches ...\n";
system "packaging/patch-update --shell";
}
print $break, <<EOT;
About to:
- create signed tag for this release: v$version
- create release diffs, "$diff_name"
- create release tar, "$srctar_name"
- generate rsync-$version/patches/* files
- create patches tar, "$pattar_name"
- update top-level README, *NEWS, TODO, and ChangeLog
- update top-level rsync*.html manpages
- gpg-sign the release files
- update hard-linked top-level release files$skipping
EOT
print "<Press Enter to continue> ";
$_ = <STDIN>;
my $passphrase;
while (1) {
ReadMode('noecho');
print "\nEnter your GPG pass-phrase: ";
chomp($passphrase = <STDIN>);
ReadMode(0);
print "\n";
# Briefly create a temp file with the passphrase for git's tagging use.
my $oldmask = umask 077;
unlink($passfile);
open(OUT, '>', $passfile) or die $!;
print OUT $passphrase, "\n";
close OUT;
umask $oldmask;
$ENV{'GPG_PASSFILE'} = $passfile;
# We want to use our passphrase-providing "gpg" script, so modify the PATH.
$ENV{PATH} = "packaging/bin:$path";
$_ = `git tag -s -m 'Version $version.' v$version 2>&1`;
$ENV{PATH} = $path;
unlink($passfile);
print $_;
next if /bad passphrase/;
last unless /failed/;
exit 1;
}
# Extract the generated files from the old tar.
@_ = @extra_files;
map { s#^#rsync-$lastversion/# } @_;
system "tar xzf $lasttar_file @_";
rename("rsync-$lastversion", 'a');
print "Creating $diff_file ...\n";
system "./config.status Makefile; make gen; rsync -a @extra_files b/";
my $sed_script = 's:^((---|\+\+\+) [ab]/[^\t]+)\t.*:\1:';
system "(git diff v$lastversion v$version; diff -upN a b | sed -r '$sed_script') | gzip -9 >$diff_file";
system "rm -rf a";
rename('b', "rsync-$version");
print "Creating $srctar_file ...\n";
system "git archive --format=tar --prefix=rsync-$version/ v$version | tar xf -";
system "support/git-set-file-times --prefix=rsync-$version/";
system "fakeroot tar czf $srctar_file rsync-$version; rm -rf rsync-$version";
print "Updating files in \"rsync-$version/patches\" dir ...\n";
mkdir("rsync-$version", 0755);
mkdir("rsync-$version/patches", 0755);
system "packaging/patch-update --skip-check --gen=rsync-$version/patches";
print "Creating $pattar_file ...\n";
system "fakeroot tar chzf $pattar_file rsync-$version/patches; rm -rf rsync-$version";
print "Updating the other files in $dest ...\n";
system "rsync -a README NEWS OLDNEWS TODO $dest";
unlink($news_file);
link("$dest/NEWS", $news_file);
system "git log --name-status | gzip -9 >$dest/ChangeLog.gz";
system "yodl2html -o $dest/rsync.html rsync.yo";
system "yodl2html -o $dest/rsyncd.conf.html rsyncd.conf.yo";
foreach my $fn ($srctar_file, $pattar_file, $diff_file) {
unlink("$fn.asc");
open(GPG, '|-', "gpg --batch --passphrase-fd=0 -ba $fn") or die $!;
print GPG $passphrase, "\n";
close GPG;
}
if (!$pre) {
system "rm $dest/rsync-*.gz $dest/rsync-*.asc $dest/rsync-*-NEWS $dest/src-previews/rsync-*diffs.gz*";
foreach my $fn ($srctar_file, "$srctar_file.asc",
$pattar_file, "$pattar_file.asc",
$diff_file, "$diff_file.asc", $news_file) {
(my $top_fn = $fn) =~ s#/src(-\w+)?/#/#;
link($fn, $top_fn);
}
}
print $break, <<'EOT';
Local changes are done. When you're satisfied, push the git repository
and rsync the release files. Remember to announce the release on *BOTH*
rsync-announce@lists.samba.org and rsync@lists.samba.org (and the web)!
EOT

View File

@@ -1,94 +0,0 @@
#!/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

View File

@@ -1,10 +1,10 @@
/* This modules is based on the params.c module from Samba, written by Karl Auer
and much modifed by Christopher Hertel. */
/*
This modules is based on the params.c module from Samba, written by Karl Auer
and much modifed by Christopher Hertel.
* 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 3 of the License, or
* 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,
@@ -12,11 +12,11 @@
* 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, visit the http://fsf.org website.
*/
/* -------------------------------------------------------------------------- **
* 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.
*
* -------------------------------------------------------------------------- **
*
* Module name: params
*
@@ -74,7 +74,6 @@
*/
#include "rsync.h"
#include "ifuncs.h"
/* -------------------------------------------------------------------------- **
* Constants...
@@ -165,7 +164,7 @@ static int Continuation( char *line, int pos )
*/
{
pos--;
while( pos >= 0 && isSpace(line + pos) )
while( (pos >= 0) && isspace(line[pos]) )
pos--;
return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
@@ -208,10 +207,10 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
if( i > (bSize - 2) )
{
bSize += BUFR_INC;
bufr = realloc_array( bufr, char, bSize );
bufr = Realloc( bufr, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s Memory re-allocation failure.", func);
rprintf(FERROR, "%s Memory re-allocation failure.", func);
return( False );
}
}
@@ -223,7 +222,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
bufr[end] = '\0';
if( 0 == end ) /* Don't allow an empty name. */
{
rprintf(FLOG, "%s Empty section name in configuration file.\n", func );
rprintf(FERROR, "%s Empty section name in configuration file.\n", func );
return( False );
}
if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */
@@ -236,7 +235,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
if( i < 0 )
{
bufr[end] = '\0';
rprintf(FLOG, "%s Badly formed line in configuration file: %s\n",
rprintf(FERROR, "%s Badly formed line in configuration file: %s\n",
func, bufr );
return( False );
}
@@ -261,7 +260,7 @@ static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
}
/* We arrive here if we've met the EOF before the closing bracket. */
rprintf(FLOG, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
rprintf(FERROR, "%s Unexpected EOF in the configuration file: %s\n", func, bufr );
return( False );
} /* Section */
@@ -302,10 +301,10 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Ensure there's space for next char. */
{
bSize += BUFR_INC;
bufr = realloc_array( bufr, char, bSize );
bufr = Realloc( bufr, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
return( False );
}
}
@@ -315,7 +314,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
case '=': /* Equal sign marks end of param name. */
if( 0 == end ) /* Don't allow an empty name. */
{
rprintf(FLOG, "%s Invalid parameter name in config. file.\n", func );
rprintf(FERROR, "%s Invalid parameter name in config. file.\n", func );
return( False );
}
bufr[end++] = '\0'; /* Mark end of string & advance. */
@@ -329,7 +328,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i < 0 )
{
bufr[end] = '\0';
rprintf(FLOG, "%s Ignoring badly formed line in configuration file: %s\n",
rprintf(FERROR, "%s Ignoring badly formed line in configuration file: %s\n",
func, bufr );
return( True );
}
@@ -340,7 +339,7 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
case '\0': /* Shouldn't have EOF within param name. */
case EOF:
bufr[i] = '\0';
rprintf(FLOG, "%s Unexpected end-of-file at: %s\n", func, bufr );
rprintf(FERROR, "%s Unexpected end-of-file at: %s\n", func, bufr );
return( True );
default:
@@ -367,10 +366,10 @@ static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
if( i > (bSize - 2) ) /* Make sure there's enough room. */
{
bSize += BUFR_INC;
bufr = realloc_array( bufr, char, bSize );
bufr = Realloc( bufr, bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s Memory re-allocation failure.", func) ;
rprintf(FERROR, "%s Memory re-allocation failure.", func) ;
return( False );
}
}
@@ -387,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(bufr[end]); end-- )
;
c = getc( InFile );
}
@@ -485,15 +484,15 @@ static FILE *OpenConfFile( char *FileName )
if( NULL == FileName || 0 == *FileName )
{
rprintf(FLOG, "%s No configuration filename specified.\n", func);
rprintf(FERROR,"%s No configuration filename specified.\n", func);
return( NULL );
}
OpenedFile = fopen( FileName, "r" );
if( NULL == OpenedFile )
{
rsyserr(FLOG, errno, "unable to open configuration file \"%s\"",
FileName);
rprintf(FERROR,"%s Unable to open configuration file \"%s\":\n\t%s\n",
func, FileName, strerror(errno));
}
return( OpenedFile );
@@ -531,10 +530,10 @@ BOOL pm_process( char *FileName,
else /* If we don't have a buffer */
{ /* allocate one, then parse, */
bSize = BUFR_INC; /* then free. */
bufr = new_array( char, bSize );
bufr = (char *)malloc( bSize );
if( NULL == bufr )
{
rprintf(FLOG, "%s memory allocation failure.\n", func);
rprintf(FERROR,"%s memory allocation failure.\n", func);
fclose(InFile);
return( False );
}
@@ -548,7 +547,7 @@ BOOL pm_process( char *FileName,
if( !result ) /* Generic failure. */
{
rprintf(FLOG, "%s Failed. Error returned from params.c:parse().\n", func);
rprintf(FERROR,"%s Failed. Error returned from params.c:parse().\n", func);
return( False );
}

169
pipe.c
View File

@@ -1,169 +0,0 @@
/*
* Routines used to setup various kinds of inter-process pipes.
*
* Copyright (C) 1996-2000 Andrew Tridgell
* Copyright (C) 1996 Paul Mackerras
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org>
* Copyright (C) 2004-2008 Wayne Davison
*
* 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 3 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, visit the http://fsf.org website.
*/
#include "rsync.h"
extern int am_sender;
extern int am_server;
extern int blocking_io;
extern int filesfrom_fd;
extern mode_t orig_umask;
extern char *logfile_name;
extern struct chmod_mode_struct *chmod_modes;
/**
* Create a child connected to us via its 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];
if (verbose >= 2)
print_child_argv("opening connection using:", command);
if (fd_pair(to_child_pipe) < 0 || fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
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) {
rsyserr(FERROR, errno, "Failed to dup/close");
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 > 0)
set_blocking(STDOUT_FILENO);
execvp(command[0], command);
rsyserr(FERROR, errno, "Failed to exec %s", command[0]);
exit_cleanup(RERR_IPC);
}
if (close(from_child_pipe[1]) < 0 || close(to_child_pipe[0]) < 0) {
rsyserr(FERROR, errno, "Failed to close");
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}
/* This function forks a child which calls child_main(). First,
* however, it has to establish communication paths to and from the
* newborn child. It creates two socket pairs -- one for writing to
* the child (from the parent) and one for reading from the child
* (writing to the parent). Since that's four socket ends, each
* process has to close the two ends it doesn't need. The remaining
* two socket ends are retained for reading and writing. In the
* child, the STDIN and STDOUT file descriptors refer to these
* sockets. In the parent, the function arguments f_in and f_out are
* set to refer to these sockets. */
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];
/* The parent process is always the sender for a local rsync. */
assert(am_sender);
if (fd_pair(to_child_pipe) < 0 ||
fd_pair(from_child_pipe) < 0) {
rsyserr(FERROR, errno, "pipe");
exit_cleanup(RERR_IPC);
}
pid = do_fork();
if (pid == -1) {
rsyserr(FERROR, errno, "fork");
exit_cleanup(RERR_IPC);
}
if (pid == 0) {
am_sender = 0;
am_server = 1;
filesfrom_fd = -1;
chmod_modes = NULL; /* Let the sending side handle this. */
/* Let the client side handle this. */
if (logfile_name) {
logfile_name = NULL;
logfile_close();
}
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) {
rsyserr(FERROR, errno, "Failed to dup/close");
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]);
#ifdef ICONV_CONST
setup_iconv();
#endif
child_main(argc, argv);
}
if (close(from_child_pipe[1]) < 0 ||
close(to_child_pipe[0]) < 0) {
rsyserr(FERROR, errno, "Failed to close");
exit_cleanup(RERR_IPC);
}
*f_in = from_child_pipe[0];
*f_out = to_child_pipe[1];
return pid;
}

9
popt/.cvsignore Normal file
View File

@@ -0,0 +1,9 @@
ID
Makefile
config.cache
config.h
config.log
config.status
dummy
rsync
zlib/dummy

View File

@@ -1,7 +1,4 @@
1.5 -> 1.6
- add ability to perform callbacks for every, not just first, match.
1.3 -> 1.5
1.3 ->
- heavy dose of const's
- poptParseArgvString() now NULL terminates the list

View File

@@ -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 parsing strings
4) popt provides convience functions for parsting strings
into argv[] style arrays
popt is used by rpm, the Red Hat install program, and many other Red Hat

View File

@@ -1,4 +0,0 @@
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.)

104
popt/config.log Normal file
View File

@@ -0,0 +1,104 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
configure:592: checking host system type
configure:613: checking target system type
configure:631: checking build system type
configure:665: checking for a BSD compatible install
configure:718: checking whether build environment is sane
configure:775: checking whether make sets ${MAKE}
configure:821: checking for working aclocal
configure:834: checking for working autoconf
configure:847: checking for working automake
configure:860: checking for working autoheader
configure:873: checking for working makeinfo
configure:891: checking for gcc
configure:1004: checking whether the C compiler (gcc ) works
configure:1020: gcc -o conftest conftest.c 1>&5
configure:1046: checking whether the C compiler (gcc ) is a cross-compiler
configure:1051: checking whether we are using GNU C
configure:1079: checking whether gcc accepts -g
configure:1111: checking for POSIXized ISC
configure:1135: checking for gcc
configure:1248: checking whether the C compiler (gcc -g -O2 ) works
configure:1264: gcc -o conftest -g -O2 conftest.c 1>&5
configure:1290: checking whether the C compiler (gcc -g -O2 ) is a cross-compiler
configure:1295: checking whether we are using GNU C
configure:1323: checking whether gcc accepts -g
configure:1355: checking how to run the C preprocessor
configure:1436: checking whether gcc needs -traditional
configure:1485: checking for gcc option to accept ANSI C
configure:1564: checking for function prototypes
configure:1795: checking for ranlib
configure:1834: checking for ld used by GCC
configure:1896: checking if the linker (/usr/bin/ld) is GNU ld
configure:1912: checking for BSD-compatible nm
configure:1948: checking whether ln -s works
ltconfig:603: checking for object suffix
ltconfig:604: gcc -c -g -O2 conftest.c 1>&5
ltconfig:629: checking for executable suffix
ltconfig:630: gcc -o conftest -g -O2 conftest.c 1>&5
ltconfig:776: checking if gcc PIC flag -fPIC works
ltconfig:777: gcc -c -g -O2 -fPIC -DPIC conftest.c 1>&5
ltconfig:829: checking if gcc supports -c -o file.o
ltconfig:830: gcc -c -g -O2 -o out/conftest2.o conftest.c 1>&5
ltconfig:862: checking if gcc supports -c -o file.lo
ltconfig:863: gcc -c -g -O2 -c -o conftest.lo conftest.c 1>&5
ltconfig:914: checking if gcc supports -fno-rtti -fno-exceptions
ltconfig:915: gcc -c -g -O2 -fno-rtti -fno-exceptions -c conftest.c conftest.c 1>&5
ltconfig:958: checking if gcc static flag -static works
ltconfig:959: gcc -o conftest -g -O2 -static conftest.c 1>&5
GNU ld version 2.10.91 (with BFD 2.10.91.0.2)
ltconfig:1635: checking if global_symbol_pipe works
ltconfig:1636: gcc -c -g -O2 conftest.c 1>&5
ltconfig:1639: eval "/usr/bin/nm -B conftest.o | sed -n -e 's/^.*[ ]\([ABCDGISTW]\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' > conftest.nm"
ltconfig:1691: gcc -o conftest -g -O2 -fno-builtin -fno-rtti -fno-exceptions conftest.c conftstm.o 1>&5
configure:2150: checking for a BSD compatible install
configure:2231: checking for alloca.h
configure:2231: checking for libintl.h
configure:2231: checking for mcheck.h
configure:2231: checking for unistd.h
configure:2268: checking for /usr/ucblib in LIBS
configure:2284: checking for GNU xgettext
configure:2294: checking for strerror
configure:2294: checking for mtrace
configure:2347: checking for setreuid
configure:2438: checking for working const
configure:2513: checking for inline
configure:2553: checking for off_t
configure:2586: checking for size_t
configure:2621: checking for working alloca.h
configure:2654: checking for alloca
configure:2856: checking for unistd.h
configure:2895: checking for getpagesize
configure:2948: checking for working mmap
configure:3124: checking for argz.h
configure:3124: checking for limits.h
configure:3124: checking for locale.h
configure:3124: checking for nl_types.h
configure:3124: checking for malloc.h
configure:3124: checking for string.h
configure:3124: checking for unistd.h
configure:3124: checking for sys/param.h
configure:3164: checking for getcwd
configure:3164: checking for munmap
configure:3164: checking for putenv
configure:3164: checking for setenv
configure:3164: checking for setlocale
configure:3164: checking for strchr
configure:3164: checking for strcasecmp
configure:3164: checking for strdup
configure:3164: checking for __argz_count
configure:3164: checking for __argz_stringify
configure:3164: checking for __argz_next
configure:3283: checking for LC_MESSAGES
configure:3316: checking whether NLS is requested
configure:3336: checking whether included gettext is requested
configure:3355: checking for libintl.h
configure:3382: checking for gettext in libc
configure:3508: checking for msgfmt
configure:3542: checking for dcgettext
configure:3597: checking for gmsgfmt
configure:3633: checking for xgettext
configure:3673: gcc -o conftest -Wall -g -O2 conftest.c 1>&5
configure:4131: checking for catalogs to be installed

Some files were not shown because too many files have changed in this diff Show More