Initial commit.
This commit is contained in:
commit
3d641859e1
1
AUTHORS.zh-cn
Normal file
1
AUTHORS.zh-cn
Normal file
@ -0,0 +1 @@
|
|||||||
|
依玛猫 <imacat@mail.imacat.idv.tw>
|
1
AUTHORS.zh-tw
Normal file
1
AUTHORS.zh-tw
Normal file
@ -0,0 +1 @@
|
|||||||
|
依瑪貓 <imacat@mail.imacat.idv.tw>
|
674
COPYING
Normal file
674
COPYING
Normal file
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
14. Revised Versions 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
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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>
|
||||||
|
|
||||||
|
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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program 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".
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
|
||||||
|
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>.
|
133
ChangeLog
Normal file
133
ChangeLog
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
vsntp change log
|
||||||
|
|
||||||
|
2013-11-13
|
||||||
|
Does not work on x86_64 yet. Don't know whether it still works on i386.
|
||||||
|
I don't have i386 anymore.
|
||||||
|
1. vsntp.c: Removed the weird method to calculate the next time line
|
||||||
|
for synchronization. It was my bad taste to synchronize at the
|
||||||
|
the time of multiples of interval. When many clients are
|
||||||
|
synchronized to a same server, synchronizing them at a same time
|
||||||
|
will overload the server and create DDoS. Thanks to the reminder of
|
||||||
|
Steven Shen <fbishen@gmail.com>.
|
||||||
|
2. AUTHORS.zh-tw, INSTALL.zh-tw, NEWS.zh-tw, README.zh-tw, THANKS.zh-tw,
|
||||||
|
init.d/README.zh-tw: Converted from Big5 to UTF-8. I'm not woking
|
||||||
|
on Windows anymore. Big5 cause problem with gedit.
|
||||||
|
3. AUTHORS.zh-cn, INSTALL.zh-cn, NEWS.zh-cn, README.zh-cn, THANKS.zh-cn,
|
||||||
|
init.d/README.zh-cn: Converted from GB2312 to UTF-8. I'm not woking
|
||||||
|
on Windows anymore. GB2312 cause problem with gedit.
|
||||||
|
4. configure: Updated with GNU Autoconf 2.69.
|
||||||
|
|
||||||
|
2007-11-28
|
||||||
|
1. ChangeLog.zh-tw, ChangeLog.zh-cn: Removed.
|
||||||
|
2. COPYING.zh-tw, COPYING.zh-cn: Removed.
|
||||||
|
3. License updated to GPLv3.
|
||||||
|
4. Removed Traditional Chinese comments.
|
||||||
|
|
||||||
|
2004-03-29 version 2.0.0
|
||||||
|
1. vsntp.c: The syhchronization scheduler has been rewritten to
|
||||||
|
allow alternative schedulers, in order to work with the problem
|
||||||
|
reported by Jean-Alain Le Borgne <jalb@pobox.com> 2007-03-26,
|
||||||
|
that sleep() may not return after MS Virtual PC 2007 was suspended
|
||||||
|
for a while.
|
||||||
|
2. vsntp.c: An alternative schedular using alarm() was added in
|
||||||
|
addition to sleep(), based on the contribution by Jean-Alain.
|
||||||
|
3. vsntp.c: New subroutine setsigalrm() was added to set the SIGALRM
|
||||||
|
signal handler.
|
||||||
|
4. vsntp.c: New subroutine alarm_wakeup() was added as the alarm()
|
||||||
|
schedular.
|
||||||
|
5. vsntp.c: Two new constants SCHEDULER_SLEEP and SCHEDULER_ALARM were
|
||||||
|
added as the scheduler choices of the user.
|
||||||
|
6. vsntp.c: Two new switches -a/--alarm and -s/--sleep were added for
|
||||||
|
the user to choose the scheduler. The default is currently -s.
|
||||||
|
7. vsntp.c: New variable "scheduler" added to as the scheduler choice
|
||||||
|
of the user.
|
||||||
|
8. vsntp.c: Variable "next" was made global so that the alarm()
|
||||||
|
scheduler can access it, too.
|
||||||
|
9. vsntp.c: Check the return value of synctime() so that skip logging
|
||||||
|
when time was not adjusted (time correct or network error).
|
||||||
|
10. vsntp.c: Logging of time synchronization after the first time
|
||||||
|
was added, in log level LOG_DEBUG.
|
||||||
|
11. vsntp.c: errstart is now calculated and maintained in synctime()
|
||||||
|
instead of neterror(), in order to log the time sequence of the
|
||||||
|
network errors.
|
||||||
|
12. vsntp.c: Re-formatting error messages and warnings according to
|
||||||
|
the GNU Coding Standards, as:
|
||||||
|
source-file-name:lineno: message
|
||||||
|
Refer to: http://www.gnu.org/prep/standards/html_node/Errors.html
|
||||||
|
13. vsntp.c: Added logging before connect(), send() and recv() at
|
||||||
|
log level LOG_DEBUG in order to know the current progress when
|
||||||
|
debugging network problems.
|
||||||
|
14. vsntp.c: Added logging of value t1, t2, t3, t4 and toff in log
|
||||||
|
level LOG_DEBUG in order to debug time calculation problems.
|
||||||
|
15. vsntp.c: New subroutine xsigemptyset() was added to run
|
||||||
|
sigemptyset() and handle its error. setsigalrm() was updated
|
||||||
|
to use xsigemptyset() instead of sigemptyset().
|
||||||
|
16. vsntp.c: New subroutine xsigaction() was added to run sigaction()
|
||||||
|
and handle its error. setsigalrm() was updated to use xsigaction()
|
||||||
|
instead of sigaction().
|
||||||
|
17. vsntp.c: English comment fix. "... and handle errors" was updated
|
||||||
|
as "... and handle its error."
|
||||||
|
18. configure.ac: Added AC_TYPE_SSIZE_T, and added "alarm()" in
|
||||||
|
AC_CHECK_FUNCS, acccording to the suggestion by automake 1.9.6.
|
||||||
|
19. configure.in and aclocal.m4: Regenrated using automake 1.9.6.
|
||||||
|
20. configure: Regenrated using autoconf 2.61.
|
||||||
|
21. vsntp.c: Added conditional #ifdef, so that if alarm() is not
|
||||||
|
supported on the target platform the alarm() scheduler will not
|
||||||
|
be compiled.
|
||||||
|
22. vsntp.c: A new constant DEFAULT_SCHEDULER was added as the
|
||||||
|
default scheduler.
|
||||||
|
23. Added init.d directory, with a Debian SysV init script, a Red Hat
|
||||||
|
SysV init script, a configuration file used by the init scripts,
|
||||||
|
and README in 3 languages.
|
||||||
|
24. Added doc directory, and moved vsntp.texi, vsntp.8 and rfc1769.txt
|
||||||
|
inside.
|
||||||
|
25. vsntp.c: Fixed the basic profile in the beginning comment, from
|
||||||
|
synctime.c to vsntp.c. That was the first name of vsntp. It was
|
||||||
|
renamed for years.
|
||||||
|
26. vsntp.8: Fixed the BUGS chapter, replacing the originall text with
|
||||||
|
the SourceForge users' mailing list information.
|
||||||
|
27. README, vsntp.8 and vsntp.texi: Added notes about the scheduler
|
||||||
|
issue.
|
||||||
|
28. README, vsntp.8 and vsntp.texi: Added notes about how to debug.
|
||||||
|
29. README, vsntp.8 and vsntp.texi: Added notes about portability.
|
||||||
|
30. README, vsntp.8 and vsntp.texi: Added requests to users to let me
|
||||||
|
know that someone is using vsntp. :p
|
||||||
|
|
||||||
|
2004-01-14 version 1.1.1
|
||||||
|
Documentation fix.
|
||||||
|
1. ChangeLog and NEWS year typo fixed. (2003 -> 2004)
|
||||||
|
2. Home site at SourceForge done.
|
||||||
|
3. Documentation revised on official website, other reference
|
||||||
|
information.
|
||||||
|
4. Documentation revised on wordings and typos.
|
||||||
|
|
||||||
|
2004-01-13
|
||||||
|
1. HTML page at Tavern IMACAT's done.
|
||||||
|
2. texinfo document revised.
|
||||||
|
|
||||||
|
2004-01-12 version 1.1.0
|
||||||
|
First public release.
|
||||||
|
1. Added texinfo documentation.
|
||||||
|
2. Added -i and -p switch.
|
||||||
|
3. Default synchronization interval changed to 900 seconds, do avoid
|
||||||
|
making troubles with foreign NTP servers.
|
||||||
|
|
||||||
|
2004-01-11
|
||||||
|
1. Added automake and autoconf.
|
||||||
|
2. Added documentation: README, INSTALL, COPYING, ChangeLog, NEWS,
|
||||||
|
AUTHORS, THANKS, and manpage.
|
||||||
|
|
||||||
|
2004-01-10
|
||||||
|
1. The SourceForge project space approved.
|
||||||
|
|
||||||
|
2004-01-09
|
||||||
|
1. Applying a SourceForge project space.
|
||||||
|
|
||||||
|
2003-12-24 version 1.0.0
|
||||||
|
Finalized.
|
||||||
|
1. Program name changed from "synctime" to "vsntp".
|
||||||
|
2. Protocol changed from RFC 868 Time to RFC 1769 SNTP.
|
||||||
|
3. Synchronization interval shortened to 5 seconds.
|
||||||
|
|
||||||
|
2003-12-23
|
||||||
|
Start writing, with a name as "synctime".
|
84
INSTALL
Normal file
84
INSTALL
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
vsntp Installation and Running Procedure
|
||||||
|
|
||||||
|
1. Compilation and Installation Procedure
|
||||||
|
|
||||||
|
vsntp uses standard GNU autoconf to compile and install:
|
||||||
|
|
||||||
|
1. Download, unzip and untar the vsntp package:
|
||||||
|
|
||||||
|
% tar xzf vsntp-x.x.x.tar.gz
|
||||||
|
|
||||||
|
2. Go into its directory:
|
||||||
|
|
||||||
|
% cd vsntp-x.x.x
|
||||||
|
|
||||||
|
3. Configure with ./configure:
|
||||||
|
|
||||||
|
% ./configure
|
||||||
|
|
||||||
|
4. Compile with make:
|
||||||
|
|
||||||
|
% make
|
||||||
|
|
||||||
|
The resulted executable will be named "vsntp".
|
||||||
|
|
||||||
|
5. You need to be root in order to install vsntp:
|
||||||
|
|
||||||
|
% su
|
||||||
|
Password:
|
||||||
|
#
|
||||||
|
|
||||||
|
6. You can simply copy vsntp to the appropriate directory:
|
||||||
|
|
||||||
|
# cp vsntp /usr/local/sbin
|
||||||
|
|
||||||
|
Or, you can run automatic install:
|
||||||
|
|
||||||
|
# make install
|
||||||
|
|
||||||
|
You can reduce the size of the installed executable by
|
||||||
|
stripping off debug symbols inside:
|
||||||
|
|
||||||
|
# make install-strip
|
||||||
|
|
||||||
|
By default vsntp will be installed in /usr/local/sbin .
|
||||||
|
|
||||||
|
2. Compilation and Installation Options
|
||||||
|
|
||||||
|
GNU autoconf configure provides the following options:
|
||||||
|
|
||||||
|
--prefix=PREFIX install architecture-independent files in PREFIX
|
||||||
|
[/usr/local]
|
||||||
|
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
|
||||||
|
[PREFIX]
|
||||||
|
|
||||||
|
--bindir=DIR user executables [EPREFIX/bin]
|
||||||
|
--sbindir=DIR system admin executables [EPREFIX/sbin]
|
||||||
|
--libexecdir=DIR program executables [EPREFIX/libexec]
|
||||||
|
--datadir=DIR read-only architecture-independent data [PREFIX/share]
|
||||||
|
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||||
|
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||||
|
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||||
|
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||||
|
--includedir=DIR C header files [PREFIX/include]
|
||||||
|
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||||
|
--infodir=DIR info documentation [PREFIX/info]
|
||||||
|
--mandir=DIR man documentation [PREFIX/man]
|
||||||
|
|
||||||
|
Type `./configure --help' for a detailed list of compilation options.
|
||||||
|
|
||||||
|
3. Run
|
||||||
|
|
||||||
|
You need to be root to run vsntp. vsntp uses settimeofday() to
|
||||||
|
set the system time. settimeofday() requires root privilege.
|
||||||
|
|
||||||
|
To start vsntp, just specify your NTP server:
|
||||||
|
|
||||||
|
# vsntp my.ntp.server.com
|
||||||
|
|
||||||
|
vsntp writes its PID in /var/run/vsntp.pid. To stop vsntp,
|
||||||
|
kill it by its PID:
|
||||||
|
|
||||||
|
# kill `cat /var/run/vsntp.pid`
|
||||||
|
|
||||||
|
The PID file location can be changed with the `-p' switch.
|
81
INSTALL.zh-cn
Normal file
81
INSTALL.zh-cn
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
vsntp 安装执行说明
|
||||||
|
|
||||||
|
一、编译安装程序
|
||||||
|
|
||||||
|
vsntp 使用标准的 GNU autoconf 来安装编译:
|
||||||
|
|
||||||
|
1. 下载 vsntp 并解压缩:
|
||||||
|
|
||||||
|
% tar xzf vsntp-x.x.x.tar.gz
|
||||||
|
|
||||||
|
2. 进入 vsntp 的子目录:
|
||||||
|
|
||||||
|
% cd vsntp-x.x.x
|
||||||
|
|
||||||
|
3. 执行 ./configure 设定:
|
||||||
|
|
||||||
|
% ./configure
|
||||||
|
|
||||||
|
4. 以 make 编译:
|
||||||
|
|
||||||
|
% make
|
||||||
|
|
||||||
|
编译出来的档案为 vsntp 。
|
||||||
|
|
||||||
|
5. 要安装程式,你可能要先 su 到 root ,用 root 的权限安装:
|
||||||
|
|
||||||
|
% su
|
||||||
|
Password:
|
||||||
|
#
|
||||||
|
|
||||||
|
6. 将 vsntp 档复制到适当的目录即可:
|
||||||
|
|
||||||
|
# cp vsntp /usr/local/sbin
|
||||||
|
|
||||||
|
或者,你也可以用自动安装:
|
||||||
|
|
||||||
|
# make install
|
||||||
|
|
||||||
|
或用 install-strip 清除档案里的除错符号,安装起来档案比较小:
|
||||||
|
|
||||||
|
# make install-strip
|
||||||
|
|
||||||
|
用上述方式安装时, vsntp 预设安装目录在 /usr/local/sbin 。
|
||||||
|
|
||||||
|
二、编译安装选项
|
||||||
|
|
||||||
|
GNU autoconf 的 configure 提供下列的编译安装选项:
|
||||||
|
|
||||||
|
--prefix=PREFIX 作业平台无关的档案装在 PREFIX 下 [/usr/local]
|
||||||
|
--exec-prefix=EPREFIX 作业平台专用的档案装在 EPREFIX 下 [PREFIX]
|
||||||
|
|
||||||
|
--bindir=DIR 一般使用者用的执行档 [EPREFIX/bin]
|
||||||
|
--sbindir=DIR 系统管理者用的执行档 [EPREFIX/sbin]
|
||||||
|
--libexecdir=DIR 程式内部引用的执行档 [EPREFIX/libexec]
|
||||||
|
--datadir=DIR 与作业平台无关的唯读资料 [PREFIX/share]
|
||||||
|
--sysconfdir=DIR 本系统专用的唯读资料 [PREFIX/etc]
|
||||||
|
--sharedstatedir=DIR 与作业平台无关的异动资料 [PREFIX/com]
|
||||||
|
--localstatedir=DIR 本系统专用的异动资料 [PREFIX/var]
|
||||||
|
--libdir=DIR 目的码程式库 [EPREFIX/lib]
|
||||||
|
--includedir=DIR C 语言标头档 [PREFIX/include]
|
||||||
|
--oldincludedir=DIR 非 gcc 用的 C 语言标头档 [/usr/include]
|
||||||
|
--infodir=DIR info 说明文件 [PREFIX/info]
|
||||||
|
--mandir=DIR man 说明文件 [PREFIX/man]
|
||||||
|
|
||||||
|
完整的编译安装选项,请参阅 ./configure --help 的说明。
|
||||||
|
|
||||||
|
三、执行
|
||||||
|
|
||||||
|
要有 root 权限才能执行 vsntp 。 vsntp 用 settimeofday() 对时,没
|
||||||
|
有 root 权限不能执行 settimeofday() 。
|
||||||
|
|
||||||
|
要启动 vsntp ,加上对时用的 ntp server 即可:
|
||||||
|
|
||||||
|
# vsntp my.ntp.server.com
|
||||||
|
|
||||||
|
vsntp 会把 PID 存在 /var/run/vsntp.pid 。要结束程式,只要 kill 它
|
||||||
|
的 PID 即可:
|
||||||
|
|
||||||
|
# kill `cat /var/run/vsntp.pid`
|
||||||
|
|
||||||
|
你可以用 -p 选项,更改 PID 档的位置。
|
81
INSTALL.zh-tw
Normal file
81
INSTALL.zh-tw
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
vsntp 安裝執行說明
|
||||||
|
|
||||||
|
一、編譯安裝程序
|
||||||
|
|
||||||
|
vsntp 使用標準的 GNU autoconf 法編譯安裝:
|
||||||
|
|
||||||
|
1. 下載 vsntp 並解壓縮:
|
||||||
|
|
||||||
|
% tar xzf vsntp-x.x.x.tar.gz
|
||||||
|
|
||||||
|
2. 進入 vsntp 的子目錄:
|
||||||
|
|
||||||
|
% cd vsntp-x.x.x
|
||||||
|
|
||||||
|
3. 執行 ./configure 設定:
|
||||||
|
|
||||||
|
% ./configure
|
||||||
|
|
||||||
|
4. 以 make 編譯:
|
||||||
|
|
||||||
|
% make
|
||||||
|
|
||||||
|
編譯出來的檔案為 vsntp 。
|
||||||
|
|
||||||
|
5. 要安裝程式,妳可能要先 su 到 root ,用 root 的權限安裝:
|
||||||
|
|
||||||
|
% su
|
||||||
|
Password:
|
||||||
|
#
|
||||||
|
|
||||||
|
6. 將 vsntp 檔複製到適當的目錄即可:
|
||||||
|
|
||||||
|
# cp vsntp /usr/local/sbin
|
||||||
|
|
||||||
|
或者,妳也可以用自動安裝:
|
||||||
|
|
||||||
|
# make install
|
||||||
|
|
||||||
|
妳也可以邊裝邊清掉檔案裏的除錯符號,安裝起來檔案比較小:
|
||||||
|
|
||||||
|
# make install-strip
|
||||||
|
|
||||||
|
用上述方式安裝時, vsntp 預設安裝目錄在 /usr/local/sbin 。
|
||||||
|
|
||||||
|
二、編譯安裝選項
|
||||||
|
|
||||||
|
GNU autoconf 的 configure 提供下列的編譯安裝選項:
|
||||||
|
|
||||||
|
--prefix=PREFIX 作業平台無關的檔案裝在 PREFIX 下 [/usr/local]
|
||||||
|
--exec-prefix=EPREFIX 作業平台專用的檔案裝在 EPREFIX 下 [PREFIX]
|
||||||
|
|
||||||
|
--bindir=DIR 一般使用者用的執行檔 [EPREFIX/bin]
|
||||||
|
--sbindir=DIR 系統管理者用的執行檔 [EPREFIX/sbin]
|
||||||
|
--libexecdir=DIR 程式內部引用的執行檔 [EPREFIX/libexec]
|
||||||
|
--datadir=DIR 與作業平台無關的唯讀資料 [PREFIX/share]
|
||||||
|
--sysconfdir=DIR 本系統專用的唯讀資料 [PREFIX/etc]
|
||||||
|
--sharedstatedir=DIR 與作業平台無關的異動資料 [PREFIX/com]
|
||||||
|
--localstatedir=DIR 本系統專用的異動資料 [PREFIX/var]
|
||||||
|
--libdir=DIR 目的碼程式庫 [EPREFIX/lib]
|
||||||
|
--includedir=DIR C 語言標頭檔 [PREFIX/include]
|
||||||
|
--oldincludedir=DIR 非 gcc 用的 C 語言標頭檔 [/usr/include]
|
||||||
|
--infodir=DIR info 說明文件 [PREFIX/info]
|
||||||
|
--mandir=DIR man 說明文件 [PREFIX/man]
|
||||||
|
|
||||||
|
完整的編譯安裝選項,請參閱 ./configure --help 的說明。
|
||||||
|
|
||||||
|
三、執行
|
||||||
|
|
||||||
|
要有 root 權限才能執行 vsntp 。 vsntp 用 settimeofday() 對時,沒
|
||||||
|
有 root 權限不能執行 settimeofday() 。
|
||||||
|
|
||||||
|
要啟動 vsntp ,加上對時用的 NTP server 即可:
|
||||||
|
|
||||||
|
# vsntp my.ntp.server.com
|
||||||
|
|
||||||
|
vsntp 會把 PID 存在 /var/run/vsntp.pid 。要結束程式,只要 kill 它
|
||||||
|
的 PID 即可:
|
||||||
|
|
||||||
|
# kill `cat /var/run/vsntp.pid`
|
||||||
|
|
||||||
|
妳可以用 -p 選項,更改 PID 檔的位置。
|
25
Makefile.am
Normal file
25
Makefile.am
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
## Makefile.in template file for vsntp
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
##
|
||||||
|
## Copyright (c) 2003-2007 imacat
|
||||||
|
##
|
||||||
|
## 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = gnits
|
||||||
|
|
||||||
|
sbin_PROGRAMS = vsntp
|
||||||
|
vsntp_SOURCES = vsntp.c
|
||||||
|
|
||||||
|
EXTRA_DIST = README.* INSTALL.* NEWS.* AUTHORS.* THANKS.*
|
||||||
|
SUBDIRS = doc init.d
|
31
NEWS
Normal file
31
NEWS
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
vsntp NEWS
|
||||||
|
|
||||||
|
2007-03-29 version 2.0.0
|
||||||
|
1. Added alarm() in addition to sleep() as an alternative
|
||||||
|
synchronization scheduler, in order to fix a problem that vsntp
|
||||||
|
sleep() may stop working after MS Virtual PC 2007 was suspended
|
||||||
|
for a while, as reported and suggested by Jean-Alain Le Borgne
|
||||||
|
<jalb@pobox.com> 2007-03-26. The codes are based on
|
||||||
|
Jean-Alain's contribution. Thank you. Two new switches "-a" and
|
||||||
|
"-s" were added for for setting the schedular. Currently the
|
||||||
|
default is -s (sleep()). If you find vsntp stops synchronization
|
||||||
|
after running for some time, that the sleep() is not functioning
|
||||||
|
normally on your system, you may try to switch to alarm() using
|
||||||
|
the "-a" switch.
|
||||||
|
2. More debugging information were logged, in the syslog log level
|
||||||
|
LOG_DEBUG with log facility LOG_DAEMON.
|
||||||
|
3. Two SysV-styled init scripts are provided for convenience in the
|
||||||
|
init.d subdirectory. Check the README file in that directory for
|
||||||
|
more information.
|
||||||
|
|
||||||
|
2004-01-14 version 1.1.1
|
||||||
|
Documentation fix.
|
||||||
|
1. Reference information revised.
|
||||||
|
|
||||||
|
2004-01-12 version 1.1.0
|
||||||
|
First public release.
|
||||||
|
1. Added -i and -p switch.
|
||||||
|
2. Documentation added.
|
||||||
|
|
||||||
|
2003-12-24 version 1.0.0
|
||||||
|
First version.
|
25
NEWS.zh-cn
Normal file
25
NEWS.zh-cn
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
vsntp 新版功能:
|
||||||
|
|
||||||
|
2007-03-29 2.0.0 版
|
||||||
|
1. 加上 alarm() ,作为 sleep() 之外的另一种计时器,以解决
|
||||||
|
Jean-Alain Le Borgne <jalb@pobox.com> 於 2007-03-26 所回报与建议
|
||||||
|
的, MS Virtual PC 2007 在暂停一段时间后复原, sleep() 定时会醒不
|
||||||
|
来的问题。程式由 Jean-Alain 贡献的修正码改写而成,在此致谢。新增两
|
||||||
|
个选项 -a 与 -s ,以设定要用的计时器。目前预设为 -s ,使用 sleep()
|
||||||
|
呼叫定时。若你 vsntp 校时一段时间后就不动了,系统的 sleep() 呼叫有
|
||||||
|
问题时,可以加上 -a 选项,改用 alarm() 定时。
|
||||||
|
2. 加上更多侦错的 syslog 记录讯息,大多记录於 LOG_DEBUG 层级。
|
||||||
|
3. 在 init.d 目录下,提供两个 SysV 的启动程式,以便大家使用。请查阅
|
||||||
|
init.d 目录下 README 档案的说明。
|
||||||
|
|
||||||
|
2004-01-14 1.1.1 版
|
||||||
|
修订说明文件。
|
||||||
|
1. 修订参考资料。
|
||||||
|
|
||||||
|
2004-01-12 1.1.0 版
|
||||||
|
正式公开发行。
|
||||||
|
1. 加上 -i 与 -p 选项。
|
||||||
|
2. 加上说明文件。
|
||||||
|
|
||||||
|
2003-12-24 1.0.0 版
|
||||||
|
第一版。
|
25
NEWS.zh-tw
Normal file
25
NEWS.zh-tw
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
vsntp 新版功能:
|
||||||
|
|
||||||
|
2007-03-29 2.0.0 版
|
||||||
|
1. 加上 alarm() ,作為 sleep() 之外的另一種計時器,以解決
|
||||||
|
Jean-Alain Le Borgne <jalb@pobox.com> 於 2007-03-26 所回報與建議
|
||||||
|
的, MS Virtual PC 2007 在暫停一段時間後復原, sleep() 定時會醒不
|
||||||
|
來的問題。程式由 Jean-Alain 貢獻的修正碼改寫而成,在此致謝。新增兩
|
||||||
|
個選項 -a 與 -s ,以設定要用的計時器。目前預設為 -s ,使用 sleep()
|
||||||
|
呼叫定時。若妳 vsntp 校時一段時間後就不動了,系統的 sleep() 呼叫有
|
||||||
|
問題時,可以加上 -a 選項,改用 alarm() 定時。
|
||||||
|
2. 加上更多偵錯的 syslog 記錄訊息,大多記錄於 LOG_DEBUG 層級。
|
||||||
|
3. 在 init.d 目錄下,提供兩個 SysV 的啟動程式,以便大家使用。詳情請查
|
||||||
|
閱 init.d 目錄下 README 檔案的說明。
|
||||||
|
|
||||||
|
2004-01-14 1.1.1 版
|
||||||
|
修訂說明文件。
|
||||||
|
1. 修訂參考資料。
|
||||||
|
|
||||||
|
2004-01-12 1.1.0 版
|
||||||
|
正式公開發行。
|
||||||
|
1. 加上 -i 與 -p 選項。
|
||||||
|
2. 加上說明文件。
|
||||||
|
|
||||||
|
2003-12-24 1.0.0 版
|
||||||
|
第一版。
|
102
README
Normal file
102
README
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
vsntp README
|
||||||
|
|
||||||
|
See INSTALL for details on how to install and run vsntp.
|
||||||
|
|
||||||
|
Obtaining the Newest Information
|
||||||
|
|
||||||
|
vsntp's official website is at...
|
||||||
|
|
||||||
|
SourceForge's home site: http://vsntp.sourceforge.net/
|
||||||
|
SourceForge's project page: https://sourceforge.net/projects/vsntp/
|
||||||
|
Tavern IMACAT's page: http://www.imacat.idv.tw/tech/vsntp.html
|
||||||
|
|
||||||
|
You can always download the newest version of vsntp from...
|
||||||
|
|
||||||
|
SourceForge: https://sourceforge.net/project/showfiles.php?group_id=99098
|
||||||
|
Tavern IMACAT's FTP: ftp://ftp.imacat.idv.tw/pub/vsntp/
|
||||||
|
|
||||||
|
imacat's PGP public key is at...
|
||||||
|
|
||||||
|
SourceForge: http://vsntp.sourceforge.net/pgpkey.asc
|
||||||
|
Tavern IMACAT's: http://www.imacat.idv.tw/me/pgpkey.asc
|
||||||
|
|
||||||
|
Introduction:
|
||||||
|
|
||||||
|
vsntp is an SNTP client daemon for machines without a sane system
|
||||||
|
time. The word "vsntp" stands for "SNTP for Virtual PC". It was
|
||||||
|
originally designed for my GNU/Linux server running on Connectix
|
||||||
|
Virtual PC. It runs according to RFC 1769 SNTP, connecting the NTP
|
||||||
|
server on UDP port 123.
|
||||||
|
|
||||||
|
Without Virtual PC Additions, the system time on Virtual PC is
|
||||||
|
completely insane. It's RTC (Real Time Clock, or CMOS time, or
|
||||||
|
hardware clock) is software emulated, which does not seems to be
|
||||||
|
running. The GNU/Linux kernel hardly maintains a system time itself.
|
||||||
|
With smooth run it goes 4 seconds ahead per minute, which is nearly
|
||||||
|
1.5 hours per day. That is insane. You can even tell it with your
|
||||||
|
eyes.
|
||||||
|
|
||||||
|
David L. Mills' ntp does not work here. It uses a method that
|
||||||
|
learns the clock frequency drift first, and adjust the kerenl clock
|
||||||
|
with adjtimex() so that time adjustment goes smoothly, from the point
|
||||||
|
of view of system and applications. This assumes an existing fix-
|
||||||
|
speed system clock. But this is not the case of Virtual PC. The
|
||||||
|
system clock on Virtual PC is software emulated. It can be faster
|
||||||
|
or slower now and then, depending on the load of the hosting machine.
|
||||||
|
There is no fixed clock speed. The frequency drift does not exist,
|
||||||
|
then. It dooms to fail to measure it.
|
||||||
|
|
||||||
|
There is an sntp client that comes with David L. Mills' ntp
|
||||||
|
package. It is suggested to be run from crontab. But crontab runs
|
||||||
|
by minutes, and Virtual PC goes 4 seconds ahead per minute. Rolling
|
||||||
|
back 4 seconds every minute is insane for most applications. It also
|
||||||
|
increases system load heavily to run one instance per minute.
|
||||||
|
|
||||||
|
vsntp is a workaround on this. It runs as a daemon to eliminates
|
||||||
|
the additional system load on every synchronization. It uses
|
||||||
|
settimeofday() to synchronize the time. It synchronizes the time
|
||||||
|
with an arbitrary interval, so that time can be accurate within a
|
||||||
|
second.
|
||||||
|
|
||||||
|
There are some defects. Synchronizing the time too often
|
||||||
|
introduces heavy network load. It introduces heavy load on the
|
||||||
|
target NTP server, too. You should have a working NTP server nearby
|
||||||
|
that is owned by you. Also, since settimeofday() is called so often,
|
||||||
|
high-accurate time operations like timer, etc., may not run
|
||||||
|
correctly.
|
||||||
|
|
||||||
|
vsntp uses sleep() as the synchronization scheduler. Reports show
|
||||||
|
that on some systems sleep() may not function normally. If you find
|
||||||
|
vsntp stops synchronization after running for some time, that the
|
||||||
|
sleep() is not functioning normally on your system, you may want to
|
||||||
|
switch to the alarm() scheduler with the "-a" switch.
|
||||||
|
|
||||||
|
If you ever encounter any problem, you may check your syslog.
|
||||||
|
vsntp logs detailed debugging information to syslog in log level
|
||||||
|
LOG_DEBUG with facility LOG_DAEMON. You may turn it on in your
|
||||||
|
/etc/syslog.conf with the following line:
|
||||||
|
|
||||||
|
daemon.debug /var/log/debug
|
||||||
|
|
||||||
|
and check the /var/log/debug file for the debugging message. Remember
|
||||||
|
to remove this afterwards, for the amount of the debugging messages
|
||||||
|
may be huge and may use up your harddisk in a very short time. To the
|
||||||
|
least it may slow down your system for frequent harddisk I/O.
|
||||||
|
|
||||||
|
vsntp was originally written for GNU/Linux. It uses POSIX
|
||||||
|
compatible system calls. It should work on any POSIX compatible
|
||||||
|
system. But I have yet only tested it on Cygwin. Cygwin is known to
|
||||||
|
work. I don't have others to test and run on. Please let me know
|
||||||
|
(and submit the patch if needed) if you can port it to other systems.
|
||||||
|
I know it does not work on MSWin32, for the way it handles the PID
|
||||||
|
file path.
|
||||||
|
|
||||||
|
Please tell me if you have successfully running vsntp on other
|
||||||
|
virtual machines, like VMWare.
|
||||||
|
|
||||||
|
Generally, please tell me if you are using vsntp. I would like
|
||||||
|
to know that I am really doing some good for the world, *^_^* but not
|
||||||
|
having fun myself. :p
|
||||||
|
|
||||||
|
This is my first daemon, my first socket program and my first
|
||||||
|
public-released C program. Any comment or suggestion is welcome. ^_*'
|
82
README.zh-cn
Normal file
82
README.zh-cn
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
vsntp 读我说明
|
||||||
|
|
||||||
|
请参阅 INSTALL 档案,以取得安装执行的相关说明。
|
||||||
|
|
||||||
|
想知道 vsntp 的最新消息,下载最新版本,请参阅:
|
||||||
|
|
||||||
|
http://vsntp.sourceforge.net/
|
||||||
|
http://sourceforge.net/projects/vsntp
|
||||||
|
http://www.imacat.idv.tw/tech/vsntp.html
|
||||||
|
ftp://ftp.imacat.idv.tw/pub/vsntp/
|
||||||
|
|
||||||
|
作者的 PGP Public Key 可在下列网址下载:
|
||||||
|
|
||||||
|
http://www.imacat.idv.tw/me/pgpkey.txt
|
||||||
|
|
||||||
|
简介:
|
||||||
|
|
||||||
|
vsntp 是 SNTP 客户端服务程式,专为时间不正常的系统设计。 vsntp
|
||||||
|
的意思是 SNTP for Virtual PC ,原先是我为了在 Connectix Virtual PC
|
||||||
|
上跑 GNU/Linux 系统而写。 vsntp 依 RFC 1769 SNTP 标准,连线到 SNTP 伺
|
||||||
|
服器上的 UDP 埠 123 以校时。
|
||||||
|
|
||||||
|
若没有装 Virtual PC Additions , Virtual PC 的时间很乱。 Virtual
|
||||||
|
PC 的 RTC ( Real Time Clock, 或称 CMOS 时钟、硬体时钟)是用软体模拟
|
||||||
|
出来的,往往根本没有在跑。 GNU/Linux 核心勉强维持一个大概的时间。正常
|
||||||
|
情况下,平均一分钟会快四秒,一天快一个半小时。这实在是太夸张了,用眼
|
||||||
|
睛都分辨得出时钟速度有问题。
|
||||||
|
|
||||||
|
David L. Mills 的 ntp 校时伺服器在此完全失灵。 ntp 先测出系统时间
|
||||||
|
速度偏移,用 adjtimex() 来调整系统时钟速度,用这个方法渐近式调整,系
|
||||||
|
统本身和相关应用程式比较不会出问题。这个方法有一个前提:时间速度本身
|
||||||
|
恒定不变。可是 Virtual PC 不讲这一套。 Virtual PC 的时间纯粹是软体模
|
||||||
|
拟出来的,受主电脑负荷与其它因素影响,时快时慢。没有固定的时间速度,
|
||||||
|
也就没有时间速度偏移值。怎么测都是枉然。
|
||||||
|
|
||||||
|
David L. Mills 的 ntp 程式里,附了一 sntp 客户端程式,可以放在
|
||||||
|
crontab 里定期对时,对时完结束程式。问题是, crontab 最小单位为分,
|
||||||
|
顶多一分钟跑一次,可是 Virtual PC 的时间一分钟慢四秒。一分钟退回四秒
|
||||||
|
,大多数应用程式都受不了。一分钟跑一次,对系统的负荷也很大。
|
||||||
|
|
||||||
|
vsntp 是为此而写的。它以 daemon 来执行,以免每次对时都对系统造成
|
||||||
|
严重负荷。它用 settimeofday() 来调整时间,校时频率可任意设定,尽可能
|
||||||
|
把系统时钟误差,维持在一秒以内。
|
||||||
|
|
||||||
|
vsntp 的做法有下列缺陷:频繁校时时,网路流量很大,频宽的负荷不小
|
||||||
|
,对对方 NTP 伺服器也会造成很大的负担。你最好自己在区网内,架一台自
|
||||||
|
己的 NTP 伺服器。同时因 settimeofday() 强制时间设定太频繁了,系统的
|
||||||
|
高精度计时功能会出问题。
|
||||||
|
|
||||||
|
vsntp 用 sleep() 呼叫来定时校时。在某些系统上 sleep() 可能不大正
|
||||||
|
常。若 vsntp 校时一段时间后就不动了,系统上的 sleep() 呼叫不正常时,
|
||||||
|
可以改用 -a 选项换成 alarm() 计时器试看看。
|
||||||
|
|
||||||
|
若碰到任何问题,请参阅你系统的上的 syslog 记录。 vsntp 把详细侦错
|
||||||
|
讯息,都以 LOG_DEBUG 层次, LOG_DAEMON 类别记录到 syslog 中。你可以在
|
||||||
|
/etc/syslog.conf 中加上这一行,写入侦错讯息:
|
||||||
|
|
||||||
|
daemon.debug /var/log/debug
|
||||||
|
|
||||||
|
并查阅 /var/log/debug 中的侦错讯息。记得在侦错结束后关闭。侦错讯息流
|
||||||
|
量很大,很快就会塞爆硬碟。就算没塞爆,大量资料写入硬碟,对系统效能的
|
||||||
|
影响也很大。
|
||||||
|
|
||||||
|
vsntp 原是为 GNU/Linux 系统上执行而写。 vsntp 用的都是 POSIX 相
|
||||||
|
容的系统呼叫,在 POSIX 相容系统上应该都可以执行。不过目前为止我只有
|
||||||
|
Cygwin ,只在 Cygwin 上测试过。 Cygwin 上可以执行。若你可以成功在其它
|
||||||
|
系统上执行,请来信告知。若需要任何原始程式的修正,亦请一并附给我。我
|
||||||
|
知道因为 PID 档路径处理方式,所以无法在 MSWin32 上执行。
|
||||||
|
|
||||||
|
vsntp 只在 GNU/Linux 系统上测试执行过。 vsntp 用的都是 POSIX 相容
|
||||||
|
的系统呼叫,在 POSIX 相容系统上应该都可以执行。不过我没有其它系统,无
|
||||||
|
从测试起。若你可以成功在其它系统上执行,请来信告知。若需要任何原始程式
|
||||||
|
的修正,亦请一并附给我。我知道因为 PID 档路径处理方式,所以无法在
|
||||||
|
MSWin32 上执行。但在 Cygwin 上说不定可以执行。
|
||||||
|
|
||||||
|
若你可以在其它虚拟机器上执行 vsntp ,例如 VMWare ,请来信告知。
|
||||||
|
|
||||||
|
基本上,若你在用 vsntp ,请一定要来信告诉我。我很想知道 vsntp 是
|
||||||
|
不是真的有人在用,对世界和平有帮助 *^_^* 或只是自己写好玩的而已。 :p
|
||||||
|
|
||||||
|
vsntp 是我写的第一个 daemon ,我写的第一个 socket 程式,也是我第
|
||||||
|
一个公开发行的 C 程式。请多多指教~ ^_*'
|
82
README.zh-tw
Normal file
82
README.zh-tw
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
vsntp 讀我說明
|
||||||
|
|
||||||
|
請參閱 INSTALL 檔案,以取得安裝執行的相關說明。
|
||||||
|
|
||||||
|
想知道 vsntp 的最新消息,下載最新版本,請參閱:
|
||||||
|
|
||||||
|
http://vsntp.sourceforge.net/
|
||||||
|
http://sourceforge.net/projects/vsntp
|
||||||
|
http://www.imacat.idv.tw/tech/vsntp.html
|
||||||
|
ftp://ftp.imacat.idv.tw/pub/vsntp/
|
||||||
|
|
||||||
|
作者的 PGP Public Key 可在下列網址下載:
|
||||||
|
|
||||||
|
http://www.imacat.idv.tw/me/pgpkey.txt
|
||||||
|
|
||||||
|
簡介:
|
||||||
|
|
||||||
|
vsntp 是 SNTP 客戶端服務程式,專為時間不正常的系統設計。 vsntp
|
||||||
|
的意思是 SNTP for Virtual PC ,原先是我為了在 Connectix Virtual PC
|
||||||
|
上跑 GNU/Linux 系統而寫。 vsntp 依 RFC 1769 SNTP 標準,連線到 SNTP 伺
|
||||||
|
服器上的 UDP 埠 123 以校時。
|
||||||
|
|
||||||
|
若沒有裝 Virtual PC Additions , Virtual PC 的時間很亂。 Virtual
|
||||||
|
PC 的 RTC ( Real Time Clock, 或稱 CMOS 時鐘、硬體時鐘)是用軟體模擬
|
||||||
|
出來的,往往根本沒有在跑。 GNU/Linux 核心勉強維持一個大概的時間。正常
|
||||||
|
情況下,平均一分鐘會快四秒,一天快一個半小時。這實在是太誇張了,用眼
|
||||||
|
睛都分辨得出時鐘速度有問題。
|
||||||
|
|
||||||
|
David L. Mills 的 ntp 校時伺服器在此完全失靈。 ntp 先測出系統時間
|
||||||
|
速度偏移,用 adjtimex() 來調整系統時鐘速度,用這個方法漸近式調整,系
|
||||||
|
統本身和相關應用程式比較不會出問題。這個方法有一個前提:時間速度本身
|
||||||
|
恆定不變。可是 Virtual PC 不講這一套。 Virtual PC 的時間純粹是軟體模
|
||||||
|
擬出來的,受主電腦負荷與其它因素影響,時快時慢。沒有固定的時間速度,
|
||||||
|
也就沒有時間速度偏移值。怎麼測都是枉然。
|
||||||
|
|
||||||
|
David L. Mills 的 ntp 程式裏,附了一 sntp 客戶端程式,可以放在
|
||||||
|
crontab 裏定期對時,對時完結束程式。問題是, crontab 最小單位為分,
|
||||||
|
頂多一分鐘跑一次,可是 Virtual PC 的時間一分鐘慢四秒。一分鐘退回四秒
|
||||||
|
,大多數應用程式都受不了。一分鐘跑一次,對系統的負荷也很大。
|
||||||
|
|
||||||
|
vsntp 是為此而寫的。它以 daemon 來執行,以免每次對時都對系統造成
|
||||||
|
嚴重負荷。它用 settimeofday() 來調整時間,校時頻率可任意設定,儘可能
|
||||||
|
把系統時鐘誤差,維持在一秒以內。
|
||||||
|
|
||||||
|
vsntp 的做法有下列缺陷:頻繁校時時,網路流量很大,頻寬的負荷不小
|
||||||
|
,對對方 NTP 伺服器也會造成很大的負擔。妳最好自己在區網內,架一台自
|
||||||
|
己的 NTP 伺服器。同時因 settimeofday() 強制時間設定太頻繁了,系統的
|
||||||
|
高精度計時功能會出問題。
|
||||||
|
|
||||||
|
vsntp 用 sleep() 呼叫來定時校時。在某些系統上 sleep() 可能不大正
|
||||||
|
常。若 vsntp 校時一段時間後就不動了,系統上的 sleep() 呼叫不正常時,
|
||||||
|
可以改用 -a 選項換成 alarm() 計時器試看看。
|
||||||
|
|
||||||
|
若碰到任何問題,請參閱妳系統的上的 syslog 記錄。 vsntp 把詳細偵錯
|
||||||
|
訊息,都以 LOG_DEBUG 層次, LOG_DAEMON 類別記錄到 syslog 中。妳可以在
|
||||||
|
/etc/syslog.conf 中加上這一行,寫入偵錯訊息:
|
||||||
|
|
||||||
|
daemon.debug /var/log/debug
|
||||||
|
|
||||||
|
並查閱 /var/log/debug 中的偵錯訊息。記得在偵錯結束後關閉。偵錯訊息流
|
||||||
|
量很大,很快就會塞爆硬碟。就算沒塞爆,大量資料寫入硬碟,對系統效能的
|
||||||
|
影響也很大。
|
||||||
|
|
||||||
|
vsntp 原是為 GNU/Linux 系統上執行而寫。 vsntp 用的都是 POSIX 相
|
||||||
|
容的系統呼叫,在 POSIX 相容系統上應該都可以執行。不過目前為止我只有
|
||||||
|
Cygwin ,只在 Cygwin 上測試過。 Cygwin 上可以執行。若妳可以成功在其它
|
||||||
|
系統上執行,請來信告知。若需要任何原始程式的修正,亦請一併附給我。我
|
||||||
|
知道因為 PID 檔路徑處理方式,所以無法在 MSWin32 上執行。
|
||||||
|
|
||||||
|
vsntp 只在 GNU/Linux 系統上測試執行過。 vsntp 用的都是 POSIX 相容
|
||||||
|
的系統呼叫,在 POSIX 相容系統上應該都可以執行。不過我沒有其它系統,無
|
||||||
|
從測試起。若妳可以成功在其它系統上執行,請來信告知。若需要任何原始程式
|
||||||
|
的修正,亦請一併附給我。我知道因為 PID 檔路徑處理方式,所以無法在
|
||||||
|
MSWin32 上執行。但在 Cygwin 上說不定可以執行。
|
||||||
|
|
||||||
|
若妳可以在其它虛擬機器上執行 vsntp ,例如 VMWare ,請來信告知。
|
||||||
|
|
||||||
|
基本上,若妳在用 vsntp ,請一定要來信告訴我。我很想知道 vsntp 是
|
||||||
|
不是真的有人在用,對世界和平有幫助 *^_^* 或只是自己寫好玩的而已。 :p
|
||||||
|
|
||||||
|
vsntp 是我寫的第一個 daemon ,我寫的第一個 socket 程式,也是我第
|
||||||
|
一個公開發行的 C 程式。請多多指教~ ^_*'
|
7
THANKS
Normal file
7
THANKS
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Thanks to SourceForge's people to kindly provide hosting of the
|
||||||
|
vsntp project.
|
||||||
|
|
||||||
|
Thanks to Jean-Alain Le Borgne <jalb@pobox.com> to debug and find out
|
||||||
|
the sleep() scheduler problem when MS Virtual PC 2007 suspended for a while,
|
||||||
|
file a bug report and provide a fix with an alternative scheduler alarm()
|
||||||
|
on 2007-03-26.
|
5
THANKS.zh-cn
Normal file
5
THANKS.zh-cn
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
感谢 SourceForge 热心提供架设 vsntp 。
|
||||||
|
|
||||||
|
感谢 Jean-Alain Le Borgne <jalb@pobox.com> 於 2007-03-26 侦错并找出
|
||||||
|
以 sleep() 定时,在 MS Virtual PC 2007 暂停一段时间后恢复,会醒不来的问题,
|
||||||
|
回报该问题,并提供 alarm() 作为替代的定时器的修正程式。
|
5
THANKS.zh-tw
Normal file
5
THANKS.zh-tw
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
感謝 SourceForge 熱心提供架設 vsntp 。
|
||||||
|
|
||||||
|
感謝 Jean-Alain Le Borgne <jalb@pobox.com> 於 2007-03-26 偵錯並找出
|
||||||
|
以 sleep() 定時,在 MS Virtual PC 2007 暫停一段時間後恢復,會醒不來的問題,
|
||||||
|
回報該問題,並提供 alarm() 作為替代的定時器的修正程式。
|
122
config.h.in
Normal file
122
config.h.in
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `alarm' function. */
|
||||||
|
#undef HAVE_ALARM
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
|
#undef HAVE_ARPA_INET_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fork' function. */
|
||||||
|
#undef HAVE_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gethostbyname' function. */
|
||||||
|
#undef HAVE_GETHOSTBYNAME
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gettimeofday' function. */
|
||||||
|
#undef HAVE_GETTIMEOFDAY
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
||||||
|
to 0 otherwise. */
|
||||||
|
#undef HAVE_MALLOC
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netdb.h> header file. */
|
||||||
|
#undef HAVE_NETDB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||||
|
#undef HAVE_NETINET_IN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `socket' function. */
|
||||||
|
#undef HAVE_SOCKET
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <syslog.h> header file. */
|
||||||
|
#undef HAVE_SYSLOG_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||||
|
#undef HAVE_SYS_SOCKET_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/time.h> header file. */
|
||||||
|
#undef HAVE_SYS_TIME_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfork' function. */
|
||||||
|
#undef HAVE_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <vfork.h> header file. */
|
||||||
|
#undef HAVE_VFORK_H
|
||||||
|
|
||||||
|
/* Define to 1 if `fork' works. */
|
||||||
|
#undef HAVE_WORKING_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if `vfork' works. */
|
||||||
|
#undef HAVE_WORKING_VFORK
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#undef PACKAGE
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the home page for this package. */
|
||||||
|
#undef PACKAGE_URL
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#undef VERSION
|
||||||
|
|
||||||
|
/* Define to rpl_malloc if the replacement function should be used. */
|
||||||
|
#undef malloc
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef pid_t
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef ssize_t
|
||||||
|
|
||||||
|
/* Define as `fork' if `vfork' does not work. */
|
||||||
|
#undef vfork
|
32
configure.ac
Normal file
32
configure.ac
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ([2.69])
|
||||||
|
AC_INIT([vsntp], [2.1.0], [imacat@mail.imacat.idv.tw])
|
||||||
|
AM_INIT_AUTOMAKE
|
||||||
|
AC_CONFIG_SRCDIR([vsntp.c])
|
||||||
|
AC_CONFIG_HEADERS([config.h])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_CHECK_HEADERS([arpa/inet.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h sys/time.h syslog.h unistd.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_TYPE_SSIZE_T
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
AC_FUNC_ERROR_AT_LINE
|
||||||
|
AC_FUNC_FORK
|
||||||
|
AC_FUNC_MALLOC
|
||||||
|
AC_CHECK_FUNCS([alarm gethostbyname gettimeofday socket strerror])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile
|
||||||
|
doc/Makefile
|
||||||
|
init.d/Makefile])
|
||||||
|
AC_OUTPUT
|
25
doc/Makefile.am
Normal file
25
doc/Makefile.am
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
## Makefile.in template file for vsntp documentation
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
##
|
||||||
|
## Copyright (c) 2007 imacat
|
||||||
|
##
|
||||||
|
## 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = gnits
|
||||||
|
|
||||||
|
info_TEXINFOS = vsntp.texi
|
||||||
|
man8_MANS = vsntp.8
|
||||||
|
dist_man8_MANS = $(man8_MANS)
|
||||||
|
|
||||||
|
EXTRA_DIST = rfc1769.txt
|
787
doc/rfc1769.txt
Normal file
787
doc/rfc1769.txt
Normal file
@ -0,0 +1,787 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Network Working Group D. Mills
|
||||||
|
Request for Comments: 1769 University of Delaware
|
||||||
|
Obsoletes: 1361 March 1995
|
||||||
|
Category: Informational
|
||||||
|
|
||||||
|
|
||||||
|
Simple Network Time Protocol (SNTP)
|
||||||
|
|
||||||
|
Status of this Memo
|
||||||
|
|
||||||
|
This memo provides information for the Internet community. This memo
|
||||||
|
does not specify an Internet standard of any kind. Distribution of
|
||||||
|
this memo is unlimited.
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
|
||||||
|
This memorandum describes the Simple Network Time Protocol (SNTP),
|
||||||
|
which is an adaptation of the Network Time Protocol (NTP) used to
|
||||||
|
synchronize computer clocks in the Internet. SNTP can be used when
|
||||||
|
the ultimate performance of the full NTP implementation described in
|
||||||
|
RFC-1305 is not needed or justified. It can operate in both unicast
|
||||||
|
modes (point to point) and broadcast modes (point to multipoint). It
|
||||||
|
can also operate in IP multicast mode where this service is
|
||||||
|
available. SNTP involves no change to the current or previous NTP
|
||||||
|
specification versions or known implementations, but rather a
|
||||||
|
clarification of certain design features of NTP which allow operation
|
||||||
|
in a simple, stateless remote-procedure call (RPC) mode with accuracy
|
||||||
|
and reliability expectations similar to the UDP/TIME protocol
|
||||||
|
described in RFC-868.
|
||||||
|
|
||||||
|
This memorandum obsoletes RFC-1361 of the same title. Its purpose is
|
||||||
|
to explain the protocol model for operation in broadcast mode, to
|
||||||
|
provide additional clarification in some places and to correct a few
|
||||||
|
typographical errors. A working knowledge of the NTP Version 3
|
||||||
|
specification RFC-1305 is not required for an implementation of SNTP.
|
||||||
|
Distribution of this memorandum is unlimited.
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
|
||||||
|
The Network Time Protocol (NTP) specified in RFC-1305 [MIL92] is used
|
||||||
|
to synchronize computer clocks in the global Internet. It provides
|
||||||
|
comprehensive mechanisms to access national time and frequency
|
||||||
|
dissemination services, organize the time-synchronization subnet and
|
||||||
|
adjust the local clock in each participating subnet peer. In most
|
||||||
|
places of the Internet of today, NTP provides accuracies of 1-50 ms,
|
||||||
|
depending on the characteristics of the synchronization source and
|
||||||
|
network paths.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 1]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
RFC-1305 specifies the NTP protocol machine in terms of events,
|
||||||
|
states, transition functions and actions and, in addition, optional
|
||||||
|
algorithms to improve the timekeeping quality and mitigate among
|
||||||
|
several, possibly faulty, synchronization sources. To achieve
|
||||||
|
accuracies in the low milliseconds over paths spanning major portions
|
||||||
|
of the Internet of today, these intricate algorithms, or their
|
||||||
|
functional equivalents, are necessary. However, in many cases
|
||||||
|
accuracies of this order are not required and something less, perhaps
|
||||||
|
in the order of large fractions of the second, is sufficient. In such
|
||||||
|
cases simpler protocols such as the Time Protocol [POS83], have been
|
||||||
|
used for this purpose. These protocols usually involve an RPC
|
||||||
|
exchange where the client requests the time of day and the server
|
||||||
|
returns it in seconds past some known reference epoch.
|
||||||
|
|
||||||
|
NTP is designed for use by clients and servers with a wide range of
|
||||||
|
capabilities and over a wide range of network delays and jitter
|
||||||
|
characteristics. Most users of the Internet NTP synchronization
|
||||||
|
subnet of today use a software package including the full suite of
|
||||||
|
NTP options and algorithms, which are relatively complex, real-time
|
||||||
|
applications. While the software has been ported to a wide variety of
|
||||||
|
hardware platforms ranging from supercomputers to personal computers,
|
||||||
|
its sheer size and complexity is not appropriate for many
|
||||||
|
applications. Accordingly, it is useful to explore alternative access
|
||||||
|
strategies using far simpler software appropriate for less stringent
|
||||||
|
accuracy expectations.
|
||||||
|
|
||||||
|
This memorandum describes the Simple Network Time Protocol (SNTP),
|
||||||
|
which is a simplified access strategy for servers and clients using
|
||||||
|
NTP as now specified and deployed in the Internet. There are no
|
||||||
|
changes to the protocol or implementations now running or likely to
|
||||||
|
be implemented in the near future. The access paradigm is identical
|
||||||
|
to the UDP/TIME Protocol and, in fact, it should be easily possible
|
||||||
|
to adapt a UDP/TIME client implementation, say for a personal
|
||||||
|
computer, to operate using SNTP. Moreover, SNTP is also designed to
|
||||||
|
operate in a dedicated server configuration including an integrated
|
||||||
|
radio clock. With careful design and control of the various latencies
|
||||||
|
in the system, which is practical in a dedicated design, it is
|
||||||
|
possible to deliver time accurate to the order of microseconds.
|
||||||
|
|
||||||
|
It is strongly recommended that SNTP be used only at the extremities
|
||||||
|
of the synchronization subnet. SNTP clients should operate only at
|
||||||
|
the leaves (highest stratum) of the subnet and in configurations
|
||||||
|
where no NTP or SNTP client is dependent on another SNTP client for
|
||||||
|
synchronization. SNTP servers should operate only at the root
|
||||||
|
(stratum 1) of the subnet and then only in configurations where no
|
||||||
|
other source of synchronization other than a reliable radio clock is
|
||||||
|
available. The full degree of reliability ordinarily expected of
|
||||||
|
primary servers is possible only using the redundant sources, diverse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 2]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
subnet paths and crafted algorithms of a full NTP implementation.
|
||||||
|
This extends to the primary source of synchronization itself in the
|
||||||
|
form of multiple radio clocks and backup paths to other primary
|
||||||
|
servers should the radio clock fail or deliver incorrect time.
|
||||||
|
Therefore, the use of SNTP rather than NTP in primary servers should
|
||||||
|
be carefully considered.
|
||||||
|
|
||||||
|
2. Operating Modes and Addressing
|
||||||
|
|
||||||
|
Like NTP, SNTP can operate in either unicast (point to point) or
|
||||||
|
broadcast (point to multipoint) modes. A unicast client sends a
|
||||||
|
request to a server and expects a reply from which it can determine
|
||||||
|
the time and, optionally, the roundtrip delay and local clock offset
|
||||||
|
relative to the server. A broadcast server periodically sends a
|
||||||
|
message to a designated IP broadcast address or IP multicast group
|
||||||
|
address and ordinarily expects no requests from clients, while a
|
||||||
|
broadcast client listens on this address and ordinarily sends no
|
||||||
|
requests to servers. Some broadcast servers may elect to respond to
|
||||||
|
client requests as well as send unsolicited broadcast messages, while
|
||||||
|
some broadcast clients may elect to send requests only in order to
|
||||||
|
determine the network propagation delay between the server and
|
||||||
|
client.
|
||||||
|
|
||||||
|
In unicast mode the client and server IP addresses are assigned
|
||||||
|
following the usual conventions. In broadcast mode the server uses a
|
||||||
|
designated IP broadcast address or IP multicast group address,
|
||||||
|
together with a designated media-access broadcast address, and the
|
||||||
|
client listens on these addresses. For this purpose, an IP broadcast
|
||||||
|
address has scope limited to a single IP subnet, since routers do not
|
||||||
|
propagate IP broadcast datagrams. In the case of Ethernets, for
|
||||||
|
example, the Ethernet media-access broadcast address (all ones) is
|
||||||
|
used with an IP address consisting of the IP subnet number in the net
|
||||||
|
field and all ones in the host field.
|
||||||
|
|
||||||
|
On the other hand, an IP multicast group address has scope extending
|
||||||
|
to potentially the entire Internet. The actual scope, group
|
||||||
|
membership and routing are determined by the Internet Group
|
||||||
|
Management Protocol (IGMP) [DEE89] and various routing protocols,
|
||||||
|
which are beyond the scope of this document. In the case of
|
||||||
|
Ethernets, for example, the Ethernet media-access broadcast address
|
||||||
|
(all ones) is used with the assigned IP multicast group address of
|
||||||
|
224.0.1.1. Other than the IP addressing conventions and IGMP, there
|
||||||
|
is no difference in server operations with either the IP broadcast
|
||||||
|
address or IP multicast group address.
|
||||||
|
|
||||||
|
Broadcast clients listen on the designated media-access broadcast
|
||||||
|
address, such as all ones in the case of Ethernets. In the case of IP
|
||||||
|
broadcast addresses, no further provisions are necessary. In the case
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 3]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
of IP multicast group addresses, the host may need to implement IGMP
|
||||||
|
in order that the local router intercepts messages to the 224.0.1.1
|
||||||
|
multicast group. These considerations are beyond the scope of this
|
||||||
|
document.
|
||||||
|
|
||||||
|
In the case of SNTP as specified herein, there is a very real
|
||||||
|
vulnerability that SNTP multicast clients can be disrupted by
|
||||||
|
misbehaving or hostile SNTP or NTP multicast servers elsewhere in the
|
||||||
|
Internet, since at present all such servers use the same IP multicast
|
||||||
|
group address 224.0.1.1. Where necessary, access control based on the
|
||||||
|
server source address can be used to select only those servers known
|
||||||
|
to and trusted by the client. Alternatively, by convention and
|
||||||
|
informal agreement, all NTP multicast servers now include an MD5-
|
||||||
|
encrypted message digest in every message, so that clients can
|
||||||
|
determine if the message is authentic and not modified in transit. It
|
||||||
|
is in principle possible that SNTP clients could implement the
|
||||||
|
necessary encryption and key-distribution schemes, but this is
|
||||||
|
considered not likely in the simple systems for which SNTP is
|
||||||
|
intended.
|
||||||
|
|
||||||
|
While not integral to the SNTP specification, it is intended that IP
|
||||||
|
broadcast addresses will be used primarily in IP subnets and LAN
|
||||||
|
segments including a fully functional NTP server with a number of
|
||||||
|
SNTP clients in the same subnet, while IP multicast group addresses
|
||||||
|
will be used only in special cases engineered for the purpose. In
|
||||||
|
particular, IP multicast group addresses should be used in SNTP
|
||||||
|
servers only if the server implements the NTP authentication scheme
|
||||||
|
described in RFC-1305, including support for the MD5 message-digest
|
||||||
|
algorithm.
|
||||||
|
|
||||||
|
3. NTP Timestamp Format
|
||||||
|
|
||||||
|
SNTP uses the standard NTP timestamp format described in RFC-1305 and
|
||||||
|
previous versions of that document. In conformance with standard
|
||||||
|
Internet practice, NTP data are specified as integer or fixed-point
|
||||||
|
quantities, with bits numbered in big-endian fashion from 0 starting
|
||||||
|
at the left, or high-order, position. Unless specified otherwise, all
|
||||||
|
quantities are unsigned and may occupy the full field width with an
|
||||||
|
implied 0 preceding bit 0.
|
||||||
|
|
||||||
|
Since NTP timestamps are cherished data and, in fact, represent the
|
||||||
|
main product of the protocol, a special timestamp format has been
|
||||||
|
established. NTP timestamps are represented as a 64-bit unsigned
|
||||||
|
fixed-point number, in seconds relative to 0h on 1 January 1900. The
|
||||||
|
integer part is in the first 32 bits and the fraction part in the
|
||||||
|
last 32 bits. In the fraction part, the non-significant low-order
|
||||||
|
bits should be set to 0. This format allows convenient multiple-
|
||||||
|
precision arithmetic and conversion to UDP/TIME representation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 4]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
(seconds), but does complicate the conversion to ICMP Timestamp
|
||||||
|
message representation (milliseconds). The precision of this
|
||||||
|
representation is about 200 picoseconds, which should be adequate for
|
||||||
|
even the most exotic requirements.
|
||||||
|
|
||||||
|
1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Seconds |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Seconds Fraction (0-padded) |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
Note that, since some time in 1968 the most significant bit (bit 0 of
|
||||||
|
the integer part) has been set and that the 64-bit field will
|
||||||
|
overflow some time in 2036. Should NTP or SNTP be in use in 2036,
|
||||||
|
some external means will be necessary to qualify time relative to
|
||||||
|
1900 and time relative to 2036 (and other multiples of 136 years).
|
||||||
|
Timestamped data requiring such qualification will be so precious
|
||||||
|
that appropriate means should be readily available. There will exist
|
||||||
|
a 200-picosecond interval, henceforth ignored, every 136 years when
|
||||||
|
the 64-bit field will be 0, which by convention is interpreted as an
|
||||||
|
invalid or unavailable timestamp.
|
||||||
|
|
||||||
|
4. NTP Message Format
|
||||||
|
|
||||||
|
Both NTP and SNTP are clients of the User Datagram Protocol (UDP)
|
||||||
|
[POS80], which itself is a client of the Internet Protocol (IP)
|
||||||
|
[DAR81]. The structure of the IP and UDP headers is described in the
|
||||||
|
cited specification documents and will not be described further here.
|
||||||
|
The UDP port number assigned to NTP is 123, which should be used in
|
||||||
|
both the Source Port and Destination Port fields in the UDP header.
|
||||||
|
The remaining UDP header fields should be set as described in the
|
||||||
|
specification.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 5]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Following is a description of the SNTP message format, which follows
|
||||||
|
the IP and UDP headers. The SNTP message format is identical to the
|
||||||
|
NTP format described in RFC-1305, with the exception that some of the
|
||||||
|
data fields are "canned," that is, initialized to pre-specified
|
||||||
|
values. The format of the NTP message is shown below.
|
||||||
|
|
||||||
|
1 2 3
|
||||||
|
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|LI | VN |Mode | Stratum | Poll | Precision |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Root Delay |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Root Dispersion |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| Reference Identifier |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| |
|
||||||
|
| Reference Timestamp (64) |
|
||||||
|
| |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| |
|
||||||
|
| Originate Timestamp (64) |
|
||||||
|
| |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| |
|
||||||
|
| Receive Timestamp (64) |
|
||||||
|
| |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| |
|
||||||
|
| Transmit Timestamp (64) |
|
||||||
|
| |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| Authenticator (optional) (96) |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
|
||||||
|
As described in the next section, in SNTP most of these fields are
|
||||||
|
initialized with pre-specified data. For completeness, the function
|
||||||
|
of each field is briefly summarized below.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 6]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Leap Indicator (LI): This is a two-bit code warning of an impending
|
||||||
|
leap second to be inserted/deleted in the last minute of the current
|
||||||
|
day, with bit 0 and bit 1, respectively, coded as follows:
|
||||||
|
|
||||||
|
LI Value Meaning
|
||||||
|
-------------------------------------------------------
|
||||||
|
00 0 no warning
|
||||||
|
01 1 last minute has 61 seconds
|
||||||
|
10 2 last minute has 59 seconds)
|
||||||
|
11 3 alarm condition (clock not synchronized)
|
||||||
|
|
||||||
|
Version Number (VN): This is a three-bit integer indicating the NTP
|
||||||
|
version number, currently 3.
|
||||||
|
|
||||||
|
Mode: This is a three-bit integer indicating the mode, with values
|
||||||
|
defined as follows:
|
||||||
|
|
||||||
|
Mode Meaning
|
||||||
|
------------------------------------
|
||||||
|
0 reserved
|
||||||
|
1 symmetric active
|
||||||
|
2 symmetric passive
|
||||||
|
3 client
|
||||||
|
4 server
|
||||||
|
5 broadcast
|
||||||
|
6 reserved for NTP control message
|
||||||
|
7 reserved for private use
|
||||||
|
|
||||||
|
In unicast mode the client sets this field to 3 (client) in the
|
||||||
|
request and the server sets it to 4 (server) in the reply. In
|
||||||
|
broadcast mode the server sets this field to 5 (broadcast).
|
||||||
|
|
||||||
|
Stratum: This is a eight-bit unsigned integer indicating the stratum
|
||||||
|
level of the local clock, with values defined as follows:
|
||||||
|
|
||||||
|
Stratum Meaning
|
||||||
|
----------------------------------------------
|
||||||
|
0 unspecified or unavailable
|
||||||
|
1 primary reference (e.g., radio clock)
|
||||||
|
2-15 secondary reference (via NTP or SNTP)
|
||||||
|
16-255 reserved
|
||||||
|
|
||||||
|
Poll Interval: This is an eight-bit signed integer indicating the
|
||||||
|
maximum interval between successive messages, in seconds to the
|
||||||
|
nearest power of two. The values that can appear in this field
|
||||||
|
presently range from 4 (16 s) to 14 (16284 s); however, most
|
||||||
|
applications use only the sub-range 6 (64 s) to 10 (1024 s).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 7]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Precision: This is an eight-bit signed integer indicating the
|
||||||
|
precision of the local clock, in seconds to the nearest power of two.
|
||||||
|
The values that normally appear in this field range from -6 for
|
||||||
|
mains-frequency clocks to -20 for microsecond clocks found in some
|
||||||
|
workstations.
|
||||||
|
|
||||||
|
Root Delay: This is a 32-bit signed fixed-point number indicating the
|
||||||
|
total roundtrip delay to the primary reference source, in seconds
|
||||||
|
with fraction point between bits 15 and 16. Note that this variable
|
||||||
|
can take on both positive and negative values, depending on the
|
||||||
|
relative time and frequency offsets. The values that normally appear
|
||||||
|
in this field range from negative values of a few milliseconds to
|
||||||
|
positive values of several hundred milliseconds.
|
||||||
|
|
||||||
|
Root Dispersion: This is a 32-bit unsigned fixed-point number
|
||||||
|
indicating the nominal error relative to the primary reference
|
||||||
|
source, in seconds with fraction point between bits 15 and 16. The
|
||||||
|
values that normally appear in this field range from 0 to several
|
||||||
|
hundred milliseconds.
|
||||||
|
|
||||||
|
Reference Clock Identifier: This is a 32-bit code identifying the
|
||||||
|
particular reference source. In the case of stratum 0 (unspecified)
|
||||||
|
or stratum 1 (primary reference), this is a four-octet, left-
|
||||||
|
justified, 0-padded ASCII string. While not enumerated as part of the
|
||||||
|
NTP specification, the following are representative ASCII
|
||||||
|
identifiers:
|
||||||
|
|
||||||
|
Stratum Code Meaning
|
||||||
|
----------------------------------------------------------------
|
||||||
|
1 pps precision calibrated source, such as ATOM (atomic
|
||||||
|
clock), PPS (precision pulse-per-second source),
|
||||||
|
etc.
|
||||||
|
1 service generic time service other than NTP, such as ACTS
|
||||||
|
(Automated Computer Time Service), TIME (UDP/Time
|
||||||
|
Protocol), TSP (Unix Time Service Protocol), DTSS
|
||||||
|
(Digital Time Synchronization Service), etc.
|
||||||
|
1 radio Generic radio service, with callsigns such as CHU,
|
||||||
|
DCF77, MSF, TDF, WWV, WWVB, WWVH, etc.
|
||||||
|
1 nav radionavigation system, such as OMEG (OMEGA), LORC
|
||||||
|
(LORAN-C), etc.
|
||||||
|
1 satellite generic satellite service, such as GOES
|
||||||
|
(Geostationary Orbit Environment Satellite, GPS
|
||||||
|
(Global Positioning Service), etc.
|
||||||
|
2 address secondary reference (four-octet Internet address of
|
||||||
|
the NTP server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 8]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Reference Timestamp: This is the time at which the local clock was
|
||||||
|
last set or corrected, in 64-bit timestamp format.
|
||||||
|
|
||||||
|
Originate Timestamp: This is the time at which the request departed
|
||||||
|
the client for the server, in 64-bit timestamp format.
|
||||||
|
|
||||||
|
Receive Timestamp: This is the time at which the request arrived at
|
||||||
|
the server, in 64-bit timestamp format.
|
||||||
|
|
||||||
|
Transmit Timestamp: This is the time at which the reply departed the
|
||||||
|
server for the client, in 64-bit timestamp format.
|
||||||
|
|
||||||
|
Authenticator (optional): When the NTP authentication mechanism is
|
||||||
|
implemented, this contains the authenticator information defined in
|
||||||
|
Appendix C of RFC-1305. In SNTP this field is ignored for incoming
|
||||||
|
messages and is not generated for outgoing messages.
|
||||||
|
|
||||||
|
5. SNTP Client Operations
|
||||||
|
|
||||||
|
The model for n SNTP client operating with either a NTP or SNTP
|
||||||
|
server is a RPC client with no persistent state. In unicast mode, the
|
||||||
|
client sends a client request (mode 3) to the server and expects a
|
||||||
|
server reply (mode 4). In broadcast mode, the client sends no request
|
||||||
|
and waits for a broadcast message (mode 5) from one or more servers,
|
||||||
|
depending on configuration. Unicast client and broadcast server
|
||||||
|
messages are normally sent at periods from 64 s to 1024 s, depending
|
||||||
|
on the client and server configurations.
|
||||||
|
|
||||||
|
A unicast client initializes the SNTP message header, sends the
|
||||||
|
message to the server and strips the time of day from the reply. For
|
||||||
|
this purpose all of the message-header fields shown above are set to
|
||||||
|
0, except the first octet. In this octet the LI field is set to 0 (no
|
||||||
|
warning) and the Mode field is set to 3 (client). The VN field must
|
||||||
|
agree with the software version of the NTP or SNTP server; however,
|
||||||
|
NTP Version 3 (RFC-1305) servers will also accept Version 2 (RFC-
|
||||||
|
1119) and Version 1 (RFC-1059) messages, while NTP Version 2 servers
|
||||||
|
will also accept NTP Version 1 messages. Version 0 (RFC-959) messages
|
||||||
|
are no longer supported. Since there are NTP servers of all three
|
||||||
|
versions interoperating in the Internet of today, it is recommended
|
||||||
|
that the VN field be set to 1.
|
||||||
|
|
||||||
|
In both unicast and broadcast modes, the unicast server reply or
|
||||||
|
broadcast message includes all the fields described above; however,
|
||||||
|
in SNTP only the Transmit Timestamp has explicit meaning and then
|
||||||
|
only if nonzero. The integer part of this field contains the server
|
||||||
|
time of day in the same format as the UDP/TIME Protocol [POS83].
|
||||||
|
While the fraction part of this field will usually be valid, the
|
||||||
|
accuracy achieved with SNTP may justify its use only to a significant
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 9]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
fraction of a second. If the Transmit Timestamp field is 0, the
|
||||||
|
message should be disregarded.
|
||||||
|
|
||||||
|
In broadcast mode, a client has no additional information to
|
||||||
|
calculate the propagation delay between the server and client, as the
|
||||||
|
Transmit Timestamp and Receive Timestamp fields have no meaning in
|
||||||
|
this mode. Even in unicast mode, most clients will probably elect to
|
||||||
|
ignore the Originate Timestamp and Receive Timestamp fields anyway.
|
||||||
|
However, in unicast mode a simple calculation can be used to provide
|
||||||
|
the roundtrip delay d and local clock offset t relative to the
|
||||||
|
server, generally to within a few tens of milliseconds. To do this,
|
||||||
|
the client sets the Originate Timestamp in the request to the time of
|
||||||
|
day according to its local clock converted to NTP timestamp format.
|
||||||
|
When the reply is received, the client determines a Destination
|
||||||
|
Timestamp as the time of arrival according to its local clock
|
||||||
|
converted to NTP timestamp format. The following table summarizes the
|
||||||
|
four timestamps.
|
||||||
|
|
||||||
|
Timestamp Name ID When Generated
|
||||||
|
------------------------------------------------------------
|
||||||
|
Originate Timestamp T1 time request sent by client
|
||||||
|
Receive Timestamp T2 time request received at server
|
||||||
|
Transmit Timestamp T3 time reply sent by server
|
||||||
|
Destination Timestamp T4 time reply received at client
|
||||||
|
|
||||||
|
The roundtrip delay d and local clock offset t are defined as
|
||||||
|
|
||||||
|
d = (T4 - T1) - (T2 - T3)
|
||||||
|
t = ((T2 - T1) + (T3 - T4)) / 2.
|
||||||
|
|
||||||
|
The following table is a summary of the SNTP client operations. There
|
||||||
|
are two recommended error checks shown in the table. In all NTP
|
||||||
|
versions, if the LI field is 3, or the Stratum field is not in the
|
||||||
|
range 1-15, or the Transmit Timestamp is 0, the server has never
|
||||||
|
synchronized or not synchronized to a valid timing source within the
|
||||||
|
last 24 hours. At the client discretion, the values of the remaining
|
||||||
|
fields can be checked as well. Whether to believe the transmit
|
||||||
|
timestamp or not in case one or more of these fields appears invalid
|
||||||
|
is at the discretion of the implementation.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 10]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Field Name Request Reply
|
||||||
|
-------------------------------------------------------------
|
||||||
|
LI 0 leap indicator; if 3
|
||||||
|
(unsynchronized), disregard
|
||||||
|
message
|
||||||
|
VN 1 (see text) ignore
|
||||||
|
Mode 3 (client) ignore
|
||||||
|
Stratum 0 ignore
|
||||||
|
Poll 0 ignore
|
||||||
|
Precision 0 ignore
|
||||||
|
Root Delay 0 ignore
|
||||||
|
Root Dispersion 0 ignore
|
||||||
|
Reference Identifier 0 ignore
|
||||||
|
Reference Timestamp 0 ignore
|
||||||
|
Originate Timestamp 0 (see text) ignore (see text)
|
||||||
|
Receive Timestamp 0 ignore (see text)
|
||||||
|
Transmit Timestamp 0 time of day; if 0
|
||||||
|
(unsynchronized), disregard
|
||||||
|
message
|
||||||
|
Authenticator (not used) ignore
|
||||||
|
|
||||||
|
6. SNTP Server Operations
|
||||||
|
|
||||||
|
The model for a SNTP server operating with either a NTP or SNTP
|
||||||
|
client is an RPC server with no persistent state. Since a SNTP server
|
||||||
|
ordinarily does not implement the full set of NTP algorithms intended
|
||||||
|
to support redundant peers and diverse network paths, it is
|
||||||
|
recommended that a SNTP server be operated only in conjunction with a
|
||||||
|
source of external synchronization, such as a reliable radio clock.
|
||||||
|
In this case the server always operates at stratum 1.
|
||||||
|
|
||||||
|
A server can operate in unicast mode, broadcast mode or both at the
|
||||||
|
same time. In unicast mode the server receives a request message,
|
||||||
|
modifies certain fields in the NTP or SNTP header, and returns the
|
||||||
|
message to the sender, possibly using the same message buffer as the
|
||||||
|
request. The server may or may not respond if not synchronized to a
|
||||||
|
correctly operating radio clock, but the preferred option is to
|
||||||
|
respond, since this allows reachability to be determined regardless
|
||||||
|
of synchronization state. In unicast mode, the VN and Poll fields of
|
||||||
|
the request are copied intact to the reply. If the Mode field of the
|
||||||
|
request is 3 (client), it is set to 4 (server) in the reply;
|
||||||
|
otherwise, this field is set to 2 (symmetric passive) in order to
|
||||||
|
conform to the NTP specification.
|
||||||
|
|
||||||
|
In broadcast mode, the server sends messages only if synchronized to
|
||||||
|
a correctly operating reference clock. In this mode, the VN field is
|
||||||
|
set to 3 (for the current SNTP version), and the Mode field to 5
|
||||||
|
(broadcast). The Poll field is set to the server poll interval, in
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 11]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
seconds to the nearest power of two. It is highly desirable that, if
|
||||||
|
a server supports broadcast mode, it also supports unicast mode. This
|
||||||
|
is necessary so a potential broadcast client can calculate the
|
||||||
|
propagation delay using client/server messages prior to regular
|
||||||
|
operation using only broadcast messages.
|
||||||
|
|
||||||
|
The remaining fields are set in the same way in both unicast and
|
||||||
|
broadcast modes. Assuming the server is synchronized to a radio clock
|
||||||
|
or other primary reference source and operating correctly, the
|
||||||
|
Stratum field is set to 1 (primary server) and the LI field is set to
|
||||||
|
0; if not, the Stratum field is set to 0 and the LI field is set to
|
||||||
|
3. The Precision field is set to reflect the maximum reading error of
|
||||||
|
the local clock. For all practical cases it is computed as the
|
||||||
|
negative of the number of significant bits to the right of the
|
||||||
|
decimal point in the NTP timestamp format. The Root Delay and Root
|
||||||
|
Dispersion fields are set to 0 for a primary server; optionally, the
|
||||||
|
Root Dispersion field can be set to a value corresponding to the
|
||||||
|
maximum expected error of the radio clock itself. The Reference
|
||||||
|
Identifier is set to designate the primary reference source, as
|
||||||
|
indicated in the table above.
|
||||||
|
|
||||||
|
The timestamp fields are set as follows. If the server is
|
||||||
|
unsynchronized or first coming up, all timestamp fields are set to
|
||||||
|
zero. If synchronized, the Reference Timestamp is set to the time the
|
||||||
|
last update was received from the radio clock or, if unavailable, to
|
||||||
|
the time of day when the message is sent. The Receive Timestamp and
|
||||||
|
Transmit Timestamp fields are set to the time of day when the message
|
||||||
|
is sent. In unicast mode, the Originate Timestamp field is copied
|
||||||
|
unchanged from the Transmit Timestamp field of the request. It is
|
||||||
|
important that this field be copied intact, as a NTP client uses it
|
||||||
|
to check for replays. In broadcast mode, this field is set to the
|
||||||
|
time of day when the message is sent. The following table summarizes
|
||||||
|
these actions.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 12]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Field Name Request Reply
|
||||||
|
----------------------------------------------------------
|
||||||
|
LI ignore 0 (normal), 3
|
||||||
|
(unsynchronized)
|
||||||
|
VN 1, 2 or 3 3 or copied from request
|
||||||
|
Mode 3 (see text) 2, 4 or 5 (see text)
|
||||||
|
Stratum ignore 1 server stratum
|
||||||
|
Poll ignore copied from request
|
||||||
|
Precision ignore server precision
|
||||||
|
Root Delay ignore 0
|
||||||
|
Root Dispersion ignore 0 (see text)
|
||||||
|
Reference Identifier ignore source identifier
|
||||||
|
Reference Timestamp ignore 0 or time of day
|
||||||
|
Originate Timestamp ignore 0 or time of day or copied
|
||||||
|
from Transmit Timestamp of
|
||||||
|
request
|
||||||
|
Receive Timestamp ignore 0 or time of day
|
||||||
|
Transmit Timestamp (see text) 0 or time of day
|
||||||
|
Authenticator ignore (not used)
|
||||||
|
|
||||||
|
There is some latitude on the part of most clients to forgive invalid
|
||||||
|
timestamps, such as might occur when first coming up or during
|
||||||
|
periods when the primary reference source is inoperative. The most
|
||||||
|
important indicator of an unhealthy server is the LI field, in which
|
||||||
|
a value of 3 indicates an unsynchronized condition. When this value
|
||||||
|
is displayed, clients should discard the server message, regardless
|
||||||
|
of the contents of other fields.
|
||||||
|
|
||||||
|
7. References
|
||||||
|
|
||||||
|
[DAR81] Postel, J., "Internet Protocol - DARPA Internet Program
|
||||||
|
Protocol Specification", STD 5, RFC 791, DARPA, September 1981.
|
||||||
|
|
||||||
|
[DEE89] Deering, S., "Host Extensions for IP Multicasting. STD 5,
|
||||||
|
RFC 1112, Stanford University, August 1989.
|
||||||
|
|
||||||
|
[MIL92] Mills, D., "Network Time Protocol (Version 3) Specification,
|
||||||
|
Implementation and Analysis. RFC 1305, University of Delaware,
|
||||||
|
March 1992.
|
||||||
|
|
||||||
|
[POS80] Postel, J., "User Datagram Protocol", STD 6, RFC 768,
|
||||||
|
USC/Information Sciences Institute, August 1980.
|
||||||
|
|
||||||
|
[POS83] Postel, J., and K. Harrenstien, "Time Protocol", STD 26,
|
||||||
|
RFC 868, USC/Information Sciences Institute, SRI, May 1983.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 13]
|
||||||
|
|
||||||
|
RFC 1769 SNTP March 1995
|
||||||
|
|
||||||
|
|
||||||
|
Security Considerations
|
||||||
|
|
||||||
|
Security issues are not discussed in this memo.
|
||||||
|
|
||||||
|
Author's Address
|
||||||
|
|
||||||
|
David L. Mills
|
||||||
|
Electrical Engineering Department
|
||||||
|
University of Delaware
|
||||||
|
Newark, DE 19716
|
||||||
|
|
||||||
|
Phone: (302) 831-8247
|
||||||
|
EMail: mills@udel.edu
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Mills [Page 14]
|
||||||
|
|
219
doc/vsntp.8
Normal file
219
doc/vsntp.8
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
.\" Process this file with
|
||||||
|
.\" groff -man -Tascii vsntp.8
|
||||||
|
.\"
|
||||||
|
.TH VSNTP 8 "MARCH 2007" VSNTP "System Administration Tools"
|
||||||
|
.SH NAME
|
||||||
|
vsntp \- SNTP client for Virtual PC
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BI "vsntp [-i " n "] [-p " file "] [-a|-s] " server
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B vsntp
|
||||||
|
is an
|
||||||
|
.SM SNTP
|
||||||
|
client daemon for machines without a sane system time. The word
|
||||||
|
.B vsntp
|
||||||
|
stands for
|
||||||
|
.BR "SNTP for Virtual PC" .
|
||||||
|
It was originally designed for my
|
||||||
|
.I GNU/Linux
|
||||||
|
server running on Connectix Virtual PC. It runs according to
|
||||||
|
.SM RFC
|
||||||
|
1769
|
||||||
|
.SM SNTP
|
||||||
|
, connecting the
|
||||||
|
.SM NTP
|
||||||
|
server on
|
||||||
|
.SM UDP
|
||||||
|
port 123. It has only been compiled and run on
|
||||||
|
.I GNU/Linux
|
||||||
|
before.
|
||||||
|
|
||||||
|
Without "Virtual
|
||||||
|
.SM PC
|
||||||
|
Additions", the system time on Virtual
|
||||||
|
.SM PC
|
||||||
|
is completely insane. It's
|
||||||
|
.SM RTC
|
||||||
|
(Real Time Clock, or
|
||||||
|
.SM CMOS
|
||||||
|
time, or hardware clock) is software emulated, which does not seems
|
||||||
|
to be running. The
|
||||||
|
.I GNU/Linux
|
||||||
|
kernel hardly maintains a system time itself. With smooth run it
|
||||||
|
goes 4 seconds ahead per minute, which is nearly 1.5 hours per day.
|
||||||
|
That is insane. You can even tell it with your eyes.
|
||||||
|
|
||||||
|
David L. Mills'
|
||||||
|
.B ntp
|
||||||
|
does not work here. It uses a method that learns the clock frequency
|
||||||
|
drift first, and adjust the kerenl clock with
|
||||||
|
.B adjtimex()
|
||||||
|
so that time adjustment goes smoothly, from the point of view of
|
||||||
|
system and applications. This assumes an existing fix-speed system
|
||||||
|
clock. But this is not the case here. The system clock on Virtual
|
||||||
|
.SM PC
|
||||||
|
is software emulated. It goes faster or slower now and then,
|
||||||
|
depending on the load of the hosting machine. There is no fixed
|
||||||
|
clock speed. The frequency drift does not exist, then. It dooms to
|
||||||
|
fail to measure it.
|
||||||
|
|
||||||
|
There is an
|
||||||
|
.B sntp
|
||||||
|
client that comes with David L. Mills'
|
||||||
|
.B ntp
|
||||||
|
package.
|
||||||
|
It is suggested to be run from crontab. But crontab runs by minutes,
|
||||||
|
and Virtual
|
||||||
|
.SM PC
|
||||||
|
goes 4 seconds ahead per minute. Rolling back 4 seconds every minute
|
||||||
|
is insane for most applications. It also increases system load
|
||||||
|
heavily to run one instance per minute.
|
||||||
|
|
||||||
|
.B vsntp
|
||||||
|
is a workaround on this. It runs as a daemon to to eliminates the
|
||||||
|
additional system load on every synchronization. It uses
|
||||||
|
.B settimeofday()
|
||||||
|
to synchronize the time. It synchronizes the
|
||||||
|
time with an arbitrary interval, so that time can be accurate within
|
||||||
|
a second.
|
||||||
|
|
||||||
|
There are some defects. Synchronizing the time too often introduces
|
||||||
|
heavy network load. It introduces heavy load on the target
|
||||||
|
.SM NTP
|
||||||
|
server, too. You should have a working
|
||||||
|
.SM NTP
|
||||||
|
server nearby that is owned by you. Also, since
|
||||||
|
.B settimeofday()
|
||||||
|
is called so often, highly-accurate time operations like timer, etc.,
|
||||||
|
may not run correctly.
|
||||||
|
|
||||||
|
.B vsntp
|
||||||
|
uses
|
||||||
|
.BI sleep()
|
||||||
|
as the synchronization scheduler. Reports show that on some systems
|
||||||
|
.BI sleep()
|
||||||
|
may not function normally. If you find
|
||||||
|
.BI vsntp
|
||||||
|
stops synchronization after running for some time, that the
|
||||||
|
.BI sleep()
|
||||||
|
is not functioning normally on your system, you may want to switch
|
||||||
|
to the
|
||||||
|
.BI alarm()
|
||||||
|
scheduler with the
|
||||||
|
.B -a
|
||||||
|
switch.
|
||||||
|
|
||||||
|
.B vsntp
|
||||||
|
was originally written for
|
||||||
|
.I GNU/Linux .
|
||||||
|
It uses
|
||||||
|
.SM POSIX
|
||||||
|
compatible system calls. It should work on any
|
||||||
|
.SM POSIX
|
||||||
|
compatible system. But I have yet only tested it on Cygwin. Cygwin
|
||||||
|
is known to work. I don't have others to test and run on. Please let
|
||||||
|
me know (and submit the patch if needed) if you can port it to other
|
||||||
|
systems. I know it does not work on MSWin32, for the way it handles
|
||||||
|
the
|
||||||
|
.SM PID
|
||||||
|
file path.
|
||||||
|
|
||||||
|
Please tell me if you have successfully running vsntp on other virtual
|
||||||
|
machines, like
|
||||||
|
.BR "VMWare" .
|
||||||
|
|
||||||
|
Generally, please tell me if you are using
|
||||||
|
.B "vsntp" .
|
||||||
|
I would like to know that I am really doing some good for the world,
|
||||||
|
*^_^* but not having fun myself. :p
|
||||||
|
|
||||||
|
This is my first daemon, my first socket program and my first
|
||||||
|
public-released C program. Any comment or suggestion is welcome. ^_*'
|
||||||
|
.SH OPTIONS
|
||||||
|
.IP "-i,--interval n"
|
||||||
|
Set the synchronization interval to
|
||||||
|
.I n
|
||||||
|
seconds. Default is 900 seconds (15 minutes).
|
||||||
|
.IP "-p,--pidfile file"
|
||||||
|
The
|
||||||
|
.SM PID
|
||||||
|
file location. Default to
|
||||||
|
.IR /var/run/vsntp.pid .
|
||||||
|
.IP -s,--sleep
|
||||||
|
Use
|
||||||
|
.BI sleep()
|
||||||
|
as the scheduler. This is currently the default.
|
||||||
|
.IP -a,--alarm
|
||||||
|
Use
|
||||||
|
.BI alarm()
|
||||||
|
as the scheduler.
|
||||||
|
.IP -h,--help
|
||||||
|
Display the help message.
|
||||||
|
.IP -v,--version
|
||||||
|
Display version information.
|
||||||
|
.SH FILES
|
||||||
|
.I /var/run/vsntp.pid
|
||||||
|
.RS
|
||||||
|
The
|
||||||
|
.SM PID
|
||||||
|
of the running daemon.
|
||||||
|
.SH DIAGNOSTICS
|
||||||
|
If you ever encounter any problem, you may check your syslog.
|
||||||
|
.B vsntp
|
||||||
|
logs detailed debugging information to syslog in log level
|
||||||
|
.B LOG_DEBUG
|
||||||
|
with facility
|
||||||
|
.B LOG_DAEMON .
|
||||||
|
You may turn it on in your
|
||||||
|
.I /etc/syslog.conf
|
||||||
|
with the following line:
|
||||||
|
|
||||||
|
daemon.debug /var/log/debug
|
||||||
|
|
||||||
|
and check the
|
||||||
|
.I /var/log/debug
|
||||||
|
file for the debugging message. Remember to remove this afterwards,
|
||||||
|
for the amount of the debugging messages may be huge and may use up
|
||||||
|
your harddisk in a very short time. To the least it may slow down
|
||||||
|
your system for frequent harddisk
|
||||||
|
.SM "I/O" .
|
||||||
|
.SH BUGS
|
||||||
|
.B vsntp
|
||||||
|
is hosted on SourceForge and Tavern IMACAT's. For the latest
|
||||||
|
infomation, see:
|
||||||
|
|
||||||
|
http://vsntp.sourceforge.net/
|
||||||
|
https://sourceforge.net/projects/vsntp/
|
||||||
|
http://www.imacat.idv.tw/tech/vsntp.html
|
||||||
|
|
||||||
|
.B vsntp has a mailing list hosted at SourceForge:
|
||||||
|
vsntp-users@lists.sourceforge.net . Please submit your questions,
|
||||||
|
suggestions or bug reports there. It is a Mailman mailing list.
|
||||||
|
For more information, see:
|
||||||
|
|
||||||
|
https://lists.sourceforge.net/lists/listinfo/vsntp-users
|
||||||
|
|
||||||
|
Alternatively, you can send a mail to:
|
||||||
|
vsntp-users-request@lists.sourceforge.net with the subject
|
||||||
|
.B help
|
||||||
|
for a list of available e-mail commands.
|
||||||
|
.SH AUTHOR
|
||||||
|
imacat <imacat@mail.imacat.idv.tw>.
|
||||||
|
.SH "SEE ALSO"
|
||||||
|
.BR settimeofday (2),
|
||||||
|
.BR adjtimex (2),
|
||||||
|
.BR sleep (3),
|
||||||
|
.BR alarm (2).
|
||||||
|
|
||||||
|
.BR ntp :
|
||||||
|
http://www.ntp.org/ .
|
||||||
|
|
||||||
|
.SM RFC
|
||||||
|
1769
|
||||||
|
.SM SNTP
|
||||||
|
: http://www.faqs.org/rfcs/rfc1769.html .
|
||||||
|
|
||||||
|
.SM RFC
|
||||||
|
1305
|
||||||
|
.SM NTP
|
||||||
|
: http://www.faqs.org/rfcs/rfc1305.html .
|
410
doc/vsntp.texi
Normal file
410
doc/vsntp.texi
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
\input texinfo @c -*-texinfo-*-
|
||||||
|
@c %**start of header
|
||||||
|
@setfilename vsntp.info
|
||||||
|
@include version.texi
|
||||||
|
@settitle vsntp v@value{VERSION}
|
||||||
|
@syncodeindex vr cp
|
||||||
|
@syncodeindex pg cp
|
||||||
|
@c %**end of header
|
||||||
|
|
||||||
|
@copying
|
||||||
|
This manual is for vsntp
|
||||||
|
(version @value{VERSION}, @value{UPDATED}),
|
||||||
|
a SNTP daemon for Virtual @acronym{PC}@.
|
||||||
|
|
||||||
|
Copyright @copyright{} 2003-2007 imacat@.
|
||||||
|
|
||||||
|
@quotation
|
||||||
|
Permission is granted to copy, distribute and/or modify this document
|
||||||
|
under the terms of the @acronym{GNU} Free Documentation License, Version 1.2
|
||||||
|
or any later version published by the Free Software Foundation;
|
||||||
|
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts@.
|
||||||
|
A copy of the license is included in the section entitled ``@acronym{GNU}
|
||||||
|
Free Documentation License''@.
|
||||||
|
@end quotation
|
||||||
|
@end copying
|
||||||
|
|
||||||
|
|
||||||
|
@titlepage
|
||||||
|
@title vsntp v@value{VERSION}
|
||||||
|
@c The following two commands start the copyright page.
|
||||||
|
@page
|
||||||
|
@vskip 0pt plus 1filll
|
||||||
|
@insertcopying
|
||||||
|
Published by imacat@*
|
||||||
|
@email{imacat@@mail.imacat.idv.tw}@*
|
||||||
|
@uref{http://www.imacat.idv.tw/}@*
|
||||||
|
@end titlepage
|
||||||
|
@c Output the table of contents at the beginning.
|
||||||
|
@contents
|
||||||
|
|
||||||
|
@ifnottex
|
||||||
|
@node Top
|
||||||
|
@top Short Sample
|
||||||
|
@insertcopying
|
||||||
|
@end ifnottex
|
||||||
|
@menu
|
||||||
|
* Introduction::
|
||||||
|
* Download the Newest Version: Download.
|
||||||
|
* Compilation and Installation: Install.
|
||||||
|
* Running and Stopping: Run.
|
||||||
|
* Command Line Options: Options.
|
||||||
|
* Supports and Bugs Report: Support.
|
||||||
|
* References::
|
||||||
|
* Copyright::
|
||||||
|
* Index::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Introduction
|
||||||
|
@chapter Introduction
|
||||||
|
|
||||||
|
@pindex Virtual PC
|
||||||
|
@pindex Connectix Virtual PC
|
||||||
|
@cindex RFC 1769 SNTP
|
||||||
|
@cindex UDP
|
||||||
|
@dfn{vsntp} is an @acronym{SNTP} client daemon for machines without a
|
||||||
|
sane system time@. The word ``@dfn{vsntp}'' stands for
|
||||||
|
``@dfn{@acronym{SNTP} for Virtual PC}''@. It was originally designed
|
||||||
|
for my @acronym{GNU}/Linux server running on Connectix Virtual @acronym{PC}@.
|
||||||
|
It runs according to @acronym{RFC} 1769 @acronym{SNTP}, connecting
|
||||||
|
the @acronym{NTP} server on @acronym{UDP} port 123@. It was originally
|
||||||
|
written for @acronym{GNU}/Linux@.
|
||||||
|
|
||||||
|
Without Virtual @acronym{PC} Additions, the system time on Virtual @acronym{PC} is
|
||||||
|
completely insane@. It's @acronym{RTC} (Real Time Clock, or
|
||||||
|
@acronym{CMOS} time, or hardware clock) is software emulated, which
|
||||||
|
does not seems to be running@. The @acronym{GNU}/Linux kernel hardly
|
||||||
|
maintains a system time itself@. With smooth run it goes 4 seconds
|
||||||
|
ahead per minute, which is nearly 1.5 hours per day@. That is
|
||||||
|
insane@. You can even tell it with your eyes@.
|
||||||
|
|
||||||
|
@pindex David L. Mills
|
||||||
|
@pindex ntp
|
||||||
|
@findex adjtimex()
|
||||||
|
@uref{http://www.ntp.org/,David L. Mills' @command{ntp}} does not
|
||||||
|
work here@. It uses a method that learns the clock frequency drift
|
||||||
|
first, and adjust the kerenl clock with @code{adjtimex()} so that
|
||||||
|
time adjustment goes smoothly, from the point of view of system and
|
||||||
|
applications@. This assumes an existing fix-speed system clock@.
|
||||||
|
But this is not the case of Virtual @acronym{PC}@. The system clock
|
||||||
|
on Virtual @acronym{PC} is software emulated@. It can be faster or
|
||||||
|
slower now and then, depending on the load of the hosting machine@.
|
||||||
|
There is no fixed clock speed@. The frequency drift does not exist,
|
||||||
|
then@. It dooms to fail to measure it@.
|
||||||
|
|
||||||
|
@pindex sntp
|
||||||
|
There is an @command{sntp} client that comes with David L. Mills'
|
||||||
|
@command{ntp} package@. It is suggested to be run from
|
||||||
|
@command{crontab}@. But @command{crontab} runs by minutes, and
|
||||||
|
Virtual @acronym{PC} goes 4 seconds ahead per minute@. Rolling back
|
||||||
|
4 seconds every minute is insane for most applications@. It also
|
||||||
|
increases system load heavily to run one instance per minute@.
|
||||||
|
|
||||||
|
@findex settimeofday()
|
||||||
|
@command{vsntp} is a workaround on this@. It runs as a daemon to
|
||||||
|
eliminates the additional system load on every synchronization@. It
|
||||||
|
uses @code{settimeofday()} to synchronize the time@. It synchronizes
|
||||||
|
the time with an arbitrary interval, so that time can be accurate
|
||||||
|
within a second@.
|
||||||
|
|
||||||
|
There are some defects@. Synchronizing the time too often introduces
|
||||||
|
heavy network load@. It introduces heavy load on the target
|
||||||
|
@acronym{NTP} server, too@. You should have a working
|
||||||
|
@acronym{NTP} server nearby that is owned by you@. Also, since
|
||||||
|
@code{settimeofday()} is called so often, high-accurate time
|
||||||
|
operations like timer, @acronym{etc.}, may not run correctly@.
|
||||||
|
|
||||||
|
@findex sleep()
|
||||||
|
@findex alarm()
|
||||||
|
@command{vsntp} uses @code{sleep()} as the synchronization scheduler.
|
||||||
|
Reports show that on some systems @code{sleep()} may not function
|
||||||
|
normally@. If you find @command{vsntp} stops synchronization after
|
||||||
|
running for some time, that the @code{sleep()} is not functioning
|
||||||
|
normally on your system, you may want to switch to the @code{alarm()}
|
||||||
|
scheduler with the @option{-a} switch@.
|
||||||
|
|
||||||
|
If you ever encounter any problem, you may check your syslog@.
|
||||||
|
@command{vsntp} logs detailed debugging information to syslog in log
|
||||||
|
level @code{LOG_DEBUG} with facility @code{LOG_DAEMON}@. You may turn
|
||||||
|
it on in your @file{/etc/syslog.conf} with the following line:
|
||||||
|
|
||||||
|
@example
|
||||||
|
daemon.debug /var/log/debug
|
||||||
|
@end example
|
||||||
|
|
||||||
|
and check the @file{/var/log/debug} file for the debugging message@.
|
||||||
|
Remember to remove this afterwards, for the amount of the debugging
|
||||||
|
messages may be huge and may use up your harddisk in a very short
|
||||||
|
time@. To the least it may slow down your system for frequent
|
||||||
|
harddisk @acronym{I/O}@.
|
||||||
|
|
||||||
|
@command{vsntp} was originally written for @acronym{GNU}/Linux@. It
|
||||||
|
uses @acronym{POSIX} compatible system calls@. It should work on
|
||||||
|
any @acronym{POSIX} compatible system@. But I have yet only tested
|
||||||
|
it on @uref{http://www.cygwin.com/, Cygwin}@. Cygwin is known to
|
||||||
|
work. I don't have others to test and run on. Please
|
||||||
|
let me know (and submit the patch if needed) if you can port it to
|
||||||
|
other systems@. I know it does not work on MSWin32, for the way it
|
||||||
|
handles the @acronym{PID} file path@.
|
||||||
|
|
||||||
|
Please tell me if you have successfully running @command{vsntp} on
|
||||||
|
other virtual machines, like @uref{http://www.vmware.com/, VMWare}@.
|
||||||
|
|
||||||
|
Generally, please tell me if you are using @command{vsntp}@. I
|
||||||
|
would like to know that I am really doing some good for the world,
|
||||||
|
*^_^* but not having fun myself@. :p
|
||||||
|
|
||||||
|
|
||||||
|
@node Download
|
||||||
|
@chapter Download the Newest Version
|
||||||
|
|
||||||
|
@cindex website
|
||||||
|
@cindex official website
|
||||||
|
@cindex download
|
||||||
|
@cindex SourceForge
|
||||||
|
@cindex Tavern IMACAT's
|
||||||
|
@command{vsntp}'s official website is at@dots{}
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
@uref{https://sourceforge.net/,SourceForge}'s home site:
|
||||||
|
@uref{http://vsntp.sourceforge.net/}
|
||||||
|
|
||||||
|
@item
|
||||||
|
@uref{https://sourceforge.net/,SourceForge}'s project page:
|
||||||
|
@uref{https://sourceforge.net/projects/vsntp/}
|
||||||
|
|
||||||
|
@item
|
||||||
|
@uref{http://www.imacat.idv.tw/,Tavern IMACAT's} page:
|
||||||
|
@uref{http://www.imacat.idv.tw/tech/vsntp.html}
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
You can always download the newest version of @command{vsntp}
|
||||||
|
from@dots{}
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
SourceForge:
|
||||||
|
@uref{https://sourceforge.net/project/showfiles.php?group_id=99098}
|
||||||
|
|
||||||
|
@item
|
||||||
|
Tavern IMACAT's @acronym{FTP}:
|
||||||
|
@uref{ftp://ftp.imacat.idv.tw/pub/vsntp/}
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
imacat's @acronym{PGP} public key is at@dots{}
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
SourceForge:
|
||||||
|
@uref{http://vsntp.sourceforge.net/pgpkey.asc}
|
||||||
|
|
||||||
|
@item
|
||||||
|
Tavern IMACAT's:
|
||||||
|
@uref{http://www.imacat.idv.tw/me/pgpkey.asc}
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@node Install
|
||||||
|
@chapter Compilation and Installation
|
||||||
|
@command{vsntp} uses standard @acronym{GNU} @command{autoconf} to
|
||||||
|
compile and install:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
Download, unzip and untar the @command{vsntp} package:
|
||||||
|
@example
|
||||||
|
% tar xzf vsntp-@value{VERSION}.tar.gz
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item
|
||||||
|
Go into its directory:
|
||||||
|
@example
|
||||||
|
% cd vsntp-@value{VERSION}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@pindex configure
|
||||||
|
@item
|
||||||
|
Configure with @command{./configure}:
|
||||||
|
@example
|
||||||
|
% ./configure
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item
|
||||||
|
Compile with @command{make}:
|
||||||
|
@example
|
||||||
|
% make
|
||||||
|
@end example
|
||||||
|
The resulted executable will be named @file{vsntp}@.
|
||||||
|
|
||||||
|
@item
|
||||||
|
You need to be @code{root} in order to install @command{vsntp}:
|
||||||
|
|
||||||
|
@example
|
||||||
|
% su
|
||||||
|
Password:
|
||||||
|
#
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item
|
||||||
|
You can simply copy @command{vsntp} to the appropriate directory:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# cp vsntp /usr/local/sbin
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Or, you can run automatic install:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# make install
|
||||||
|
@end example
|
||||||
|
|
||||||
|
You can reduce the size of the installed executable by stripping off
|
||||||
|
debug symbols inside:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# make install-strip
|
||||||
|
@end example
|
||||||
|
|
||||||
|
By default @command{vsntp} will be installed in
|
||||||
|
@file{/usr/local/sbin}@.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
|
||||||
|
@node Run
|
||||||
|
@chapter Running and Stopping
|
||||||
|
You need to be @code{root} to run @command{vsntp}@. @command{vsntp}
|
||||||
|
uses @code{settimeofday()} to set the system time@.
|
||||||
|
@code{settimeofday()} requires @code{root} privilege@.
|
||||||
|
|
||||||
|
To start @command{vsntp}, just specify your @acronym{NTP} server:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# vsntp my.ntp.server.com
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@command{vsntp} writes its @acronym{PID} in
|
||||||
|
@file{/var/run/vsntp.pid}@. To stop @command{vsntp}, @command{kill}
|
||||||
|
it by its @acronym{PID}:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# kill `cat /var/run/vsntp.pid`
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The @acronym{PID} file location can be changed with the @option{-p}
|
||||||
|
switch.
|
||||||
|
|
||||||
|
|
||||||
|
@node Options
|
||||||
|
@chapter Command Line Options
|
||||||
|
|
||||||
|
@defopt{-i,--interval} @var{n}
|
||||||
|
Set the synchronization interval to @var{n} seconds@. Default is
|
||||||
|
900@dmn{sec} (15@dmn{min})@.
|
||||||
|
@end defopt
|
||||||
|
|
||||||
|
@defopt{-p,--pidfile} @var{file}
|
||||||
|
The @acronym{PID} file location@. Default to @file{/var/run/vsntp.pid}@.
|
||||||
|
@end defopt
|
||||||
|
|
||||||
|
@defopt{-s,--sleep}
|
||||||
|
Use @code{sleep()} to schedule synchronization@. (default)
|
||||||
|
@end defopt
|
||||||
|
|
||||||
|
@defopt{-a,--alarm}
|
||||||
|
Use @code{alarm()} to schedule synchronization@.
|
||||||
|
@end defopt
|
||||||
|
|
||||||
|
@defopt{-h,--help}
|
||||||
|
Display the help message@.
|
||||||
|
@end defopt
|
||||||
|
|
||||||
|
@defopt{-v,--version}
|
||||||
|
Display version information@.
|
||||||
|
@end defopt
|
||||||
|
|
||||||
|
|
||||||
|
@node Support
|
||||||
|
@chapter Supports and Bugs Report
|
||||||
|
|
||||||
|
@cindex SourceForge
|
||||||
|
@cindex Tavern IMACAT's
|
||||||
|
@command{vsntp} is hosted on
|
||||||
|
@uref{https://sourceforge.net/,SourceForge} and
|
||||||
|
@uref{http://www.imacat.idv.tw/,Tavern IMACAT's}@. For the latest
|
||||||
|
infomation, see:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
@uref{http://vsntp.sourceforge.net/}
|
||||||
|
@item
|
||||||
|
@uref{https://sourceforge.net/projects/vsntp/}
|
||||||
|
@item
|
||||||
|
@uref{http://www.imacat.idv.tw/tech/vsntp.html}
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@cindex mailing list
|
||||||
|
@cindex Mailman
|
||||||
|
@command{vsntp} has a mailing list hosted at
|
||||||
|
@uref{https://sourceforge.net/,SourceForge}:
|
||||||
|
@email{vsntp-users@@lists.sourceforge.net}@. Please submit your
|
||||||
|
questions, suggestions or bug reports there@. It is a
|
||||||
|
@uref{http://www.list.org/,Mailman} mailing list@. For more
|
||||||
|
information, see:
|
||||||
|
@uref{https://lists.sourceforge.net/lists/listinfo/vsntp-users}@.
|
||||||
|
Alternatively, you can send a mail to:
|
||||||
|
@email{vsntp-users-request@@lists.sourceforge.net}
|
||||||
|
with the subject @code{help} for a list of available e-mail
|
||||||
|
commands@.
|
||||||
|
|
||||||
|
|
||||||
|
@node References
|
||||||
|
@unnumbered References
|
||||||
|
|
||||||
|
@findex settimeofday()
|
||||||
|
@findex adjtimex()
|
||||||
|
@pindex ntp
|
||||||
|
@cindex RFC 1769 SNTP
|
||||||
|
@cindex RFC 1305 NTP
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
@inforef{High-Resolution Calendar, ,libc}, for settimeofday() and adjtimex().
|
||||||
|
@inforef{Setting an Alarm, ,libc}, for alarm().
|
||||||
|
@inforef{Sleeping, ,libc}, for sleep().
|
||||||
|
@item
|
||||||
|
@uref{http://www.ntp.org/,ntp}
|
||||||
|
@item
|
||||||
|
@uref{http://www.faqs.org/rfcs/rfc1769.html,@acronym{RFC} 1769 @acronym{SNTP}}.
|
||||||
|
@item
|
||||||
|
@uref{http://www.faqs.org/rfcs/rfc1305.html,@acronym{RFC} 1305 @acronym{NTP}}.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@node Copyright
|
||||||
|
@unnumbered Copyright
|
||||||
|
|
||||||
|
@quotation
|
||||||
|
Copyright @copyright{} 2003-2007 imacat@.
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the @cite{@acronym{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 @emph{WITHOUT ANY WARRANTY}; without even the implied warranty of
|
||||||
|
@emph{MERCHANTABILITY} or @emph{FITNESS FOR A PARTICULAR PURPOSE}@.
|
||||||
|
See the @cite{@acronym{GNU} General Public License} for more details@.
|
||||||
|
|
||||||
|
You should have received a copy of the @cite{@acronym{GNU} General
|
||||||
|
Public License} along with this program@. If not, see
|
||||||
|
<@uref{http://www.gnu.org/licenses/}>@.
|
||||||
|
@end quotation
|
||||||
|
|
||||||
|
@node Index
|
||||||
|
@unnumbered Index
|
||||||
|
@printindex cp
|
||||||
|
@bye
|
||||||
|
|
||||||
|
@bye
|
21
init.d/Makefile.am
Normal file
21
init.d/Makefile.am
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
## Makefile.in template file for vsntp init.d directory
|
||||||
|
## Process this file with automake to produce Makefile.in
|
||||||
|
##
|
||||||
|
## Copyright (c) 2007 imacat
|
||||||
|
##
|
||||||
|
## 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, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = gnits
|
||||||
|
|
||||||
|
EXTRA_DIST = README* vsntp vsntp.debian vsntp.redhat
|
62
init.d/README
Normal file
62
init.d/README
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
vsntp SysV init.d start-up scripts README
|
||||||
|
|
||||||
|
TABLE OF CONTENTS
|
||||||
|
|
||||||
|
* Preface
|
||||||
|
* Debian Based Systems
|
||||||
|
* Red Hat Based Systems
|
||||||
|
|
||||||
|
PREFACE
|
||||||
|
|
||||||
|
Two SysV-styled init.d scripts are supplied with vsntp from 2.0.0,
|
||||||
|
together with one configuration file. One of them is for Debian based
|
||||||
|
systems (Knoppix, Ubuntu... etc.) The other is for Red Hat based systems
|
||||||
|
(Fedora, Mandriva... etc.) They are not installed by default. You may
|
||||||
|
install them so that vsntp will start as a daemon after each reboot.
|
||||||
|
|
||||||
|
Installion is easy. You have to be root.
|
||||||
|
|
||||||
|
DEBIAN BASED SYSTEMS
|
||||||
|
|
||||||
|
Copy the files to their appropriate directory:
|
||||||
|
|
||||||
|
# cp vsntp.debian /etc/init.d/vsntp
|
||||||
|
# cp vsntp /etc/default/vsntp
|
||||||
|
|
||||||
|
Edit /etc/default/vsntp to accommodate your environment. Remember
|
||||||
|
to uncomment the line with "SERVER=" and change it to your local NTP
|
||||||
|
server. Once finished, run:
|
||||||
|
|
||||||
|
# /etc/init.d/vsntp start
|
||||||
|
|
||||||
|
And watch the syslog. vsntp shall start working.
|
||||||
|
|
||||||
|
To run it every time the system boots, use updat-rc.d:
|
||||||
|
|
||||||
|
# update-rc.d vsntp defaults 23
|
||||||
|
|
||||||
|
23 is taken from the start/stop order of the Debian ntp package.
|
||||||
|
You may set it to your preferred order.
|
||||||
|
|
||||||
|
RED HAT BASED SYSTEMS
|
||||||
|
|
||||||
|
Copy the files to their appropriate directory:
|
||||||
|
|
||||||
|
# cp vsntp.redhat /etc/init.d/vsntp
|
||||||
|
# cp vsntp /etc/sysconfig/vsntp
|
||||||
|
|
||||||
|
Edit /etc/sysconfig/vsntp to accommodate your environment. Remember
|
||||||
|
to uncomment the line with "SERVER=" and change it to your local NTP
|
||||||
|
server. Once finished, run:
|
||||||
|
|
||||||
|
# /etc/init.d/vsntp start
|
||||||
|
|
||||||
|
And watch the syslog. vsntp shall start working.
|
||||||
|
|
||||||
|
To run it every time the system boots, use chkconfig:
|
||||||
|
|
||||||
|
# chkconfig --add vsntp
|
||||||
|
|
||||||
|
imacat
|
||||||
|
imacat@mail.imacat.idv.tw
|
||||||
|
2007-03-30
|
59
init.d/README.zh-cn
Normal file
59
init.d/README.zh-cn
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
vsntp SysV init.d 启动程式读我说明
|
||||||
|
|
||||||
|
目录
|
||||||
|
|
||||||
|
* 前言
|
||||||
|
* Debian 类系统
|
||||||
|
* Red Hat 类系统
|
||||||
|
|
||||||
|
前言
|
||||||
|
|
||||||
|
自 2.0.0 版起, vsntp 新增了两个 SysV 式的启动程式,及一个启动设定档。
|
||||||
|
一个程式是 Debian 类的系统(如 Knoppix 、 Ubuntu 等)专用,另一个则是
|
||||||
|
Red Hat 类系统专用(如 Fedora 、 Mandriva 等)。安装 vsntp 时,不会自动安
|
||||||
|
装这些档案。若你希望每次系统启动都会自动启动 vsntp ,你可以安装这些档案。
|
||||||
|
|
||||||
|
安装不难。你要先切为 root 的权限。
|
||||||
|
|
||||||
|
Debian 类系统
|
||||||
|
|
||||||
|
将档案复制到相关目录:
|
||||||
|
|
||||||
|
# cp vsntp.debian /etc/init.d/vsntp
|
||||||
|
# cp vsntp /etc/default/vsntp
|
||||||
|
|
||||||
|
编辑 /etc/default/vsntp ,依你的环境需求修改其中的设定。记得一定要将
|
||||||
|
SERVER= 那一行前的 # 符号去掉,改为你自己架的时间伺服器。改好后,执行:
|
||||||
|
|
||||||
|
# /etc/init.d/vsntp start
|
||||||
|
|
||||||
|
查阅 syslog 记录档,应该就会开始校时了。
|
||||||
|
|
||||||
|
若要在每次系统启动时自动执行,可以跑 updat-rc.d :
|
||||||
|
|
||||||
|
# update-rc.d vsntp defaults 23
|
||||||
|
|
||||||
|
23 是 Debian NTP 套件的启动顺序。你也可以自设适当的启动顺序。
|
||||||
|
|
||||||
|
Red Hat 类系统
|
||||||
|
|
||||||
|
将档案复制到相关目录:
|
||||||
|
|
||||||
|
# cp vsntp.redhat /etc/init.d/vsntp
|
||||||
|
# cp vsntp /etc/sysconfig/vsntp
|
||||||
|
|
||||||
|
编辑 /etc/sysconfig/vsntp ,依你的环境需求修改其中的设定。记得一定
|
||||||
|
要将 SERVER= 那一行前的 # 符号去掉,改为你自己架的时间伺服器。改好后,
|
||||||
|
执行:
|
||||||
|
|
||||||
|
# /etc/init.d/vsntp start
|
||||||
|
|
||||||
|
查阅 syslog 记录档,应该就会开始校时了。
|
||||||
|
|
||||||
|
若要在每次系统启动时自动执行,可以跑 chkconfig :
|
||||||
|
|
||||||
|
# chkconfig --add vsntp
|
||||||
|
|
||||||
|
依玛猫
|
||||||
|
imacat@mail.imacat.idv.tw
|
||||||
|
2007-03-30
|
59
init.d/README.zh-tw
Normal file
59
init.d/README.zh-tw
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
vsntp SysV init.d 啟動程式讀我說明
|
||||||
|
|
||||||
|
目錄
|
||||||
|
|
||||||
|
* 前言
|
||||||
|
* Debian 類系統
|
||||||
|
* Red Hat 類系統
|
||||||
|
|
||||||
|
前言
|
||||||
|
|
||||||
|
自 2.0.0 版起, vsntp 新增了兩個 SysV 式的啟動程式,及一個啟動設定檔。
|
||||||
|
一個程式是 Debian 類的系統(如 Knoppix 、 Ubuntu 等)專用,另一個則是
|
||||||
|
Red Hat 類系統專用(如 Fedora 、 Mandriva 等)。安裝 vsntp 時,不會自動安
|
||||||
|
裝這些檔案。若妳希望每次系統啟動都會自動啟動 vsntp ,妳可以安裝這些檔案。
|
||||||
|
|
||||||
|
安裝不難。妳要先切為 root 的權限。
|
||||||
|
|
||||||
|
Debian 類系統
|
||||||
|
|
||||||
|
將檔案複製到相關目錄:
|
||||||
|
|
||||||
|
# cp vsntp.debian /etc/init.d/vsntp
|
||||||
|
# cp vsntp /etc/default/vsntp
|
||||||
|
|
||||||
|
編輯 /etc/default/vsntp ,依妳的環境需求修改其中的設定。記得一定要將
|
||||||
|
SERVER= 那一行前的 # 符號去掉,改為妳自己架的時間伺服器。改好後,執行:
|
||||||
|
|
||||||
|
# /etc/init.d/vsntp start
|
||||||
|
|
||||||
|
查閱 syslog 記錄檔,應該就會開始校時了。
|
||||||
|
|
||||||
|
若要在每次系統啟動時自動執行,可以跑 updat-rc.d :
|
||||||
|
|
||||||
|
# update-rc.d vsntp defaults 23
|
||||||
|
|
||||||
|
23 是 Debian NTP 套件的啟動順序。妳也可以自設適當的啟動順序。
|
||||||
|
|
||||||
|
Red Hat 類系統
|
||||||
|
|
||||||
|
將檔案複製到相關目錄:
|
||||||
|
|
||||||
|
# cp vsntp.redhat /etc/init.d/vsntp
|
||||||
|
# cp vsntp /etc/sysconfig/vsntp
|
||||||
|
|
||||||
|
編輯 /etc/sysconfig/vsntp ,依妳的環境需求修改其中的設定。記得一定
|
||||||
|
要將 SERVER= 那一行前的 # 符號去掉,改為妳自己架的時間伺服器。改好後,
|
||||||
|
執行:
|
||||||
|
|
||||||
|
# /etc/init.d/vsntp start
|
||||||
|
|
||||||
|
查閱 syslog 記錄檔,應該就會開始校時了。
|
||||||
|
|
||||||
|
若要在每次系統啟動時自動執行,可以跑 chkconfig :
|
||||||
|
|
||||||
|
# chkconfig --add vsntp
|
||||||
|
|
||||||
|
依瑪貓
|
||||||
|
imacat@mail.imacat.idv.tw
|
||||||
|
2007-03-30
|
13
init.d/vsntp
Normal file
13
init.d/vsntp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# SNTP client for Virtual PC configuration file
|
||||||
|
# by imacat <imacat@mail.imacat.idv.tw> 2007-03-29
|
||||||
|
|
||||||
|
# SERVER: The server. Uncomment this line and replace it with YOUR LOCAL NTP SERVER.
|
||||||
|
# This must be set and cannot be commented out.
|
||||||
|
#SERVER=my.ntp.server.com
|
||||||
|
|
||||||
|
# SCHEDULER: Choose the scheduler. Currently either "sleep" or "alarm"
|
||||||
|
# Values that are not "alarm" are treated as "sleep".
|
||||||
|
SCHEDULER=sleep
|
||||||
|
|
||||||
|
# SYNC_INTERVAL: The synchronization interval, in seconds. The default is 900.
|
||||||
|
SYNC_INTERVAL=900
|
182
init.d/vsntp.debian
Executable file
182
init.d/vsntp.debian
Executable file
@ -0,0 +1,182 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# start and stop the SNTP client for Virtual PC
|
||||||
|
|
||||||
|
# LSB-convension comments
|
||||||
|
# See: http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: vsntp
|
||||||
|
# Required-Start: $network $time
|
||||||
|
# Required-Stop:
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: start and stop the SNTP client for Virtual PC
|
||||||
|
# Description: vsntp is a SNTP client for Virtual PC that synchronize
|
||||||
|
# time periodically for systems without hardward RTC.
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
|
||||||
|
THISFILE=${0##*/}
|
||||||
|
VERSION=1.1.0
|
||||||
|
AUTHORNAME=imacat
|
||||||
|
AUTHORMAIL=imacat@mail.imacat.idv.tw
|
||||||
|
DESC="SNTP client for Virtual PC"
|
||||||
|
THISCONF=/etc/default/vsntp
|
||||||
|
|
||||||
|
# source the configuration
|
||||||
|
test -e $THISCONF && . $THISCONF
|
||||||
|
case "$SCHEDULER" in
|
||||||
|
alarm|a|-a|--alarm)
|
||||||
|
SCHEDULER=-a ;;
|
||||||
|
*)
|
||||||
|
SCHEDULER=-s ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
BINPATH=/usr/sbin/vsntp
|
||||||
|
BINNAME=${BINPATH##*/}
|
||||||
|
PIDFILE=/var/run/$BINNAME.pid
|
||||||
|
RUNUSER=root
|
||||||
|
|
||||||
|
# default values -- do not change anything here
|
||||||
|
_DEFSYNC_INTERVAL=900
|
||||||
|
_DEFSCHEDULER=-s
|
||||||
|
|
||||||
|
# startup options
|
||||||
|
OPTS=""
|
||||||
|
test -n "$SCHEDULER" -a "$SCHEDULER" != "$_DEFSCHEDULER" && OPTS="$OPTS $SCHEDULER"
|
||||||
|
test -n "$SYNC_INTERVAL" -a "$SYNC_INTERVAL" != "$_DEFSYNC_INTERVAL" && OPTS="$OPTS -i $SYNC_INTERVAL"
|
||||||
|
OPTS="$OPTS $SERVER"
|
||||||
|
|
||||||
|
# sanity checks
|
||||||
|
if test ! -n "$SERVER"; then
|
||||||
|
echo "$THISFILE: You must set the SERVER in $THISCONF" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if test ! -x $BINPATH; then
|
||||||
|
echo "$THISFILE: Missing valid daemon program at $BINPATH" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if test -n "$USER" -a ! "$USER" = "root"; then
|
||||||
|
echo "$THISFILE: You need to be root to run this script." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
start () {
|
||||||
|
echo -n "Starting $DESC:"
|
||||||
|
RETVAL=0
|
||||||
|
|
||||||
|
echo -n " $BINNAME"
|
||||||
|
start-stop-daemon --start --startas $BINPATH --quiet \
|
||||||
|
--pidfile $PIDFILE --name $BINNAME --user $RUNUSER --exec $BINPATH -- $OPTS
|
||||||
|
RETVALS=$?
|
||||||
|
test $RETVALS = 0 || { echo -n ":failed"; RETVAL=$RETVALS; }
|
||||||
|
|
||||||
|
echo "."
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
stop () {
|
||||||
|
echo -n "Stopping $DESC:"
|
||||||
|
RETVAL=0
|
||||||
|
|
||||||
|
echo -n " $BINNAME"
|
||||||
|
start-stop-daemon --stop --quiet \
|
||||||
|
--pidfile $PIDFILE --name $BINNAME --user $RUNUSER --exec $BINPATH
|
||||||
|
RETVALS=$?
|
||||||
|
test $RETVALS = 0 || { echo -n ":failed"; RETVAL=$RETVALS; }
|
||||||
|
rm -f $PIDFILE
|
||||||
|
|
||||||
|
echo "."
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
restart () {
|
||||||
|
stop
|
||||||
|
sleep 1
|
||||||
|
start
|
||||||
|
RETVAL=$?
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
status () {
|
||||||
|
RETVAL=0
|
||||||
|
|
||||||
|
start-stop-daemon --stop --signal 0 --quiet \
|
||||||
|
--pidfile $PIDFILE --name $BINNAME --user $RUNUSER --exec $BINPATH
|
||||||
|
RETVALS=$?
|
||||||
|
if test $RETVALS = 0; then
|
||||||
|
echo "$DESC $BINNAME is up and running ($(<$PIDFILE))."
|
||||||
|
else
|
||||||
|
echo "$DESC $BINNAME is not running (or some problem may exists)."
|
||||||
|
RETVAL=$RETVALS
|
||||||
|
fi
|
||||||
|
|
||||||
|
return $RETVAL
|
||||||
|
}
|
||||||
|
|
||||||
|
# parse the arguments
|
||||||
|
while test $# != 0; do
|
||||||
|
case "$1" in
|
||||||
|
start|stop|restart|force-reload|status)
|
||||||
|
action="$1"
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
cat << EOF
|
||||||
|
Start and/or stop the $DESC
|
||||||
|
Usage: $THISFILE {start|stop|restart|force-reload|status}
|
||||||
|
|
||||||
|
start Start the daemon.
|
||||||
|
stop Stop the daemon.
|
||||||
|
restart Stop and restart the daemon.
|
||||||
|
force-reload Enforce a reload to the configuration file.
|
||||||
|
status Display the daemon status.
|
||||||
|
-h,--help Display this help.
|
||||||
|
-v,--version Display the version infomation.
|
||||||
|
|
||||||
|
Report bugs to $AUTHORNAME <$AUTHORMAIL>
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-v|--version)
|
||||||
|
cat << EOF
|
||||||
|
$THISFILE version $VERSION by $AUTHORNAME <$AUTHORMAIL>
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$THISFILE: unrecognized argument: $1" >&2
|
||||||
|
echo "Try \`$THISFILE --help' for more infomation" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# no action specified
|
||||||
|
if test -z "$action"; then
|
||||||
|
echo "$THISFILE: what do you want to do now?" >&2
|
||||||
|
echo "Try \`$THISFILE --help' for more infomation" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# act now!
|
||||||
|
case "$action" in
|
||||||
|
start)
|
||||||
|
start
|
||||||
|
RETVAL=$?
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop
|
||||||
|
RETVAL=$?
|
||||||
|
;;
|
||||||
|
restart|force-reload)
|
||||||
|
restart
|
||||||
|
RETVAL=$?
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
status
|
||||||
|
RETVAL=$?
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit $RETVAL
|
148
init.d/vsntp.redhat
Executable file
148
init.d/vsntp.redhat
Executable file
@ -0,0 +1,148 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# start and stop the SNTP client for Virtual PC
|
||||||
|
|
||||||
|
# Red Hat styled comments for chkconfig
|
||||||
|
# chkconfig: 2345 58 74
|
||||||
|
# description: SNTP client for Virtual PC
|
||||||
|
# processname: vsntp
|
||||||
|
# config: /etc/sysconfig/vsntp
|
||||||
|
|
||||||
|
# LSB-convension comments
|
||||||
|
# See: http://refspecs.freestandards.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/initscrcomconv.html
|
||||||
|
### BEGIN INIT INFO
|
||||||
|
# Provides: vsntp
|
||||||
|
# Required-Start: $network $time
|
||||||
|
# Required-Stop:
|
||||||
|
# Default-Start: 2 3 4 5
|
||||||
|
# Default-Stop: 0 1 6
|
||||||
|
# Short-Description: start and stop the SNTP client for Virtual PC
|
||||||
|
# Description: vsntp is a SNTP client for Virtual PC that synchronize
|
||||||
|
# time periodically for systems without hardward RTC.
|
||||||
|
### END INIT INFO
|
||||||
|
|
||||||
|
export PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
|
|
||||||
|
# initialize the environment
|
||||||
|
THISFILE="${0##*/}"
|
||||||
|
VERSION="1.0.0"
|
||||||
|
AUTHORNAME=imacat
|
||||||
|
AUTHORMAIL=imacat@mail.imacat.idv.tw
|
||||||
|
lock=/var/lock/subsys/vsntp
|
||||||
|
|
||||||
|
# Source function library.
|
||||||
|
. /etc/init.d/functions
|
||||||
|
|
||||||
|
# Source networking configuration.
|
||||||
|
. /etc/sysconfig/network
|
||||||
|
|
||||||
|
# Check that networking is up.
|
||||||
|
[ ${NETWORKING} = "no" ] && exit 0
|
||||||
|
|
||||||
|
if [ -f /etc/sysconfig/vsntp ];then
|
||||||
|
. /etc/sysconfig/vsntp
|
||||||
|
fi
|
||||||
|
case "$SCHEDULER" in
|
||||||
|
alarm|a|-a|--alarm)
|
||||||
|
SCHEDULER=-a ;;
|
||||||
|
*)
|
||||||
|
SCHEDULER=-s ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# default values -- do not change anything here
|
||||||
|
_DEFSYNC_INTERVAL=900
|
||||||
|
_DEFSCHEDULER=-s
|
||||||
|
|
||||||
|
RETVAL="0"
|
||||||
|
OPTIONS=""
|
||||||
|
test -n "$SCHEDULER" -a "$SCHEDULER" != "$_DEFSCHEDULER" && OPTIONS="$OPTIONS $SCHEDULER"
|
||||||
|
test -n "$SYNC_INTERVAL" -a "$SYNC_INTERVAL" != "$_DEFSYNC_INTERVAL" && OPTIONS="$OPTIONS -i $SYNC_INTERVAL"
|
||||||
|
OPTIONS="$OPTIONS $SERVER"
|
||||||
|
|
||||||
|
# See how we were called.
|
||||||
|
start() {
|
||||||
|
echo -n "Starting SNTP client for Virtual PC: "
|
||||||
|
daemon vsntp $OPTIONS
|
||||||
|
RETVAL="$?"
|
||||||
|
echo
|
||||||
|
[ "$RETVAL" -eq "0" ] && touch $lock
|
||||||
|
return "$RETVAL"
|
||||||
|
}
|
||||||
|
stop() {
|
||||||
|
echo -n "Stopping SNTP client for Virtual PC: "
|
||||||
|
killproc vsntp
|
||||||
|
RETVAL="$?"
|
||||||
|
echo
|
||||||
|
[ "$RETVAL" -eq "0" ] && rm -f $lock
|
||||||
|
return "$RETVAL"
|
||||||
|
}
|
||||||
|
rhstatus() {
|
||||||
|
status vsntp
|
||||||
|
}
|
||||||
|
restart() {
|
||||||
|
stop
|
||||||
|
start
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# parse the arguments
|
||||||
|
while [ "$#" != "0" ]; do
|
||||||
|
case "$1" in
|
||||||
|
start|stop|restart|status)
|
||||||
|
action="$1"
|
||||||
|
;;
|
||||||
|
-h|--help)
|
||||||
|
cat << EOF
|
||||||
|
Start and/or stop the SNTP client for Virtual PC
|
||||||
|
Usage: $THISFILE {start|stop|restart|status}
|
||||||
|
|
||||||
|
start Start the daemon.
|
||||||
|
stop Stop the daemon.
|
||||||
|
restart Stop and restart the daemon.
|
||||||
|
status Display the daemon status
|
||||||
|
-h,--help Display this help.
|
||||||
|
-v,--version Display the version infomation.
|
||||||
|
|
||||||
|
Report bugs to $AUTHORNAME <$AUTHORMAIL>
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-v|--version)
|
||||||
|
cat << EOF
|
||||||
|
$THISFILE v$VERSION by $AUTHORNAME <$AUTHORMAIL>
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$THISFILE: unrecognized argument: $1"
|
||||||
|
echo "Try \`$THISFILE --help' for more infomation"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# check the arguments
|
||||||
|
if [ -z "$action" ]; then
|
||||||
|
cat << EOF
|
||||||
|
Usage: $THISFILE {start|stop|restart|status}
|
||||||
|
EOF
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# process now
|
||||||
|
case "$action" in
|
||||||
|
start)
|
||||||
|
start
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
stop
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
restart
|
||||||
|
;;
|
||||||
|
status)
|
||||||
|
rhstatus
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit $?
|
960
vsntp.c
Normal file
960
vsntp.c
Normal file
@ -0,0 +1,960 @@
|
|||||||
|
/* SNTP for Virtual PC */
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003-2007 imacat.
|
||||||
|
|
||||||
|
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, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Filename: vsntp.c
|
||||||
|
Description: SNTP for Virtual PC
|
||||||
|
Author: imacat <imacat@mail.imacat.idv.tw>
|
||||||
|
Date: 2003-12-22
|
||||||
|
Copyright: (c) 2003-2007 imacat */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Headers */
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
extern int h_errno;
|
||||||
|
|
||||||
|
/* Configuration */
|
||||||
|
#define AUTHOR "imacat"
|
||||||
|
#define AUTHORMAIL "imacat@mail.imacat.idv.tw"
|
||||||
|
#define EXEC_USER "root"
|
||||||
|
#define PIDDIR "/var/run"
|
||||||
|
#define DEFAULT_INTERVAL 900
|
||||||
|
#define MAX_NETWORK_ERROR 1200
|
||||||
|
#define SNTP_PORT 123
|
||||||
|
#define SCHEDULER_SLEEP 1
|
||||||
|
#define SCHEDULER_ALARM 2
|
||||||
|
#define DEFAULT_SCHEDULER SCHEDULER_SLEEP
|
||||||
|
|
||||||
|
#define VERSTR "\
|
||||||
|
%s v%s, Copyright (C) 2003-2007 %s\n\
|
||||||
|
This is free software; see the source for copying conditions. There is NO\n\
|
||||||
|
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||||
|
\n"
|
||||||
|
|
||||||
|
#define LONGHELP "\
|
||||||
|
Usage: %s [-i n] [-p file] [-a|-s] server\n\
|
||||||
|
Synchronize the system time against a time server periodically. It\n\
|
||||||
|
uses RFC 1361 SNTP service UDP port 123 to synchronize the time. You\n\
|
||||||
|
may need to be root to synchronize the system time.\n\
|
||||||
|
\n\
|
||||||
|
-i,--interval n Set the synchronization interval to n seconds. (%d)\n\
|
||||||
|
-p,--pidfile file The PID file location. (%s)\n\
|
||||||
|
-s,--sleep Use sleep() to schedule synchronization. (default)\n\
|
||||||
|
-a,--alarm Use alarm() to schedule synchronization.\n\
|
||||||
|
-h,--help Display this help.\n\
|
||||||
|
-v,--version Display version information.\n\
|
||||||
|
server Time server to synchronize against.\n\
|
||||||
|
\n"
|
||||||
|
|
||||||
|
#define EXIT_OK 0
|
||||||
|
#define EXIT_ARGERR 1
|
||||||
|
#define EXIT_NETERR 2
|
||||||
|
#define EXIT_SYSERR 127
|
||||||
|
|
||||||
|
#define EPOCH_DIFF ((unsigned long) 86400 * (365 * 70 + 17))
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
void set_this_file (char *argv0);
|
||||||
|
void parse_args (int argc, char *argv[]);
|
||||||
|
void check_priv (void);
|
||||||
|
void xexit (int status)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
void verror (int status, char *message, va_list ap)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
void error (int status, char *message, ...)
|
||||||
|
__attribute__((noreturn, format(printf, 2, 3)));
|
||||||
|
void vwarn (char *message, va_list ap);
|
||||||
|
void warn (char *message, ...)
|
||||||
|
__attribute__((format(printf, 1, 2)));
|
||||||
|
void neterror (int firstsync, time_t errstart, char *message, ...)
|
||||||
|
__attribute__((format(printf, 3, 4)));
|
||||||
|
void sigterm_exit (int signum)
|
||||||
|
__attribute__((noreturn));
|
||||||
|
void daemonize (void);
|
||||||
|
void makepid (void);
|
||||||
|
void setsigterm (void);
|
||||||
|
#ifdef HAVE_ALARM
|
||||||
|
void setsigalrm (void);
|
||||||
|
void alarm_wakeup (int signum);
|
||||||
|
#endif
|
||||||
|
double synctime (void);
|
||||||
|
|
||||||
|
void fork2background (void);
|
||||||
|
void closeall (void);
|
||||||
|
unsigned long fromnetnum (const char *oct);
|
||||||
|
const char *tonetnum (unsigned long num);
|
||||||
|
unsigned long usec2frac (long usec);
|
||||||
|
long frac2usec (unsigned long frac);
|
||||||
|
|
||||||
|
void *xmalloc (size_t size);
|
||||||
|
char *xstrcpy (const char *src);
|
||||||
|
char *xstrcat (int n, ...);
|
||||||
|
time_t xtime (time_t *t);
|
||||||
|
void xgettimeofday (struct timeval *tv, struct timezone *tz);
|
||||||
|
void xsettimeofday (const struct timeval *tv , const struct timezone *tz);
|
||||||
|
void xchdir (const char *path);
|
||||||
|
pid_t xfork (void);
|
||||||
|
pid_t xsetsid (void);
|
||||||
|
long xsysconf (int name, const char *confname);
|
||||||
|
FILE *xfopen (const char *path, const char *mode);
|
||||||
|
void xfclose (FILE *stream);
|
||||||
|
int xfprintf (FILE *stream, const char *format, ...)
|
||||||
|
__attribute__((format(printf, 2, 3)));
|
||||||
|
void xsigemptyset (sigset_t *set);
|
||||||
|
void xsigaction (int signum, const struct sigaction *act, struct sigaction *oldact);
|
||||||
|
|
||||||
|
/* Variables */
|
||||||
|
char *server_name = NULL, *this_file = NULL, *pidfile = NULL;
|
||||||
|
int interval = -1, daemonized = 0, scheduler = -1;
|
||||||
|
struct sockaddr_in server;
|
||||||
|
time_t next;
|
||||||
|
|
||||||
|
/* Main program */
|
||||||
|
int
|
||||||
|
main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
double toff;
|
||||||
|
|
||||||
|
/* Find this file's name */
|
||||||
|
set_this_file (argv[0]);
|
||||||
|
parse_args (argc, argv);
|
||||||
|
|
||||||
|
/* Synchronize for the first time, to ensure no obvious network errors */
|
||||||
|
toff = synctime ();
|
||||||
|
/* Record the first synchronization */
|
||||||
|
if (toff != 0)
|
||||||
|
syslog (LOG_INFO, "Time adjusted %.6f seconds.", toff);
|
||||||
|
|
||||||
|
/* Daemonize */
|
||||||
|
daemonize ();
|
||||||
|
/* Make the PID file */
|
||||||
|
makepid ();
|
||||||
|
/* Set the way we exit */
|
||||||
|
setsigterm ();
|
||||||
|
|
||||||
|
switch (scheduler)
|
||||||
|
{
|
||||||
|
/* Use sleep() to schedule synchronization */
|
||||||
|
case SCHEDULER_SLEEP:
|
||||||
|
syslog (LOG_INFO, "Using sleep() to schedule synchronization");
|
||||||
|
/* Enter an endless loop of synchronization */
|
||||||
|
while (1) {
|
||||||
|
/* Synchronize the time */
|
||||||
|
toff = synctime ();
|
||||||
|
/* Record the synchronization */
|
||||||
|
if (toff != 0)
|
||||||
|
syslog (LOG_DEBUG, "Time adjusted %.6f seconds.", toff);
|
||||||
|
|
||||||
|
/* Wait until the next time */
|
||||||
|
sleep (interval);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef HAVE_ALARM
|
||||||
|
/* Use alarm() to schedule synchronization */
|
||||||
|
case SCHEDULER_ALARM:
|
||||||
|
/* Set the the synchronization scheduler alerm */
|
||||||
|
setsigalrm ();
|
||||||
|
/* syslog() must follow setaction(), or it crash after the first alarm.
|
||||||
|
To be investigated. */
|
||||||
|
syslog (LOG_INFO, "Using alarm() to schedule synchronization");
|
||||||
|
/* Schedule the next alarm */
|
||||||
|
alarm (interval);
|
||||||
|
/* Enter an endless loop of synchronization
|
||||||
|
pause() is interrupted by every SIGALRM signal.
|
||||||
|
Endless loop of pause() make SIGALRM signals endlessly. */
|
||||||
|
while (1)
|
||||||
|
pause ();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set_this_file: Get the name of this file
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
set_this_file (char *argv0)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
p = rindex (argv0, '/');
|
||||||
|
if (p == NULL)
|
||||||
|
this_file = xstrcpy (argv0);
|
||||||
|
else
|
||||||
|
this_file = xstrcpy (++p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse_args: Parse the arguments.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
parse_args (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
static struct option longopts[] = {
|
||||||
|
{"interval", 1, NULL, 'i'},
|
||||||
|
{"pidfile", 1, NULL, 'p'},
|
||||||
|
{"sleep", 0, NULL, 's'},
|
||||||
|
{"alarm", 0, NULL, 'a'},
|
||||||
|
{"help", 0, NULL, 'h'},
|
||||||
|
{"version", 0, NULL, 'v'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
int i, r, c, c0, longindex = 0;
|
||||||
|
struct in_addr server_addr;
|
||||||
|
struct hostent *server_hostent;
|
||||||
|
void *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
/* Set the default value */
|
||||||
|
interval = DEFAULT_INTERVAL;
|
||||||
|
scheduler = DEFAULT_SCHEDULER;
|
||||||
|
pidfile = xstrcat (4, PIDDIR, "/", this_file, ".pid");
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
c = getopt_long (argc, argv, "i:p:sahv", longopts, &longindex);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'i':
|
||||||
|
r = sscanf (optarg, "%5d%c", &interval, &c0);
|
||||||
|
if (r != 1 || interval <= 0)
|
||||||
|
error (EXIT_ARGERR, "invalid interval: %s.", optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (pidfile != NULL)
|
||||||
|
free (pidfile);
|
||||||
|
pidfile = xstrcpy (optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
scheduler = SCHEDULER_SLEEP;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
scheduler = SCHEDULER_ALARM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
printf (LONGHELP, this_file, interval, pidfile);
|
||||||
|
exit (EXIT_OK);
|
||||||
|
|
||||||
|
case 'v':
|
||||||
|
printf (VERSTR, this_file, VERSION, AUTHOR);
|
||||||
|
exit (EXIT_OK);
|
||||||
|
|
||||||
|
default:
|
||||||
|
exit (EXIT_ARGERR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process each argument */
|
||||||
|
for (i = optind; i < argc; i++)
|
||||||
|
switch (i - optind)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
server_name = xstrcpy (argv[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
error (EXIT_ARGERR, "Too many argument: %s.", argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Process the interval */
|
||||||
|
if (interval == -1)
|
||||||
|
interval = DEFAULT_INTERVAL;
|
||||||
|
|
||||||
|
#ifndef HAVE_ALARM
|
||||||
|
if (scheduler == SCHEDULER_ALARM)
|
||||||
|
error (EXIT_ARGERR, "alarm() is not supported on this platform.");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Process the PID file */
|
||||||
|
/* Compose the default PID file path */
|
||||||
|
if (pidfile == NULL)
|
||||||
|
pidfile = xstrcat (4, PIDDIR, "/", this_file, ".pid");
|
||||||
|
|
||||||
|
/* Process the time server */
|
||||||
|
if (server_name == NULL)
|
||||||
|
error (EXIT_ARGERR, "Please specify the time server.");
|
||||||
|
r = inet_aton (server_name, &server_addr);
|
||||||
|
if (r == 0)
|
||||||
|
{
|
||||||
|
/* Try DNS look up */
|
||||||
|
server_hostent = gethostbyname (server_name);
|
||||||
|
if (server_hostent == NULL)
|
||||||
|
error (EXIT_ARGERR, "%s: %s.", server_name, hstrerror (h_errno));
|
||||||
|
/* Obtain the IP number, reverse the byte order */
|
||||||
|
server_addr.s_addr =
|
||||||
|
((server_hostent->h_addr_list[0][3] << 24) & 0xFF000000) |
|
||||||
|
((server_hostent->h_addr_list[0][2] << 16) & 0x00FF0000) |
|
||||||
|
((server_hostent->h_addr_list[0][1] << 8) & 0x0000FF00) |
|
||||||
|
(server_hostent->h_addr_list[0][0] & 0x000000FF);
|
||||||
|
/* Modify the server name for logging */
|
||||||
|
len = strlen (server_name) + 20;
|
||||||
|
p = (void *) server_name;
|
||||||
|
server_name = (char *) xmalloc (len);
|
||||||
|
snprintf (server_name, len, "%s (%hhu.%hhu.%hhu.%hhu)", (char *) p,
|
||||||
|
server_hostent->h_addr_list[0][0],
|
||||||
|
server_hostent->h_addr_list[0][1],
|
||||||
|
server_hostent->h_addr_list[0][2],
|
||||||
|
server_hostent->h_addr_list[0][3]);
|
||||||
|
free (p);
|
||||||
|
}
|
||||||
|
/* Save the server infomation */
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_addr = server_addr;
|
||||||
|
server.sin_port = htons (SNTP_PORT);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xexit: Properly handle the exit.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xexit (int status)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Proper exit in daemon mode */
|
||||||
|
if (daemonized)
|
||||||
|
{
|
||||||
|
/* Remove the PID file */
|
||||||
|
r = unlink (pidfile);
|
||||||
|
if (r == -1)
|
||||||
|
syslog (LOG_ERR, "%s:%d: unlink %s: %s",
|
||||||
|
__FILE__, __LINE__, pidfile, strerror (errno));
|
||||||
|
/* Close the syslog */
|
||||||
|
closelog ();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* verror: Issue an error with variable argument list */
|
||||||
|
void
|
||||||
|
verror (int status, char *message, va_list ap)
|
||||||
|
{
|
||||||
|
/* Issue the error message */
|
||||||
|
if (daemonized)
|
||||||
|
{
|
||||||
|
vsyslog (LOG_ERR, message, ap);
|
||||||
|
syslog (LOG_ERR, "Exited upon unrecoverable network error.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vfprintf (stderr, message, ap);
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
xexit (status);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* error: Issue an error */
|
||||||
|
void
|
||||||
|
error (int status, char *message, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
/* Handle the error with verror */
|
||||||
|
va_start (ap, message);
|
||||||
|
verror (status, message, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
/* No return */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* vwarn: Issue a warning with variable argument list */
|
||||||
|
void
|
||||||
|
vwarn (char *message, va_list ap)
|
||||||
|
{
|
||||||
|
/* Issue the warning message */
|
||||||
|
if (daemonized)
|
||||||
|
vsyslog (LOG_WARNING, message, ap);
|
||||||
|
else
|
||||||
|
vfprintf (stderr, message, ap);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* warn: Issue a warning */
|
||||||
|
void
|
||||||
|
warn (char *message, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
/* Handle warnings with vwarn */
|
||||||
|
va_start (ap, message);
|
||||||
|
vwarn (message, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* neterror: Issue a network error */
|
||||||
|
void
|
||||||
|
neterror (int firstsync, time_t errstart, char *message, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
va_start (ap, message);
|
||||||
|
|
||||||
|
/* Don't pass it if we can't even synchronize the first time */
|
||||||
|
if (firstsync)
|
||||||
|
verror (EXIT_NETERR, message, ap);
|
||||||
|
|
||||||
|
/* Warn it */
|
||||||
|
vwarn (message, ap);
|
||||||
|
/* Errors lasted for too long */
|
||||||
|
now = xtime (NULL);
|
||||||
|
if (now - errstart > MAX_NETWORK_ERROR)
|
||||||
|
error (EXIT_NETERR, "Exited upon network error exceeding %d seconds.", MAX_NETWORK_ERROR);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sigterm: End the program */
|
||||||
|
void
|
||||||
|
sigterm_exit (int signum)
|
||||||
|
{
|
||||||
|
/* Log the exit */
|
||||||
|
syslog (LOG_INFO, "Exited upon TERM signal.");
|
||||||
|
/* Exit normally */
|
||||||
|
xexit (EXIT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* daemonize: Daemonize the process */
|
||||||
|
/* http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 */
|
||||||
|
void
|
||||||
|
daemonize (void)
|
||||||
|
{
|
||||||
|
/* Fork to be a new process group leader */
|
||||||
|
fork2background ();
|
||||||
|
/* Become a new session group leader, to get rid of the
|
||||||
|
controlling terminal */
|
||||||
|
xsetsid ();
|
||||||
|
/* Fork again to get rid of this new session */
|
||||||
|
fork2background ();
|
||||||
|
/* chdir to "/", to avoid staying on any mounted file system */
|
||||||
|
xchdir ("/");
|
||||||
|
/* Avoid inheriting umasks */
|
||||||
|
umask (0);
|
||||||
|
/* Close all opened file descriptors */
|
||||||
|
closeall ();
|
||||||
|
|
||||||
|
/* Set the flag */
|
||||||
|
daemonized = 1;
|
||||||
|
|
||||||
|
/* Start the syslog */
|
||||||
|
openlog (this_file, LOG_PID, LOG_DAEMON);
|
||||||
|
/* Log the start */
|
||||||
|
syslog (LOG_INFO, "Start synchronization with %s.", server_name);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* makepid: Make the PID file */
|
||||||
|
void
|
||||||
|
makepid (void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
/* Record the PID */
|
||||||
|
pid = getpid ();
|
||||||
|
|
||||||
|
/* Save to the file */
|
||||||
|
fp = xfopen (pidfile, "w");
|
||||||
|
xfprintf (fp, "%d\n", pid);
|
||||||
|
xfclose (fp);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setsigterm: Configure the way we exit */
|
||||||
|
void
|
||||||
|
setsigterm (void)
|
||||||
|
{
|
||||||
|
struct sigaction action;
|
||||||
|
/* Set the TERM signal handler */
|
||||||
|
action.sa_handler = sigterm_exit;
|
||||||
|
/* Block further signals */
|
||||||
|
xsigemptyset (&action.sa_mask);
|
||||||
|
/* Set the TERM signal handler */
|
||||||
|
xsigaction (SIGTERM, &action, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_ALARM
|
||||||
|
/* setsigalrm: Configure the synchronization scheduler alerm */
|
||||||
|
void
|
||||||
|
setsigalrm (void)
|
||||||
|
{
|
||||||
|
struct sigaction action;
|
||||||
|
/* Set the ALRM signal handler */
|
||||||
|
action.sa_handler = alarm_wakeup;
|
||||||
|
/* Block further signals */
|
||||||
|
xsigemptyset (&action.sa_mask);
|
||||||
|
/* Set the TERM signal handler */
|
||||||
|
xsigaction (SIGALRM, &action, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* alarm_wakeup: Wake up on alarm and synchronize the time */
|
||||||
|
void
|
||||||
|
alarm_wakeup (int signum)
|
||||||
|
{
|
||||||
|
double toff;
|
||||||
|
|
||||||
|
/* Synchronize the time */
|
||||||
|
toff = synctime ();
|
||||||
|
/* Record the synchronization */
|
||||||
|
if (toff != 0)
|
||||||
|
syslog (LOG_DEBUG, "Time adjusted %.6f seconds.", toff);
|
||||||
|
|
||||||
|
/* Schedule the next alarm */
|
||||||
|
alarm (interval);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* synctime: Synchronize the time. See RFC 1361.
|
||||||
|
return: Time offset that is synchronized */
|
||||||
|
double
|
||||||
|
synctime (void)
|
||||||
|
{
|
||||||
|
int i, r, udp;
|
||||||
|
static int firstsync = 1;
|
||||||
|
char buf[61];
|
||||||
|
ssize_t len;
|
||||||
|
static time_t errstart = 0;
|
||||||
|
static struct timeval tv1, tv2, tv3, tv4, tvnew;
|
||||||
|
struct timezone tz;
|
||||||
|
double t1, t2, t3, t4, toff, tnew;
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
/* Create the UDP socket */
|
||||||
|
syslog (LOG_DEBUG, "%s:%d: Connecting UDP to %s",
|
||||||
|
__FILE__, __LINE__, server_name);
|
||||||
|
udp = socket (PF_INET, SOCK_DGRAM, 0);
|
||||||
|
/* Initialize the connection */
|
||||||
|
r = connect (udp, (struct sockaddr*) &server, sizeof (server));
|
||||||
|
if (r == -1)
|
||||||
|
{
|
||||||
|
now = xtime (NULL);
|
||||||
|
/* First error */
|
||||||
|
if (errstart == 0)
|
||||||
|
errstart = now;
|
||||||
|
neterror (firstsync, errstart, "%s:%d: connect %s (%d): %s",
|
||||||
|
__FILE__, __LINE__, server_name, now - errstart, strerror (errno));
|
||||||
|
/* Close the opened socket */
|
||||||
|
r = close (udp);
|
||||||
|
if (r != 0)
|
||||||
|
warn ("%s:%d: close udp: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send to the server */
|
||||||
|
/* Pad zeroes */
|
||||||
|
for (i = 0; i < 61; i++)
|
||||||
|
buf[i] = 0;
|
||||||
|
/* 00 001 011 - leap, ntp ver, client. See RFC 1361. */
|
||||||
|
buf[0] = (0 << 6) | (1 << 3) | 3;
|
||||||
|
/* Get the local sent time - Originate Timestamp */
|
||||||
|
xgettimeofday (&tv1, &tz);
|
||||||
|
t1 = (double) tv1.tv_sec + (double) tv1.tv_usec / 1000000;
|
||||||
|
/* Send to the server */
|
||||||
|
memcpy (&buf[40], tonetnum ((unsigned long) tv1.tv_sec + EPOCH_DIFF), 4);
|
||||||
|
memcpy (&buf[44], tonetnum (usec2frac (tv1.tv_usec)), 4);
|
||||||
|
syslog (LOG_DEBUG, "%s:%d: Sending UDP buf to %s",
|
||||||
|
__FILE__, __LINE__, server_name);
|
||||||
|
len = send (udp, buf, 48, 0);
|
||||||
|
if (len == -1)
|
||||||
|
{
|
||||||
|
now = xtime (NULL);
|
||||||
|
/* First error */
|
||||||
|
if (errstart == 0)
|
||||||
|
errstart = now;
|
||||||
|
neterror (firstsync, errstart, "%s:%d: send %s (%d): %s",
|
||||||
|
__FILE__, __LINE__, server_name, now - errstart, strerror (errno));
|
||||||
|
/* Close the opened socket */
|
||||||
|
r = close (udp);
|
||||||
|
if (r != 0)
|
||||||
|
warn ("%s:%d: close udp: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read from the server */
|
||||||
|
syslog (LOG_DEBUG, "%s:%d: Reading UDP buf from %s",
|
||||||
|
__FILE__, __LINE__, server_name);
|
||||||
|
len = recv (udp, &buf, 60, 0);
|
||||||
|
if (len == -1)
|
||||||
|
{
|
||||||
|
now = xtime (NULL);
|
||||||
|
/* First error */
|
||||||
|
if (errstart == 0)
|
||||||
|
errstart = now;
|
||||||
|
neterror (firstsync, errstart, "%s:%d: recv %s (%d): %s",
|
||||||
|
__FILE__, __LINE__, server_name, now - errstart, strerror (errno));
|
||||||
|
/* Close the opened socket */
|
||||||
|
r = close (udp);
|
||||||
|
if (r != 0)
|
||||||
|
warn ("%s:%d: close udp: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the socket */
|
||||||
|
r = close (udp);
|
||||||
|
if (r != 0)
|
||||||
|
warn ("%s:%d: close udp: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
|
||||||
|
/* Get the local received time */
|
||||||
|
xgettimeofday (&tv4, &tz);
|
||||||
|
t4 = (double) tv4.tv_sec + (double) tv4.tv_usec / 1000000;
|
||||||
|
|
||||||
|
/* Calculate the local time offset */
|
||||||
|
/* Get the remote Receive Timestamp */
|
||||||
|
tv2.tv_sec = fromnetnum (&buf[32]) - EPOCH_DIFF;
|
||||||
|
tv2.tv_usec = frac2usec (fromnetnum (&buf[36]));
|
||||||
|
t2 = (double) tv2.tv_sec + (double) tv2.tv_usec / 1000000;
|
||||||
|
/* Get the remote Transmit Timestamp */
|
||||||
|
tv3.tv_sec = fromnetnum (&buf[40]) - EPOCH_DIFF;
|
||||||
|
tv3.tv_usec = frac2usec (fromnetnum (&buf[44]));
|
||||||
|
t3 = (double) tv3.tv_sec + (double) tv3.tv_usec / 1000000;
|
||||||
|
/* The time offset */
|
||||||
|
toff = (t2 + t3 - t1 - t4) / 2;
|
||||||
|
syslog (LOG_DEBUG, "%s:%d: Local time offset: t1: %.6f, t2: %.6f, t3: %.6f, t4: %.6f, toff: %.6f",
|
||||||
|
__FILE__, __LINE__, t1, t2, t3, t4, toff);
|
||||||
|
/* Calculate the new time */
|
||||||
|
tnew = t4 + toff;
|
||||||
|
tvnew.tv_usec = (long long) (tnew * 1000000) % 1000000;
|
||||||
|
tvnew.tv_sec = ((long long) (tnew * 1000000) - tvnew.tv_usec) / 1000000;
|
||||||
|
|
||||||
|
/* Set the time */
|
||||||
|
xsettimeofday (&tvnew, &tz);
|
||||||
|
|
||||||
|
/* Re-initialize the error timer */
|
||||||
|
errstart = 0;
|
||||||
|
/* Remove the first time flag */
|
||||||
|
firstsync = 0;
|
||||||
|
|
||||||
|
return toff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fork2background: Fork to the background.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
fork2background (void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
/* Fork */
|
||||||
|
pid = xfork ();
|
||||||
|
/* Exit the parent process */
|
||||||
|
if (pid != 0)
|
||||||
|
exit (0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* closeall: Close all the opened file descriptors,
|
||||||
|
especially: stdin, stdout and stderr.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
closeall (void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
long openmax;
|
||||||
|
openmax = xsysconf (_SC_OPEN_MAX, "_SC_OPEN_MAX");
|
||||||
|
for (i = 0; i < openmax; i++)
|
||||||
|
close (i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fromnetnum: Convert from a network number to a C number.
|
||||||
|
return: the number in unsigned long. */
|
||||||
|
unsigned long
|
||||||
|
fromnetnum (const char *oct)
|
||||||
|
{
|
||||||
|
return ((unsigned char) oct[0] << 24 | (unsigned char) oct[1] << 16 | (unsigned char) oct[2] << 8 | (unsigned char) oct[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tonetnum: Convert from a C number to a network number.
|
||||||
|
return: the number in network octet. */
|
||||||
|
const char *tonetnum (unsigned long num)
|
||||||
|
{
|
||||||
|
static char oct[5] = "0000";
|
||||||
|
oct[0] = (num >> 24) & 255;
|
||||||
|
oct[1] = (num >> 16) & 255;
|
||||||
|
oct[2] = (num >> 8) & 255;
|
||||||
|
oct[3] = num & 255;
|
||||||
|
return oct;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* usec2frac: Convert from microsecond to fraction of a second.
|
||||||
|
return: Fraction of a second. */
|
||||||
|
unsigned long
|
||||||
|
usec2frac (long usec)
|
||||||
|
{
|
||||||
|
return (unsigned long) (((long long) usec << 32) / 1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* usec2frac: Convert from fraction of a second to microsecond
|
||||||
|
return: microsecond. */
|
||||||
|
long
|
||||||
|
frac2usec (unsigned long frac)
|
||||||
|
{
|
||||||
|
return (long) (((long long) frac * 1000000) >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xstrcpy: allocate enough memory, make a copy of the string, and handle its error.
|
||||||
|
return: pointer to the destination string. */
|
||||||
|
char *
|
||||||
|
xstrcpy (const char *src)
|
||||||
|
{
|
||||||
|
char *dest;
|
||||||
|
dest = (char *) xmalloc (strlen (src) + 1);
|
||||||
|
strcpy (dest, src);
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xstrcat: allocate enough memory, concatenate the strings, and handle its error.
|
||||||
|
return: pointer to the destination string. */
|
||||||
|
char *
|
||||||
|
xstrcat (int n, ...)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
size_t len;
|
||||||
|
va_list ap;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
/* Calculate the result size */
|
||||||
|
va_start (ap, n);
|
||||||
|
for (i = 0, len = 0; i < n; i++)
|
||||||
|
len += strlen (va_arg (ap, char *));
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
/* Allocate the memory */
|
||||||
|
s = (char *) xmalloc (len + 1);
|
||||||
|
|
||||||
|
/* Concatenate the strings */
|
||||||
|
va_start (ap, n);
|
||||||
|
strcpy (s, va_arg (ap, char *));
|
||||||
|
for (i = 1; i < n; i++)
|
||||||
|
strcat (s, va_arg (ap, char *));
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xmalloc: malloc() and handle its error.
|
||||||
|
return: pointer to the allocated memory block. */
|
||||||
|
void *
|
||||||
|
xmalloc (size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
ptr = malloc (size);
|
||||||
|
if (ptr == NULL)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: malloc: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xtime: time() and handle its error.
|
||||||
|
return: current time. */
|
||||||
|
time_t
|
||||||
|
xtime (time_t *t)
|
||||||
|
{
|
||||||
|
time_t r;
|
||||||
|
r = time (t);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: time: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xgettimeofday: gettimeofday() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xgettimeofday (struct timeval *tv, struct timezone *tz)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = gettimeofday (tv, tz);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: gettimeofday: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xsettimeofday: settimeofday() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xsettimeofday (const struct timeval *tv , const struct timezone *tz)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = settimeofday (tv, tz);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: settimeofday: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xchdir: chdir() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xchdir (const char *path)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = chdir (path);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: chdir %s: %s",
|
||||||
|
__FILE__, __LINE__, path, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xfork: fork() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
pid_t
|
||||||
|
xfork (void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
pid = fork ();
|
||||||
|
if (pid == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: fork: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xsetsid: setsid() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
pid_t
|
||||||
|
xsetsid (void)
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
pid = setsid ();
|
||||||
|
if (pid == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: setsid: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xsysconf: sysconf() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
long
|
||||||
|
xsysconf (int name, const char *confname)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
r = sysconf (name);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: sysconf %s: %s",
|
||||||
|
__FILE__, __LINE__, confname, strerror (errno));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xfopen: fopen() and handle its error.
|
||||||
|
return: file handler pointer. */
|
||||||
|
FILE *
|
||||||
|
xfopen (const char *path, const char *mode)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
fp = fopen (path, mode);
|
||||||
|
if (fp == NULL)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: fopen %s: %s",
|
||||||
|
__FILE__, __LINE__, path, strerror (errno));
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xfclose: fclose() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xfclose (FILE *stream)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = fclose (stream);
|
||||||
|
if (r == EOF)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: fclose: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xfprintf: fprintf() and handle its error.
|
||||||
|
return: length print so far. */
|
||||||
|
int
|
||||||
|
xfprintf (FILE *stream, const char *format, ...)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
va_list ap;
|
||||||
|
va_start (ap, format);
|
||||||
|
len = vfprintf (stream, format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
if (len < 0)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: vfprintf: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xsigemptyset: sigemptyset() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xsigemptyset (sigset_t *set)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = sigemptyset (set);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: sigemptyset: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xsigaction: sigaction() and handle its error.
|
||||||
|
return: none. */
|
||||||
|
void
|
||||||
|
xsigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
r = sigaction (signum, act, oldact);
|
||||||
|
if (r == -1)
|
||||||
|
error (EXIT_SYSERR, "%s:%d: sigaction: %s",
|
||||||
|
__FILE__, __LINE__, strerror (errno));
|
||||||
|
return;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user