mirror of
git://git.sv.gnu.org/findutils.git
synced 2026-07-10 17:06:38 +02:00
GNU findutils package version 4.1
This commit is contained in:
@@ -1,627 +1,285 @@
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
NO WARRANTY
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
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.
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -629,15 +287,15 @@ free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -646,31 +304,36 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
|
||||
@@ -1,43 +1,27 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
@@ -59,64 +43,48 @@ The simplest way to compile this package is:
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
source directory by typing `make clean'. To also remove the files
|
||||
that `configure' created (so you can compile the package for a
|
||||
different kind of computer), type `make distclean'.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
Using a Different Build Directory
|
||||
=================================
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
You can compile the package in a different directory from the one
|
||||
containing the source code. Doing so allows you to compile it on more
|
||||
than one kind of computer at the same time. To do this, you must use a
|
||||
version of `make' that supports the `VPATH' variable, such as GNU
|
||||
`make'. `cd' to the directory where you want the object files and
|
||||
executables to go and run the `configure' script. `configure'
|
||||
automatically checks for the source code in the directory that
|
||||
`configure' is in and in `..'.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
@@ -125,7 +93,7 @@ option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
@@ -140,97 +108,60 @@ you can use the `configure' options `--x-includes=DIR' and
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
need to know the host type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
Save the results of the tests in FILE instead of `config.cache'.
|
||||
Set FILE to `/dev/null' to disable caching, for debugging
|
||||
`configure'.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
Do not print messages saying which checks are being made.
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
||||
|
||||
|
||||
+5
-69
@@ -1,70 +1,6 @@
|
||||
AUTOMAKE_OPTIONS=gnits
|
||||
# readme-alpha
|
||||
DIST_OTHER = COPYING ChangeLog TODO install-sh config.h.in stamp-h.in
|
||||
SUBDIRS = lib find xargs locate doc testsuite
|
||||
CONFIG_HEADER = config.h
|
||||
|
||||
EXTRA_DIST = COPYING ChangeLog TODO config.h.in stamp-h.in \
|
||||
THANKS import-gnulib.sh import-gnulib.config
|
||||
# "tests" is the gnulib unit test dir.
|
||||
SUBDIRS = gnulib tests build-aux lib find xargs locate doc po m4
|
||||
|
||||
ACLOCAL_AMFLAGS = -I gnulib/m4 -I m4
|
||||
|
||||
TESTFILE_SUFFIXES = .exp .xo .xe .xi
|
||||
|
||||
# CONFIG_CLEAN_FILES = gnulib/lib/regex.c
|
||||
|
||||
|
||||
# DISTCLEANFILES = intl/libintl.h
|
||||
|
||||
dist-hook: jy-regex-fix findutils-check-pofiles findutils-check-testfiles
|
||||
|
||||
|
||||
## regex.c seems to get left out if I use automake-1.9 but not
|
||||
## if I use automake-1.7. Hence dist-hook has to be able to
|
||||
## copy regex.c into the relevant (read-only) directory if it
|
||||
## is not already there, but needs to avoid doing so if the
|
||||
## file is already in place. Ugh.
|
||||
##
|
||||
## This problem appears not to apply to Automake-1.10, but since
|
||||
## gnulib only requires Automake-1.9.6, we should support that.
|
||||
## Therefore we probably can't remove this kludge yet.
|
||||
##
|
||||
## -- James Youngman <jay@gnu.org>
|
||||
##
|
||||
jy-regex-fix:
|
||||
if test -f $(distdir)/gnulib/lib/regex.c ; then \
|
||||
echo regex.c is already in place. Great. ; \
|
||||
else \
|
||||
echo Making $(distdir)/gnulib/lib writable ... ; \
|
||||
chmod +w $(distdir)/gnulib/lib ; \
|
||||
echo Copying $(srcdir)/gnulib/lib/regex.c to $(distdir)/gnulib/lib ; \
|
||||
cp $(srcdir)/gnulib/lib/regex.c $(distdir)/gnulib/lib/regex.c ; \
|
||||
fi
|
||||
# ls -ld $(srcdir)/gnulib/lib/regex.c $(distdir)/gnulib/lib
|
||||
|
||||
## Check that we actually shipped all the .po files. If this rule fails,
|
||||
## check ALL_LINGUAS in configure.in against the po files in the source
|
||||
## directory (their names, not their contents)
|
||||
findutils-check-pofiles:
|
||||
@echo ; echo Checking to see if we distributed the full set of .po files
|
||||
distcount=`ls $(distdir)/po/*.po | wc -l` ; srccount=`ls $(srcdir)/po/*.po | wc -l` ; test $$distcount -eq $$srccount || ( echo FAILED: Please check the value of ALL_LINGUAS in configure.in against the actual set of ".po" files >&2 ; false )
|
||||
@echo All .po files distributed OK.
|
||||
|
||||
## Check that we actually shipped all the test files that exist in the source.
|
||||
## runtest will run all the .exp files it finds, and so if we don't ship all
|
||||
## of them, there will be some tests which people using the CVS code will be
|
||||
## running, but people using the source distribution will not.
|
||||
findutils-check-testfiles:
|
||||
@echo
|
||||
$(AUXDIR)/check-testfiles.sh "$(distdir)" "$(srcdir)" $(TESTFILE_SUFFIXES)
|
||||
|
||||
|
||||
findutils-check-smells:
|
||||
find $(srcdir) \( -path $(srcdir)/autom4te.cache -o \
|
||||
-path $(srcdir)/gnulib-git -o \
|
||||
-name .git -o \
|
||||
\( -type d -name CVS \) \
|
||||
\) -prune -o \
|
||||
\( -type f -o -type l \) \
|
||||
\! \( -name '*~' -o -name '*.xo' -o -name '*.xi' \) \
|
||||
-print0 | \
|
||||
xargs -0 python $(AUXDIR)/src-sniff.py
|
||||
distname:
|
||||
echo findutils-`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q find/version.c` > $@
|
||||
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
# Makefile.in generated automatically by automake from Makefile.am.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
datadir = $(prefix)/share
|
||||
sysconfdir = $(prefix)/etc
|
||||
sharedstatedir = $(prefix)/com
|
||||
localstatedir = $(prefix)/var
|
||||
libdir = $(exec_prefix)/lib
|
||||
infodir = $(prefix)/info
|
||||
mandir = $(prefix)/man
|
||||
includedir = $(prefix)/include
|
||||
oldincludedir = /usr/include
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
ALL = ${PROGRAMS} ${LIBPROGRAMS} ${SCRIPTS} ${LIBSCRIPTS} ${LIBFILES}
|
||||
ACCONFIG = acconfig.h
|
||||
SOURCES =
|
||||
DIST_CONF = Makefile.am Makefile.in README INSTALL NEWS \
|
||||
configure configure.in ${ACLOCAL} ${ACCONFIG} ${CONFIG_TOP} \
|
||||
${CONFIG_BOT} mkinstalldirs
|
||||
DIST_FILES = $(DIST_CONF) $(SOURCES) $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER)
|
||||
|
||||
DIST_OTHER = COPYING ChangeLog TODO install-sh config.h.in stamp-h.in
|
||||
SUBDIRS = lib find xargs locate doc testsuite
|
||||
CONFIG_HEADER = config.h
|
||||
|
||||
all:: ${ALL}
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
all install install-info uninstall check tags TAGS info dvi::
|
||||
for subdir in $(SUBDIRS); do \
|
||||
echo making $@ in $$subdir ; \
|
||||
(cd $$subdir; $(MAKE) $@); \
|
||||
done
|
||||
|
||||
mostlyclean: mostlyclean-recursive mostlyclean-local
|
||||
|
||||
clean: clean-recursive clean-local
|
||||
|
||||
distclean: distclean-recursive
|
||||
$(MAKE) distclean-local
|
||||
|
||||
realclean: realclean-recursive
|
||||
$(MAKE) realclean-local
|
||||
|
||||
mostlyclean-recursive clean-recursive distclean-recursive realclean-recursive:
|
||||
for subdir in $(SUBDIRS); do \
|
||||
(cd $$subdir; $(MAKE) `echo $@ | sed s/-recursive//`); \
|
||||
done
|
||||
|
||||
mostlyclean-local:
|
||||
|
||||
clean-local: mostlyclean-local
|
||||
|
||||
distclean-local: clean-local
|
||||
rm -f Makefile config.cache config.log config.status
|
||||
rm -f ${CONFIG_HEADER} stamp-h
|
||||
|
||||
realclean-local: distclean-local
|
||||
|
||||
# For an explanation of the following Makefile rules, see node
|
||||
# `Automatic Remaking' in GNU Autoconf documentation.
|
||||
Makefile: Makefile.in config.status
|
||||
CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
|
||||
config.status: configure
|
||||
./config.status --recheck
|
||||
${srcdir}/configure: configure.in ${ACLOCAL}
|
||||
cd $(srcdir); autoconf
|
||||
|
||||
${CONFIG_HEADER}: stamp-h
|
||||
stamp-h: ${CONFIG_HEADER}.in config.status
|
||||
CONFIG_FILES= CONFIG_HEADERS=${CONFIG_HEADER} ./config.status
|
||||
${srcdir}/${CONFIG_HEADER}.in: stamp-h.in
|
||||
${srcdir}/stamp-h.in: configure.in ${ACLOCAL} ${ACCONFIG} ${CONFIG_TOP} ${CONFIG_BOT}
|
||||
cd $(srcdir); autoheader
|
||||
date > $(srcdir)/stamp-h.in
|
||||
|
||||
dist: $(DIST_FILES) $(DIST_DIRS) distname
|
||||
rm -rf `cat distname`; mkdir `cat distname`
|
||||
@for file in $(DIST_FILES); do \
|
||||
echo linking $$file; \
|
||||
ln $(srcdir)/$$file `cat distname`/$$file || \
|
||||
{ echo copying $$file instead; cp -p $(srcdir)/$$file `cat distname`/$$file;}; \
|
||||
done
|
||||
for subdir in $(SUBDIRS); do \
|
||||
(cd $$subdir; $(MAKE) subdir=$$subdir $@); done
|
||||
chmod -R a+r `cat distname`
|
||||
tar -chozf `cat distname`.tar.gz `cat distname`
|
||||
rm -rf `cat distname` distname
|
||||
|
||||
check dvi info install uninstall::
|
||||
|
||||
tags:: TAGS
|
||||
|
||||
TAGS::
|
||||
cd $(srcdir); etags $(SOURCES)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
distname:
|
||||
echo findutils-`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q find/version.c` > $@
|
||||
@@ -1,21 +1,12 @@
|
||||
This package contains the GNU find, xargs, and locate programs. find
|
||||
and xargs comply with POSIX 1003.2, as far as I know (with the
|
||||
exception of the "+" modifier for the "-exec" action, which isn't
|
||||
implemented yet). They also support a large number of additional
|
||||
options, some borrowed from Unix and some unique to GNU.
|
||||
and xargs comply with POSIX 1003.2, as far as I know. They also
|
||||
support some additional options, some borrowed from Unix and some
|
||||
unique to GNU.
|
||||
|
||||
See the file NEWS for a list of major changes in the current release.
|
||||
|
||||
See the file INSTALL for compilation and installation instructions.
|
||||
|
||||
To verify the GPG signature of the release, you will need the public
|
||||
key of the findutils maintainer. You can download this from
|
||||
ftp://ftp.gnu.org/gnu/gnu-keyring.gpg. Alternatively, you could query
|
||||
a PGP keyserver, but you will need to use one that can cope with
|
||||
subkeys containing photos. Many older key servers cannot do this. I
|
||||
use subkeys.pgp.net. I think that one works. See also the
|
||||
"Downloading" section of http://www.gnu.org/software/findutils/.
|
||||
|
||||
Special configure options:
|
||||
|
||||
--with-afs
|
||||
@@ -30,20 +21,6 @@ getpwuid or getgrgid when needed. Speeds up -nouser and -nogroup
|
||||
unless you are running NIS or Hesiod, which make password and group
|
||||
calls very expensive.
|
||||
|
||||
--enable-debug
|
||||
Produce output on the standard error output indicating what find is
|
||||
doing. This information includes details about how the command line
|
||||
has been parsed and what files have been stat()ed. This output is
|
||||
normally interesting only to the maintainer, and so is off by default.
|
||||
|
||||
DEFAULT_ARG_SIZE=<value>
|
||||
If this environment variable is defined to a numeric expression
|
||||
during configure, it determines the default argument size limits used
|
||||
by xargs without -s, and by find, when spawning child processes.
|
||||
Otherwise, the default is set at 128 kibibytes. If the system cannot
|
||||
support the default limit, the system's limit will be used instead.
|
||||
|
||||
|
||||
To gain speed, GNU find avoids statting files whenever possible.
|
||||
It does this by:
|
||||
1. Checking the number of links to directories and not statting files
|
||||
@@ -62,5 +39,9 @@ searching has been moved to a separate program, `locate'; the same
|
||||
thing has been done in 4.4BSD. If you use locate, you should run the
|
||||
included `updatedb' script from cron periodically (typically nightly).
|
||||
|
||||
The `Makefile.am' files are used by an experimental program called
|
||||
AutoMake that is under development. It's not ready for general use
|
||||
yet, so don't worry about them.
|
||||
|
||||
Mail suggestions and bug reports for these programs to
|
||||
bug-findutils@gnu.org.
|
||||
bug-gnu-utils@prep.ai.mit.edu.
|
||||
|
||||
@@ -1,53 +1,5 @@
|
||||
-*-outline-*-
|
||||
* -fstype core dumps on sparc-sun-sunos4.1.3_U1 with gcc-2.95.2
|
||||
This is on foxtrot.rahul.net. dbx does not work on compiled find.
|
||||
Perhaps gcc is installed incorrectly. "find / -fstype ufs" core dumps
|
||||
quickly. cc works correctly.
|
||||
To do:
|
||||
|
||||
* Speed of locate without "-i" option needs to be increased.
|
||||
Eliminate unnecessary strcpy calls in xargs.
|
||||
|
||||
* Internationalization
|
||||
** updatedb.sh should be internationalized
|
||||
|
||||
* Eliminate unnecessary strcpy calls in xargs.
|
||||
|
||||
* man pages for frcode, bigram, and code
|
||||
Perhaps a better description in texi pages as well.
|
||||
|
||||
* Add option for find to sort output in lexical order for use for updatedb
|
||||
olarsac@airfrance.fr (Olivier) made the following suggestion:
|
||||
|
||||
As I was running thru the code looking for the bug I wondered why the updatedb
|
||||
has to use sort...
|
||||
why not add an option to find that sorts the output in lexical order?
|
||||
my point is:
|
||||
- sort on a big list is costly (here we do locate on big big file system)
|
||||
- find may (in theory) sort incrementally very easily by sorting only the current
|
||||
directory entries before recursion
|
||||
|
||||
|
||||
* large file problems
|
||||
depcomp gets added by automake
|
||||
|
||||
* investigate _LIBC when used with TOLOWER and TOUPPER
|
||||
_LIBC is used to determine whether TOLOWER should check isupper first.
|
||||
Is there something better to check? Alternatively, can tolower be
|
||||
checked at run time to determine whether isupper should be called first.
|
||||
|
||||
* BeOS problems with multibyte
|
||||
Bruno Haible reported problems with BeOS.
|
||||
|
||||
* Include example of use of updatedb in documentation.
|
||||
Use something close to the Debian daily cron job.
|
||||
|
||||
* Supply example for time range commands for find.
|
||||
|
||||
--//--
|
||||
This is used by Emacs' spell checker ispell.el:
|
||||
|
||||
LocalWords: strftime xargs updatedb sh strcpy
|
||||
LocalWords: lib frcode bigram texi depcomp automake
|
||||
LocalWords: LIBOBJS FUNC findutils
|
||||
LocalWords: LIBC TOLOWER TOUPPER tolower isupper
|
||||
LocalWords: Debian cron
|
||||
LocalWords: Haible BeOS
|
||||
Use mode_t and AC_TYPE_MODE_T.
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/* Entries for config.h.in that aren't automatically generated. */
|
||||
|
||||
/* Define if you have the Andrew File System. */
|
||||
#undef AFS
|
||||
|
||||
/* Define If you want find -nouser and -nogroup to make tables of
|
||||
used UIDs and GIDs at startup instead of using getpwuid or
|
||||
getgrgid when needed. Speeds up -nouser and -nogroup unless you
|
||||
are running NIS or Hesiod, which make password and group calls
|
||||
very expensive. */
|
||||
#undef CACHE_IDS
|
||||
|
||||
/* Define to use SVR4 statvfs to get filesystem type. */
|
||||
#undef FSTYPE_STATVFS
|
||||
|
||||
/* Define to use SVR3.2 statfs to get filesystem type. */
|
||||
#undef FSTYPE_USG_STATFS
|
||||
|
||||
/* Define to use AIX3 statfs to get filesystem type. */
|
||||
#undef FSTYPE_AIX_STATFS
|
||||
|
||||
/* Define to use 4.3BSD getmntent to get filesystem type. */
|
||||
#undef FSTYPE_MNTENT
|
||||
|
||||
/* Define to use 4.4BSD and OSF1 statfs to get filesystem type. */
|
||||
#undef FSTYPE_STATFS
|
||||
|
||||
/* Define to use Ultrix getmnt to get filesystem type. */
|
||||
#undef FSTYPE_GETMNT
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
|
||||
#undef dev_t
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
|
||||
#undef ino_t
|
||||
|
||||
+171
@@ -0,0 +1,171 @@
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#undef _ALL_SOURCE
|
||||
#endif
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
#undef C_ALLOCA
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
#undef CLOSEDIR_VOID
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
|
||||
This function is required for alloca.c support on those systems. */
|
||||
#undef CRAY_STACKSEG_END
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define if you have alloca, as a function or macro. */
|
||||
#undef HAVE_ALLOCA
|
||||
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#undef HAVE_ALLOCA_H
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
#undef HAVE_DOPRNT
|
||||
|
||||
/* Define if you have the getmntent function. */
|
||||
#undef HAVE_GETMNTENT
|
||||
|
||||
/* Define if your struct stat has st_blocks. */
|
||||
#undef HAVE_ST_BLOCKS
|
||||
|
||||
/* Define if your struct stat has st_rdev. */
|
||||
#undef HAVE_ST_RDEV
|
||||
|
||||
/* Define if you have the strftime function. */
|
||||
#undef HAVE_STRFTIME
|
||||
|
||||
/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||
#undef HAVE_SYS_WAIT_H
|
||||
|
||||
/* Define if your struct tm has tm_zone. */
|
||||
#undef HAVE_TM_ZONE
|
||||
|
||||
/* Define if you don't have tm_zone but do have the external array
|
||||
tzname. */
|
||||
#undef HAVE_TZNAME
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
#undef HAVE_VPRINTF
|
||||
|
||||
/* Define if major, minor, and makedev are declared in <mkdev.h>. */
|
||||
#undef MAJOR_IN_MKDEV
|
||||
|
||||
/* Define if major, minor, and makedev are declared in <sysmacros.h>. */
|
||||
#undef MAJOR_IN_SYSMACROS
|
||||
|
||||
/* Define if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef pid_t
|
||||
|
||||
/* Define if the system does not provide POSIX.1 features except
|
||||
with this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define if you need to in order for stat and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> doesn't define. */
|
||||
#undef size_t
|
||||
|
||||
/* If using the C implementation of alloca, define if you know the
|
||||
direction of stack growth for your system; otherwise it will be
|
||||
automatically deduced at run-time.
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown
|
||||
*/
|
||||
#undef STACK_DIRECTION
|
||||
|
||||
/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
#undef STAT_MACROS_BROKEN
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Define if your <sys/time.h> declares struct tm. */
|
||||
#undef TM_IN_SYS_TIME
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
/* Define if you have the Andrew File System. */
|
||||
#undef AFS
|
||||
|
||||
/* Define If you want find -nouser and -nogroup to make tables of
|
||||
used UIDs and GIDs at startup instead of using getpwuid or
|
||||
getgrgid when needed. Speeds up -nouser and -nogroup unless you
|
||||
are running NIS or Hesiod, which make password and group calls
|
||||
very expensive. */
|
||||
#undef CACHE_IDS
|
||||
|
||||
/* Define to use SVR4 statvfs to get filesystem type. */
|
||||
#undef FSTYPE_STATVFS
|
||||
|
||||
/* Define to use SVR3.2 statfs to get filesystem type. */
|
||||
#undef FSTYPE_USG_STATFS
|
||||
|
||||
/* Define to use AIX3 statfs to get filesystem type. */
|
||||
#undef FSTYPE_AIX_STATFS
|
||||
|
||||
/* Define to use 4.3BSD getmntent to get filesystem type. */
|
||||
#undef FSTYPE_MNTENT
|
||||
|
||||
/* Define to use 4.4BSD and OSF1 statfs to get filesystem type. */
|
||||
#undef FSTYPE_STATFS
|
||||
|
||||
/* Define to use Ultrix getmnt to get filesystem type. */
|
||||
#undef FSTYPE_GETMNT
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
|
||||
#undef dev_t
|
||||
|
||||
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
|
||||
#undef ino_t
|
||||
|
||||
/* Define if you have the fchdir function. */
|
||||
#undef HAVE_FCHDIR
|
||||
|
||||
/* Define if you have the getcwd function. */
|
||||
#undef HAVE_GETCWD
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#undef HAVE_STRERROR
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#undef HAVE_DIRENT_H
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#undef HAVE_FCNTL_H
|
||||
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
#undef HAVE_NDIR_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
#undef HAVE_SYS_DIR_H
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
#undef HAVE_SYS_NDIR_H
|
||||
|
||||
/* Define if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if you have the sun library (-lsun). */
|
||||
#undef HAVE_LIBSUN
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,89 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(find/pred.c)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_SUBST(INCLUDES)dnl
|
||||
AC_ARG_ENABLE(id-cache,
|
||||
[ --enable-id-cache cache all UIDs & GIDs; avoid if using NIS or Hesiod],
|
||||
AC_DEFINE(CACHE_IDS))
|
||||
AC_ARG_WITH(afs,
|
||||
[ --with-afs support -fstype afs],
|
||||
[ AC_DEFINE(AFS)
|
||||
CPPFLAGS="$CPPFLAGS -I/usr/afsws/include"
|
||||
LIBS="$LIBS -L/usr/afsws/lib -L/usr/afsws/lib/afs -lsys -lrx -llwp"])
|
||||
AC_ARG_PROGRAM
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_MAKE_SET
|
||||
|
||||
dnl Try to get a POSIX.1 environment.
|
||||
AC_AIX
|
||||
AC_MINIX
|
||||
AC_ISC_POSIX
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_CHECK_LIB(sun, getpwnam)
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(fcntl.h string.h limits.h unistd.h)
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_MAJOR
|
||||
AC_HEADER_DIRENT
|
||||
AC_HEADER_STAT
|
||||
AC_HEADER_SYS_WAIT
|
||||
|
||||
AC_MSG_CHECKING(how to get filesystem type)
|
||||
fstype=no
|
||||
# The order of these tests is important.
|
||||
AC_TRY_CPP([#include <sys/statvfs.h>
|
||||
#include <sys/fstyp.h>], AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4)
|
||||
if test $fstype = no; then
|
||||
AC_TRY_CPP([#include <sys/statfs.h>
|
||||
#include <sys/fstyp.h>], AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3)
|
||||
fi
|
||||
if test $fstype = no; then
|
||||
AC_TRY_CPP([#include <sys/statfs.h>
|
||||
#include <sys/vmount.h>], AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX)
|
||||
fi
|
||||
if test $fstype = no; then
|
||||
AC_TRY_CPP([#include <mntent.h>], AC_DEFINE(FSTYPE_MNTENT) fstype=4.3BSD)
|
||||
fi
|
||||
if test $fstype = no; then
|
||||
AC_EGREP_HEADER(f_type;, sys/mount.h, AC_DEFINE(FSTYPE_STATFS) fstype=4.4BSD/OSF1)
|
||||
fi
|
||||
if test $fstype = no; then
|
||||
AC_TRY_CPP([#include <sys/mount.h>
|
||||
#include <sys/fs_types.h>], AC_DEFINE(FSTYPE_GETMNT) fstype=Ultrix)
|
||||
fi
|
||||
AC_MSG_RESULT($fstype)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
AC_TYPE_UID_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_TYPE_PID_T
|
||||
AC_CHECK_TYPE(ino_t, unsigned long)
|
||||
AC_CHECK_TYPE(dev_t, unsigned long)
|
||||
AC_STRUCT_ST_BLOCKS
|
||||
AC_STRUCT_ST_RDEV
|
||||
AC_STRUCT_TM
|
||||
AC_STRUCT_TIMEZONE
|
||||
AC_C_CONST
|
||||
|
||||
dnl Checks for library functions.
|
||||
|
||||
AC_REPLACE_FUNCS(memcmp memset mktime stpcpy strdup strftime strspn strstr strtol)
|
||||
AC_CHECK_FUNCS(fchdir getcwd strerror)
|
||||
AC_FUNC_STRFTIME
|
||||
AC_FUNC_VPRINTF
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_GETMNTENT
|
||||
AC_FUNC_CLOSEDIR_VOID
|
||||
|
||||
AC_OUTPUT(Makefile lib/Makefile find/Makefile xargs/Makefile \
|
||||
locate/Makefile doc/Makefile testsuite/Makefile,
|
||||
date > stamp-h)
|
||||
+3
-74
@@ -1,75 +1,4 @@
|
||||
info_TEXINFOS = find.texi find-maint.texi
|
||||
find_TEXINFOS = perm.texi getdate.texi regexprops.texi fdl.texi
|
||||
find_maint_TEXINFOS = fdl.texi
|
||||
MOSTLYCLEANFILES = find.cps
|
||||
CLEANFILES = find.txt find_mono.html findutils.texi_html_node.tar.gz
|
||||
TEXINFOS = find.texi
|
||||
DIST_OTHER = perm.texi texinfo.tex
|
||||
|
||||
# To build regexprops.texi, we need to build the regexprops program and
|
||||
# run it on the host. If we are cross compiling, we may not have a native
|
||||
# binary. When this is the case, we use a workaround; don't delete the
|
||||
# file for 'make clean'. This fixes Savannah bug #19658.
|
||||
if !CROSS_COMPILING
|
||||
CLEANFILES += regexprops.texi regexprops-generic.texi
|
||||
endif
|
||||
|
||||
MAKEINFOTXT = $(MAKEINFO) --plaintext
|
||||
|
||||
find.txt: find.texi $(srcdir)/version.texi $(find_TEXINFOS)
|
||||
|
||||
# find.txt is a file which we need to know how to build
|
||||
# because it gets put on the www.gnu.org website.
|
||||
# This rule is derived from the .texi.html rule.
|
||||
.texi.txt:
|
||||
rm -rf $(@:.txt=.tmp)
|
||||
if $(MAKEINFOTXT) $(AM_MAKEINFOTXTFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
|
||||
-o $(@:.txt=.tmp) $<; \
|
||||
then \
|
||||
rm -rf $@; \
|
||||
if test ! -d $(@:.txt=.tmp) && test -d $(@:.txt=); then \
|
||||
mv $(@:.txt=) $@; else mv $(@:.txt=.tmp) $@; fi; \
|
||||
else \
|
||||
if test ! -d $(@:.txt=.tmp) && test -d $(@:.txt=); then \
|
||||
rm -rf $(@:.txt=); else rm -Rf $(@:.txt=.tmp) $@; fi; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
|
||||
# find_mono.html is a file which we need to know how to build
|
||||
# because it gets put on the www.gnu.org website.
|
||||
# This rule is derived from the generic .texi.html rule.
|
||||
find_mono.html: find.texi
|
||||
rm -rf $(@:.html=.htp)
|
||||
if $(MAKEINFOHTML) --no-split $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
|
||||
-o $(@:.html=.htp) $<; \
|
||||
then \
|
||||
rm -rf $@; \
|
||||
if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
|
||||
mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
|
||||
else \
|
||||
if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
|
||||
rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
|
||||
# findutils.texi_html_node.tar.gz is a file which we need to know
|
||||
# how to build because it gets put on the www.gnu.org website.
|
||||
# This rule depends on GNU tar, but it's principally used
|
||||
# by the maintainer, and we don't need to build the file
|
||||
# for "make all" or "make install" (or even "make check").
|
||||
findutils.texi_html_node.tar.gz: find.html
|
||||
tar zcf $@ $<
|
||||
|
||||
if CROSS_COMPILING
|
||||
regexprops.texi regexprops-generic.texi: ../gnulib/lib/regex.h
|
||||
echo "WARNING: $? is newer than $@ but $@ cannot be rebuilt because we are cross-compiling. Continuing anyway." >&2
|
||||
else
|
||||
regexprops.texi: ../gnulib/lib/regex.h ../lib/regexprops.c
|
||||
cd ../lib && $(MAKE) $(AM_MAKEFLAGS) regexprops$(EXEEXT)
|
||||
../lib/regexprops$(EXEEXT) "Regular Expressions" findutils > $@
|
||||
rm ../lib/regexprops$(EXEEXT)
|
||||
regexprops-generic.texi: ../gnulib/lib/regex.h ../lib/regexprops.c
|
||||
cd ../lib && $(MAKE) $(AM_MAKEFLAGS) regexprops$(EXEEXT)
|
||||
../lib/regexprops$(EXEEXT) "Regular Expressions" generic > $@
|
||||
rm ../lib/regexprops$(EXEEXT)
|
||||
endif
|
||||
find.info find.dvi: perm.texi
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
# Makefile.in generated automatically by automake from Makefile.am.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
datadir = $(prefix)/share
|
||||
sysconfdir = $(prefix)/etc
|
||||
sharedstatedir = $(prefix)/com
|
||||
localstatedir = $(prefix)/var
|
||||
libdir = $(exec_prefix)/lib
|
||||
infodir = $(prefix)/info
|
||||
mandir = $(prefix)/man
|
||||
includedir = $(prefix)/include
|
||||
oldincludedir = /usr/include
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
ALL = ${PROGRAMS} ${LIBPROGRAMS} ${SCRIPTS} ${LIBSCRIPTS} ${LIBFILES}
|
||||
MAKEINFO = makeinfo
|
||||
TEXI2DVI = texi2dvi
|
||||
|
||||
TEXFILES = *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.log *.pg *.toc *.tp *.vr
|
||||
|
||||
INFOS = find.info*
|
||||
INFO_DEPS = find.info
|
||||
DVIS = find.dvi
|
||||
SOURCES =
|
||||
DIST_CONF = Makefile.am Makefile.in
|
||||
DIST_FILES = $(DIST_CONF) $(SOURCES) $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER)
|
||||
|
||||
TEXINFOS = find.texi
|
||||
DIST_OTHER = perm.texi texinfo.tex
|
||||
|
||||
all:: ${ALL}
|
||||
|
||||
.SUFFIXES: .texi .info .dvi
|
||||
|
||||
.texi.info:
|
||||
$(MAKEINFO) -I$(srcdir) $<
|
||||
|
||||
.texi.dvi:
|
||||
TEXINPUTS=$(srcdir):$$TEXINPUTS $(TEXI2DVI) $<
|
||||
|
||||
info:: $(INFO_DEPS)
|
||||
|
||||
dvi:: $(DVIS)
|
||||
|
||||
install:: install-info
|
||||
|
||||
install-info: $(INFO_DEPS)
|
||||
$(top_srcdir)/mkinstalldirs $(infodir)
|
||||
cd $(srcdir); for file in *.info*; do \
|
||||
$(INSTALL_DATA) $$file $(infodir)/$$file; \
|
||||
done
|
||||
|
||||
uninstall:: uninstall-info
|
||||
|
||||
uninstall-info:
|
||||
cd $(srcdir); for file in *.info*; do \
|
||||
rm -f $(infodir)/$$file; \
|
||||
done
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.o core
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f $(PROGRAMS) $(LIBPROGRAMS) $(LIBFILES) $(TEXFILES) $(CLEANFILES)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *.tab.c $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS $(INFOS)
|
||||
|
||||
dist: $(DIST_FILES) $(DIST_DIRS)
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
@for file in $(DIST_FILES); do \
|
||||
echo linking $$file; \
|
||||
ln $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file || \
|
||||
{ echo copying $$file instead; cp -p $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file;}; \
|
||||
done
|
||||
|
||||
check dvi info install uninstall::
|
||||
|
||||
tags:: TAGS
|
||||
|
||||
TAGS::
|
||||
cd $(srcdir); etags $(SOURCES)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
find.info find.dvi: perm.texi
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
This is Info file find.info, produced by Makeinfo-1.55 from the input
|
||||
file find.texi.
|
||||
|
||||
START-INFO-DIR-ENTRY
|
||||
* Finding Files: (find). Listing and operating on files
|
||||
that match certain criteria.
|
||||
END-INFO-DIR-ENTRY
|
||||
|
||||
This file documents the GNU utilities for finding files that match
|
||||
certain criteria and performing various operations on them.
|
||||
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to make and distribute verbatim copies of this
|
||||
manual provided the copyright notice and this permission notice are
|
||||
preserved on all copies.
|
||||
|
||||
Permission is granted to copy and distribute modified versions of
|
||||
this manual under the conditions for verbatim copying, provided that
|
||||
the entire resulting derived work is distributed under the terms of a
|
||||
permission notice identical to this one.
|
||||
|
||||
Permission is granted to copy and distribute translations of this
|
||||
manual into another language, under the above conditions for modified
|
||||
versions, except that this permission notice may be stated in a
|
||||
translation approved by the Foundation.
|
||||
|
||||
|
||||
Indirect:
|
||||
find.info-1: 1097
|
||||
find.info-2: 50752
|
||||
|
||||
Tag Table:
|
||||
(Indirect)
|
||||
Node: Top1097
|
||||
Node: Introduction1909
|
||||
Node: Scope3080
|
||||
Node: Overview5000
|
||||
Node: find Expressions6758
|
||||
Node: Finding Files8379
|
||||
Node: Name8845
|
||||
Node: Base Name Patterns9469
|
||||
Node: Full Name Patterns10008
|
||||
Node: Fast Full Name Search10993
|
||||
Node: Shell Pattern Matching13148
|
||||
Node: Links14989
|
||||
Node: Symbolic Links15419
|
||||
Node: Hard Links16367
|
||||
Node: Time17403
|
||||
Node: Age Ranges17918
|
||||
Node: Comparing Timestamps18851
|
||||
Node: Size20130
|
||||
Node: Type20945
|
||||
Node: Owner21757
|
||||
Node: Permissions22570
|
||||
Node: Contents23255
|
||||
Node: Directories24423
|
||||
Node: Filesystems26897
|
||||
Node: Combining Primaries With Operators28169
|
||||
Node: Actions29470
|
||||
Node: Print File Name30017
|
||||
Node: Print File Information30621
|
||||
Node: Escapes32856
|
||||
Node: Format Directives33516
|
||||
Node: Name Directives34214
|
||||
Node: Ownership Directives34745
|
||||
Node: Size Directives35170
|
||||
Node: Location Directives35466
|
||||
Node: Time Directives36018
|
||||
Node: Time Formats36886
|
||||
Node: Time Components37313
|
||||
Node: Date Components37806
|
||||
Node: Combined Time Formats38616
|
||||
Node: Run Commands39100
|
||||
Node: Single File39453
|
||||
Node: Multiple Files40303
|
||||
Node: Unsafe File Name Handling42106
|
||||
Node: Safe File Name Handling43656
|
||||
Node: Limiting Command Size44342
|
||||
Node: Interspersing File Names46097
|
||||
Node: Querying47158
|
||||
Node: Adding Tests48074
|
||||
Node: Common Tasks50336
|
||||
Node: Viewing And Editing50752
|
||||
Node: Archiving51263
|
||||
Node: Cleaning Up52895
|
||||
Node: Strange File Names54456
|
||||
Node: Fixing Permissions56086
|
||||
Node: Classifying Files56645
|
||||
Node: Databases57363
|
||||
Node: Database Locations57977
|
||||
Node: Database Formats59501
|
||||
Node: New Database Format60152
|
||||
Node: Sample Database61714
|
||||
Node: Old Database Format62353
|
||||
Node: File Permissions64083
|
||||
Node: Mode Structure64651
|
||||
Node: Symbolic Modes66779
|
||||
Node: Setting Permissions67777
|
||||
Node: Copying Permissions70314
|
||||
Node: Changing Special Permissions71115
|
||||
Node: Conditional Executability72951
|
||||
Node: Multiple Changes73568
|
||||
Node: Umask and Protection75216
|
||||
Node: Numeric Modes76305
|
||||
Node: Reference78135
|
||||
Node: Invoking find78433
|
||||
Node: Invoking locate79480
|
||||
Node: Invoking updatedb80163
|
||||
Node: Invoking xargs80932
|
||||
Node: Primary Index84002
|
||||
|
||||
End Tag Table
|
||||
+1581
File diff suppressed because it is too large
Load Diff
+1069
File diff suppressed because it is too large
Load Diff
+803
-3901
File diff suppressed because it is too large
Load Diff
+57
-84
@@ -46,9 +46,9 @@ everyone else.
|
||||
Files are given an owner and group when they are created. Usually the
|
||||
owner is the current user and the group is the group of the directory
|
||||
the file is in, but this varies with the operating system, the
|
||||
file system the file is created on, and the way the file is created. You
|
||||
can change the owner and group of a file by using the @command{chown} and
|
||||
@command{chgrp} commands.
|
||||
filesystem the file is created on, and the way the file is created. You
|
||||
can change the owner and group of a file by using the @code{chown} and
|
||||
@code{chgrp} commands.
|
||||
|
||||
In addition to the three sets of three permissions listed above, a
|
||||
file's permissions have three special components, which affect only
|
||||
@@ -57,11 +57,11 @@ executable files (programs) and, on some systems, directories:
|
||||
@enumerate
|
||||
@item
|
||||
@cindex setuid
|
||||
Set the process's effective user ID to that of the file upon execution
|
||||
set the process's effective user ID to that of the file upon execution
|
||||
(called the @dfn{setuid bit}). No effect on directories.
|
||||
@item
|
||||
@cindex setgid
|
||||
Set the process's effective group ID to that of the file upon execution
|
||||
set the process's effective group ID to that of the file upon execution
|
||||
(called the @dfn{setgid bit}). For directories on some systems, put
|
||||
files created in the directory into the same group as the directory, no
|
||||
matter what group the user who creates them is in.
|
||||
@@ -69,48 +69,13 @@ matter what group the user who creates them is in.
|
||||
@cindex sticky
|
||||
@cindex swap space, saving text image in
|
||||
@cindex text image, saving in swap space
|
||||
@cindex restricted deletion flag
|
||||
prevent users from removing or renaming a file in a directory
|
||||
unless they own the file or the directory; this is called the
|
||||
@dfn{restricted deletion flag} for the directory.
|
||||
For regular files on some systems, save the program's text image on the
|
||||
swap device so it will load more quickly when run; this is called the
|
||||
@dfn{sticky bit}.
|
||||
@cindex append-only directories
|
||||
save the program's text image on the swap device so it will load more
|
||||
quickly when run (called the @dfn{sticky bit}). For directories on some
|
||||
systems, prevent users from removing files that they do not own in the
|
||||
directory; this is called making the directory @dfn{append-only}.
|
||||
@end enumerate
|
||||
|
||||
In addition to the permissions listed above, there may be file attributes
|
||||
specific to the file system, e.g: access control lists (ACLs), whether a
|
||||
file is compressed, whether a file can be modified (immutability), whether
|
||||
a file can be dumped. These are usually set using programs
|
||||
specific to the file system. For example:
|
||||
@c should probably say a lot more about ACLs... someday
|
||||
|
||||
@table @asis
|
||||
@item ext2
|
||||
On @acronym{GNU} and @acronym{GNU}/Linux the file permissions
|
||||
(``attributes'') specific to
|
||||
the ext2 file system are set using @command{chattr}.
|
||||
|
||||
@item FFS
|
||||
On FreeBSD the file permissions (``flags'') specific to the FFS
|
||||
file system are set using @command{chrflags}.
|
||||
@end table
|
||||
|
||||
Although a file's permission ``bits'' allow an operation on that file,
|
||||
that operation may still fail, because:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
the file-system-specific permissions do not permit it;
|
||||
|
||||
@item
|
||||
the file system is mounted as read-only.
|
||||
@end itemize
|
||||
|
||||
For example, if the immutable attribute is set on a file,
|
||||
it cannot be modified, regardless of the fact that you
|
||||
may have just run @code{chmod a+w FILE}.
|
||||
|
||||
@node Symbolic Modes
|
||||
@section Symbolic Modes
|
||||
|
||||
@@ -124,13 +89,9 @@ their previous values, and perhaps on the current @code{umask} as well
|
||||
The format of symbolic modes is:
|
||||
|
||||
@example
|
||||
@r{[}ugoa@dots{}@r{][}+-=@r{]}@var{perms}@dots{}@r{[},@dots{}@r{]}
|
||||
@r{[}ugoa@dots{}@r{][[}+-=@r{][}rwxXstugo@dots{}@r{]}@dots{}@r{][},@dots{}@r{]}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
where @var{perms} is either zero or more letters from the set
|
||||
@samp{rwxXst}, or a single letter from the set @samp{ugo}.
|
||||
|
||||
The following sections describe the operators and other details of
|
||||
symbolic modes.
|
||||
|
||||
@@ -157,7 +118,7 @@ format:
|
||||
|
||||
@noindent
|
||||
The spaces between the three parts above are shown for readability only;
|
||||
symbolic modes cannot contain spaces.
|
||||
symbolic modes can not contain spaces.
|
||||
|
||||
The @var{users} part tells which users' access to the file is changed.
|
||||
It consists of one or more of the following letters (or it can be empty;
|
||||
@@ -199,7 +160,7 @@ have for the file.
|
||||
@end table
|
||||
|
||||
The @var{permissions} part tells what kind of access to the file should
|
||||
be changed; it is normally zero or more of the following letters. As with the
|
||||
be changed; it is zero or more of the following letters. As with the
|
||||
@var{users} part, the order does not matter when more than one letter is
|
||||
given. Omitting the @var{permissions} part is useful only with the
|
||||
@samp{=} operation, where it gives the specified @var{users} no access
|
||||
@@ -224,7 +185,7 @@ but not to execute it, use:
|
||||
a=rw
|
||||
@end example
|
||||
|
||||
To remove write permission for all users other than the file's
|
||||
To remove write permission for from all users other than the file's
|
||||
owner, use:
|
||||
|
||||
@example
|
||||
@@ -248,7 +209,7 @@ go=
|
||||
Another way to specify the same thing is:
|
||||
|
||||
@example
|
||||
og-rwx
|
||||
og-rxw
|
||||
@end example
|
||||
|
||||
@node Copying Permissions
|
||||
@@ -256,17 +217,17 @@ og-rwx
|
||||
|
||||
@cindex copying existing permissions
|
||||
@cindex permissions, copying existing
|
||||
You can base a file's permissions on its existing permissions. To do
|
||||
this, instead of using a series of @samp{r}, @samp{w}, or @samp{x}
|
||||
letters after the
|
||||
operator, you use the letter @samp{u}, @samp{g}, or @samp{o}. For
|
||||
example, the mode
|
||||
You can base part of a file's permissions on part of its existing
|
||||
permissions. To do this, instead of using @samp{r}, @samp{w}, or
|
||||
@samp{x} after the operator, you use the letter @samp{u}, @samp{g}, or
|
||||
@samp{o}. For example, the mode
|
||||
|
||||
@example
|
||||
o+g
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@c FIXME describe the ls -l notation for showing permissions.
|
||||
adds the permissions for users who are in a file's group to the
|
||||
permissions that other users have for the file. Thus, if the file
|
||||
started out as mode 664 (@samp{rw-rw-r--}), the above mode would change
|
||||
@@ -291,34 +252,45 @@ To change a file's permission to set the group ID on execution, use
|
||||
@samp{g} in the @var{users} part of the symbolic mode and
|
||||
@samp{s} in the @var{permissions} part.
|
||||
|
||||
To change a file's permission to set the restricted deletion flag or sticky bit,
|
||||
omit the @var{users} part of the symbolic mode (or use @samp{a}) and put
|
||||
To change a file's permission to stay permanently on the swap device,
|
||||
use @samp{o} in the @var{users} part of the symbolic mode and
|
||||
@samp{t} in the @var{permissions} part.
|
||||
|
||||
For example, to add set-user-ID permission to a program,
|
||||
For example, to add set user ID permission to a program,
|
||||
you can use the mode:
|
||||
|
||||
@example
|
||||
u+s
|
||||
@end example
|
||||
|
||||
To remove both set-user-ID and set-group-ID permission from
|
||||
To remove both set user ID and set group ID permission from
|
||||
it, you can use the mode:
|
||||
|
||||
@example
|
||||
ug-s
|
||||
@end example
|
||||
|
||||
To set the restricted deletion flag or sticky bit, you can use
|
||||
To cause a program to be saved on the swap device, you can use
|
||||
the mode:
|
||||
|
||||
@example
|
||||
+t
|
||||
o+t
|
||||
@end example
|
||||
|
||||
The combination @samp{o+s} has no effect. On @acronym{GNU} systems
|
||||
the combinations @samp{u+t} and @samp{g+t} have no effect, and
|
||||
@samp{o+t} acts like plain @samp{+t}.
|
||||
Remember that the special permissions only affect files that are
|
||||
executable, plus, on some systems, directories (on which they have
|
||||
different meanings; @pxref{Mode Structure}). Using @samp{a}
|
||||
in the @var{users} part of a symbolic mode does not cause the special
|
||||
permissions to be affected; thus,
|
||||
|
||||
@example
|
||||
a+s
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
has @emph{no effect}. You must use @samp{u}, @samp{g}, and @samp{o}
|
||||
explicitly to affect the special permissions. Also, the
|
||||
combinations @samp{u+t}, @samp{g+t}, and @samp{o+s} have no effect.
|
||||
|
||||
The @samp{=} operator is not very useful with special permissions; for
|
||||
example, the mode:
|
||||
@@ -328,7 +300,7 @@ o=t
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
does set the restricted deletion flag or sticky bit, but it also
|
||||
does cause the file to be saved on the swap device, but it also
|
||||
removes all read, write, and execute permissions that users not in the
|
||||
file's group might have had for it.
|
||||
|
||||
@@ -338,7 +310,9 @@ file's group might have had for it.
|
||||
@cindex conditional executability
|
||||
There is one more special type of symbolic permission: if you use
|
||||
@samp{X} instead of @samp{x}, execute permission is affected only if the
|
||||
file is a directory or already had execute permission.
|
||||
file already had execute permission or is a directory. It affects
|
||||
directories' execute permission even if they did not initially have any
|
||||
execute permissions set.
|
||||
|
||||
For example, this mode:
|
||||
|
||||
@@ -347,8 +321,8 @@ a+X
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
gives all users permission to search directories, or to execute files if
|
||||
anyone could execute them before.
|
||||
gives all users permission to execute files (or search directories) if
|
||||
anyone could before.
|
||||
|
||||
@node Multiple Changes
|
||||
@subsection Making Multiple Changes
|
||||
@@ -371,7 +345,7 @@ og+rX-w
|
||||
gives users other than the owner of the file read permission and, if
|
||||
it is a directory or if someone already had execute permission
|
||||
to it, gives them execute permission; and it also denies them write
|
||||
permission to the file. It does not affect the permission that the
|
||||
permission to it file. It does not affect the permission that the
|
||||
owner of the file has for it. The above mode is equivalent to
|
||||
the two modes:
|
||||
|
||||
@@ -459,23 +433,22 @@ the file to all users.
|
||||
@cindex numeric modes
|
||||
@cindex file permissions, numeric
|
||||
@cindex octal numbers for file modes
|
||||
As an
|
||||
File permissions are stored internally as 16 bit integers. As an
|
||||
alternative to giving a symbolic mode, you can give an octal (base 8)
|
||||
number that represents the new mode.
|
||||
number that corresponds to the internal representation of the new mode.
|
||||
This number is always interpreted in octal; you do not have to add a
|
||||
leading 0, as you do in C. Mode 0055 is the same as mode 55.
|
||||
|
||||
A numeric mode is usually shorter than the corresponding symbolic
|
||||
mode, but it is limited in that it cannot take into account a file's
|
||||
mode, but it is limited in that it can not take into account a file's
|
||||
previous permissions; it can only set them absolutely.
|
||||
|
||||
The permissions granted to the user,
|
||||
to other users in the file's group,
|
||||
and to other users not in the file's group each require three
|
||||
The permissions granted to the user, to other users in the file's group,
|
||||
and to other users not in the file's group are each stored as three
|
||||
bits, which are represented as one octal digit. The three special
|
||||
permissions also require one bit each, and they are as a group
|
||||
represented as another octal digit. Here is how the bits are arranged,
|
||||
starting with the lowest valued bit:
|
||||
permissions are also each stored as one bit, and they are as a group
|
||||
represented as another octal digit. Here is how the bits are arranged
|
||||
in the 16 bit integer, starting with the lowest valued bit:
|
||||
|
||||
@example
|
||||
Value in Corresponding
|
||||
@@ -497,7 +470,7 @@ Mode Permission
|
||||
400 Read
|
||||
|
||||
Special permissions:
|
||||
1000 Restricted deletion flag or sticky bit
|
||||
1000 Save text image on swap device
|
||||
2000 Set group ID on execution
|
||||
4000 Set user ID on execution
|
||||
@end example
|
||||
@@ -505,4 +478,4 @@ Mode Permission
|
||||
For example, numeric mode 4755 corresponds to symbolic mode
|
||||
@samp{u=rwxs,go=rx}, and numeric mode 664 corresponds to symbolic mode
|
||||
@samp{ug=rw,o=r}. Numeric mode 0 corresponds to symbolic mode
|
||||
@samp{a=}.
|
||||
@samp{ugo=}.
|
||||
|
||||
+4365
File diff suppressed because it is too large
Load Diff
+12
-36
@@ -1,38 +1,14 @@
|
||||
AUTOMAKE_OPTIONS = std-options
|
||||
localedir = $(datadir)/locale
|
||||
# noinst_PROGRAMS = regexprops
|
||||
# regexprops_SOURCES = regexprops.c
|
||||
PROGRAMS = find
|
||||
find_SOURCES = find.c fstype.c parser.c pred.c tree.c util.c version.c
|
||||
DIST_OTHER = defs.h
|
||||
INCLUDES = -I.. -I$(top_srcdir)/lib
|
||||
LDADD = ../lib/libfind.a
|
||||
MANS = find.1
|
||||
CONFIG_HEADER = ../config.h
|
||||
|
||||
noinst_LIBRARIES = libfindtools.a
|
||||
libfindtools_a_SOURCES = finddata.c fstype.c parser.c pred.c tree.c util.c
|
||||
$(PROGRAMS): ../lib/libfind.a
|
||||
|
||||
|
||||
# We always build two versions of find, one with fts, one without.
|
||||
# Their names depend on whether the user specified --with-fts.
|
||||
#
|
||||
# --with-fts find extra binary
|
||||
# yes with fts 'oldfind', without fts
|
||||
# no without fts 'ftsfind', with fts
|
||||
#
|
||||
if WITH_FTS
|
||||
bin_PROGRAMS = find oldfind
|
||||
find_SOURCES = ftsfind.c
|
||||
oldfind_SOURCES = find.c
|
||||
else
|
||||
bin_PROGRAMS = find ftsfind
|
||||
find_SOURCES = find.c
|
||||
ftsfind_SOURCES = ftsfind.c
|
||||
endif
|
||||
|
||||
EXTRA_DIST = defs.h $(man_MANS)
|
||||
INCLUDES = -I../gnulib/lib -I$(top_srcdir)/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCALEDIR=\"$(localedir)\"
|
||||
LDADD = ./libfindtools.a ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@ @LIB_CLOCK_GETTIME@ @FINDLIBS@
|
||||
man_MANS = find.1
|
||||
SUBDIRS = . testsuite
|
||||
|
||||
#$(PROGRAMS): ../lib/libfind.a
|
||||
|
||||
dist-hook: findutils-check-manpages
|
||||
|
||||
findutils-check-manpages:
|
||||
$(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
|
||||
parser.o: ../lib/modechange.h
|
||||
find.o fstype.o parser.o pred.o: ../lib/modetype.h
|
||||
find.o fstype.o parser.o pred.o tree.o util.o: defs.h
|
||||
pred.o: ../lib/wait.h
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
# Makefile.in generated automatically by automake from Makefile.am.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
datadir = $(prefix)/share
|
||||
sysconfdir = $(prefix)/etc
|
||||
sharedstatedir = $(prefix)/com
|
||||
localstatedir = $(prefix)/var
|
||||
libdir = $(exec_prefix)/lib
|
||||
infodir = $(prefix)/info
|
||||
mandir = $(prefix)/man
|
||||
includedir = $(prefix)/include
|
||||
oldincludedir = /usr/include
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
ALL = ${PROGRAMS} ${LIBPROGRAMS} ${SCRIPTS} ${LIBSCRIPTS} ${LIBFILES}
|
||||
CC = @CC@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
ANSI2KNR = ./ansi2knr
|
||||
|
||||
DEFS = @DEFS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
find_OBJECTS = find.o fstype.o parser.o pred.o tree.o util.o version.o
|
||||
NROFF = nroff
|
||||
|
||||
SOURCES = ${find_SOURCES}
|
||||
DIST_CONF = Makefile.am Makefile.in
|
||||
DIST_FILES = $(DIST_CONF) $(SOURCES) $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER)
|
||||
|
||||
PROGRAMS = find
|
||||
find_SOURCES = find.c fstype.c parser.c pred.c tree.c util.c version.c
|
||||
DIST_OTHER = defs.h
|
||||
INCLUDES = -I.. -I$(top_srcdir)/lib
|
||||
LDADD = ../lib/libfind.a
|
||||
MANS = find.1
|
||||
CONFIG_HEADER = ../config.h
|
||||
|
||||
all:: ${ALL}
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $<
|
||||
|
||||
$(find_OBJECTS): ../config.h
|
||||
install:: install-programs
|
||||
|
||||
install-programs: $(PROGRAMS) $(SCRIPTS)
|
||||
$(top_srcdir)/mkinstalldirs $(bindir)
|
||||
for p in $(PROGRAMS) $(SCRIPTS); do \
|
||||
$(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
uninstall:: uninstall-programs
|
||||
|
||||
uninstall-programs:
|
||||
for p in $(PROGRAMS) $(SCRIPTS); do \
|
||||
rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
find: $(find_OBJECTS)
|
||||
$(CC) -o $@ $(find_OBJECTS) $(LDADD) $(LDFLAGS) $(LIBS)
|
||||
|
||||
install:: install-man
|
||||
|
||||
install-man:
|
||||
for man in $(MANS); do \
|
||||
sect=`echo $$man|sed 's%.*\.\([0-9][a-z]*\)$$%\1%'`; \
|
||||
inst=`basename $$man $$sect|sed '$(transform)'`$$sect; \
|
||||
mdir=$(mandir)/man$$sect; \
|
||||
$(top_srcdir)/mkinstalldirs $$mdir; \
|
||||
echo installing $$man as $$mdir/$$inst; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$man $$mdir/$$inst; \
|
||||
cdir=$(mandir)/cat$$sect; \
|
||||
if test -d $$cdir; then \
|
||||
echo formatting $$man as $$cdir/$$inst; \
|
||||
$(NROFF) -man $(srcdir)/$$man > $$cdir/$$inst; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
uninstall:: uninstall-man
|
||||
|
||||
uninstall-man:
|
||||
for man in $(MANS); do \
|
||||
sect=`echo $$man|sed 's%.*\(\.[0-9][a-z]*\)$$%\1%'; \
|
||||
inst=`basename $$man $sect|sed '$(transform)'`.$$sect; \
|
||||
mdir=$(mandir)/man$$sect; \
|
||||
cdir=$(mandir)/cat$$sect; \
|
||||
rm -f $$mdir/$$inst $$cdir/$$inst; \
|
||||
done
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.o core
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f $(PROGRAMS) $(LIBPROGRAMS) $(LIBFILES) $(TEXFILES) $(CLEANFILES)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *.tab.c $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS $(INFOS)
|
||||
|
||||
dist: $(DIST_FILES) $(DIST_DIRS)
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
@for file in $(DIST_FILES); do \
|
||||
echo linking $$file; \
|
||||
ln $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file || \
|
||||
{ echo copying $$file instead; cp -p $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file;}; \
|
||||
done
|
||||
|
||||
check dvi info install uninstall::
|
||||
|
||||
tags:: TAGS
|
||||
|
||||
TAGS::
|
||||
cd $(srcdir); etags $(SOURCES)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
$(PROGRAMS): ../lib/libfind.a
|
||||
|
||||
parser.o: ../lib/modechange.h
|
||||
find.o fstype.o parser.o pred.o: ../lib/modetype.h
|
||||
find.o fstype.o parser.o pred.o tree.o util.o: defs.h
|
||||
pred.o: ../lib/wait.h
|
||||
+183
-510
@@ -1,101 +1,62 @@
|
||||
/* defs.h -- data types and declarations.
|
||||
Copyright (C) 1990, 91, 92, 93, 94, 2000, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
#ifndef INC_DEFS_H
|
||||
#define INC_DEFS_H 1
|
||||
|
||||
#if !defined(ALREADY_INCLUDED_CONFIG_H)
|
||||
/*
|
||||
* Savannah bug #20128: if we include some system header and it
|
||||
* includes some othersecond system header, the second system header
|
||||
* may in fact turn out to be a file provided by gnulib. For that
|
||||
* situation, we need to have already included <config.h> so that the
|
||||
* Gnulib files have access to the information probed by their
|
||||
* configure script fragments. So <config.h> should be the first
|
||||
* thing included.
|
||||
*/
|
||||
#error "<config.h> should be #included before defs.h, and indeed before any other header"
|
||||
Please stop compiling the program now
|
||||
#endif
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/* XXX: some of these includes probably don't belong in a common header file */
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h> /* for FILE* */
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#ifndef strchr
|
||||
#define strchr index
|
||||
#endif
|
||||
#ifndef strrchr
|
||||
#define strrchr rindex
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <limits.h> /* for CHAR_BIT */
|
||||
#include <stdbool.h> /* for bool/boolean */
|
||||
#include <stdint.h> /* for uintmax_t */
|
||||
#include <sys/stat.h> /* S_ISUID etc. */
|
||||
|
||||
|
||||
|
||||
#ifndef CHAR_BIT
|
||||
# define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
typedef bool boolean;
|
||||
|
||||
#include "regex.h"
|
||||
#include "timespec.h"
|
||||
#include "buildcmd.h"
|
||||
#include "quotearg.h"
|
||||
|
||||
/* These days we will assume ANSI/ISO C protootypes work on our compiler. */
|
||||
#define PARAMS(Args) Args
|
||||
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
# if HAVE_ATTRIBUTE_NORETURN
|
||||
# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
# else
|
||||
# define ATTRIBUTE_NORETURN /* nothing */
|
||||
# endif
|
||||
#if __STDC__
|
||||
# define P_(s) s
|
||||
#else
|
||||
# define P_(s) ()
|
||||
#endif
|
||||
|
||||
int optionl_stat PARAMS((const char *name, struct stat *p));
|
||||
int optionp_stat PARAMS((const char *name, struct stat *p));
|
||||
int optionh_stat PARAMS((const char *name, struct stat *p));
|
||||
int debug_stat PARAMS((const char *file, struct stat *bufp));
|
||||
/* Not char because of type promotion; NeXT gcc can't handle it. */
|
||||
typedef int boolean;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
void set_stat_placeholders PARAMS((struct stat *p));
|
||||
int get_statinfo PARAMS((const char *pathname, const char *name, struct stat *p));
|
||||
|
||||
|
||||
#define MODE_WXUSR (S_IWUSR | S_IXUSR)
|
||||
#define MODE_R (S_IRUSR | S_IRGRP | S_IROTH)
|
||||
#define MODE_RW (S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
|
||||
#define MODE_RWX (S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
|
||||
#define MODE_ALL (S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
|
||||
|
||||
|
||||
struct predicate;
|
||||
struct options;
|
||||
|
||||
/* Pointer to a predicate function. */
|
||||
typedef boolean (*PRED_FUNC)(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
|
||||
/* Pointer to function returning boolean. */
|
||||
typedef boolean (*PFB)();
|
||||
|
||||
/* The number of seconds in a day. */
|
||||
#define DAYSECS 86400
|
||||
@@ -109,13 +70,6 @@ enum comparison_type
|
||||
COMP_EQ
|
||||
};
|
||||
|
||||
enum permissions_type
|
||||
{
|
||||
PERM_AT_LEAST,
|
||||
PERM_ANY,
|
||||
PERM_EXACT
|
||||
};
|
||||
|
||||
enum predicate_type
|
||||
{
|
||||
NO_TYPE,
|
||||
@@ -139,64 +93,27 @@ enum predicate_precedence
|
||||
struct long_val
|
||||
{
|
||||
enum comparison_type kind;
|
||||
boolean negative; /* Defined only when representing time_t. */
|
||||
uintmax_t l_val;
|
||||
};
|
||||
|
||||
struct perm_val
|
||||
{
|
||||
enum permissions_type kind;
|
||||
mode_t val[2];
|
||||
};
|
||||
|
||||
/* dir_id is used to support loop detection in find.c
|
||||
*/
|
||||
struct dir_id
|
||||
{
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
};
|
||||
|
||||
/* samefile_file_id is used to support the -samefile test.
|
||||
*/
|
||||
struct samefile_file_id
|
||||
{
|
||||
ino_t ino;
|
||||
dev_t dev;
|
||||
int fd;
|
||||
unsigned long l_val;
|
||||
};
|
||||
|
||||
struct size_val
|
||||
{
|
||||
enum comparison_type kind;
|
||||
int blocksize;
|
||||
uintmax_t size;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
|
||||
enum xval
|
||||
{
|
||||
XVAL_ATIME, XVAL_BIRTHTIME, XVAL_CTIME, XVAL_MTIME, XVAL_TIME
|
||||
};
|
||||
|
||||
struct time_val
|
||||
struct path_arg
|
||||
{
|
||||
enum xval xval;
|
||||
enum comparison_type kind;
|
||||
struct timespec ts;
|
||||
short offset; /* Offset in `vec' of this arg. */
|
||||
short count; /* Number of path replacements in this arg. */
|
||||
char *origarg; /* Arg with "{}" intact. */
|
||||
};
|
||||
|
||||
|
||||
struct exec_val
|
||||
{
|
||||
boolean multiple; /* -exec {} \+ denotes multiple argument. */
|
||||
struct buildcmd_control ctl;
|
||||
struct buildcmd_state state;
|
||||
char **replace_vec; /* Command arguments (for ";" style) */
|
||||
int num_args;
|
||||
boolean use_current_dir; /* If nonzero, don't chdir to start dir */
|
||||
boolean close_stdin; /* If true, close stdin in the child. */
|
||||
int dirfd; /* The directory to do the exec in. */
|
||||
struct path_arg *paths; /* Array of args with path replacements. */
|
||||
char **vec; /* Array of args to pass to program. */
|
||||
};
|
||||
|
||||
/* The format string for a -printf or -fprintf is chopped into one or
|
||||
@@ -205,17 +122,12 @@ struct exec_val
|
||||
each \c and `%' conversion is a segment. */
|
||||
|
||||
/* Special values for the `kind' field of `struct segment'. */
|
||||
enum SegmentKind
|
||||
{
|
||||
KIND_PLAIN=0, /* Segment containing just plain text. */
|
||||
KIND_STOP=1, /* \c -- stop printing and flush output. */
|
||||
KIND_FORMAT, /* Regular format */
|
||||
};
|
||||
#define KIND_PLAIN 0 /* Segment containing just plain text. */
|
||||
#define KIND_STOP 1 /* \c -- stop printing and flush output. */
|
||||
|
||||
struct segment
|
||||
{
|
||||
enum SegmentKind segkind; /* KIND_FORMAT, KIND_PLAIN, KIND_STOP */
|
||||
char format_char[2]; /* Format chars if kind is KIND_FORMAT */
|
||||
int kind; /* Format chars or KIND_{PLAIN,STOP}. */
|
||||
char *text; /* Plain text or `%' format string. */
|
||||
int text_len; /* Length of `text'. */
|
||||
struct segment *next; /* Next segment for this predicate. */
|
||||
@@ -225,38 +137,12 @@ struct format_val
|
||||
{
|
||||
struct segment *segment; /* Linked list of segments. */
|
||||
FILE *stream; /* Output stream to print on. */
|
||||
const char *filename; /* We need the filename for error messages. */
|
||||
boolean dest_is_tty; /* True if the destination is a terminal. */
|
||||
struct quoting_options *quote_opts;
|
||||
};
|
||||
|
||||
/* Profiling information for a predicate */
|
||||
struct predicate_performance_info
|
||||
{
|
||||
unsigned long visits;
|
||||
unsigned long successes;
|
||||
};
|
||||
|
||||
/* evaluation cost of a predicate */
|
||||
enum EvaluationCost
|
||||
{
|
||||
NeedsNothing,
|
||||
NeedsType,
|
||||
NeedsStatInfo,
|
||||
NeedsLinkName,
|
||||
NeedsAccessInfo,
|
||||
NeedsSyncDiskHit,
|
||||
NeedsEventualExec,
|
||||
NeedsImmediateExec,
|
||||
NeedsUserInteraction,
|
||||
NeedsUnknown,
|
||||
NumEvaluationCosts
|
||||
};
|
||||
|
||||
struct predicate
|
||||
{
|
||||
/* Pointer to the function that implements this predicate. */
|
||||
PRED_FUNC pred_func;
|
||||
PFB pred_func;
|
||||
|
||||
/* Only used for debugging, but defined unconditionally so individual
|
||||
modules can be compiled with -DDEBUG. */
|
||||
@@ -270,54 +156,32 @@ struct predicate
|
||||
/* The precedence of this node. Only has meaning for operators. */
|
||||
enum predicate_precedence p_prec;
|
||||
|
||||
/* True if this predicate node produces side effects.
|
||||
If side_effects are produced
|
||||
then optimization will not be performed */
|
||||
/* True if this predicate node produces side effects. */
|
||||
boolean side_effects;
|
||||
|
||||
/* True if this predicate node requires default print be turned off. */
|
||||
boolean no_default_print;
|
||||
|
||||
/* True if this predicate node requires a stat system call to execute. */
|
||||
boolean need_stat;
|
||||
|
||||
/* True if this predicate node requires knowledge of the file type. */
|
||||
boolean need_type;
|
||||
|
||||
enum EvaluationCost p_cost;
|
||||
|
||||
/* est_success_rate is a number between 0.0 and 1.0 */
|
||||
float est_success_rate;
|
||||
|
||||
/* True if this predicate should display control characters literally */
|
||||
boolean literal_control_chars;
|
||||
|
||||
/* True if this predicate didn't originate from the user. */
|
||||
boolean artificial;
|
||||
|
||||
/* The raw text of the argument of this predicate. */
|
||||
char *arg_text;
|
||||
|
||||
/* Information needed by the predicate processor.
|
||||
Next to each member are listed the predicates that use it. */
|
||||
union
|
||||
{
|
||||
const char *str; /* fstype [i]lname [i]name [i]path */
|
||||
char *str; /* fstype [i]lname [i]name [i]path */
|
||||
struct re_pattern_buffer *regex; /* regex */
|
||||
struct exec_val exec_vec; /* exec ok */
|
||||
struct long_val numinfo; /* gid inum links uid */
|
||||
struct long_val info; /* atime ctime mtime inum links */
|
||||
struct size_val size; /* size */
|
||||
uid_t uid; /* user */
|
||||
gid_t gid; /* group */
|
||||
struct time_val reftime; /* newer newerXY anewer cnewer mtime atime ctime mmin amin cmin */
|
||||
struct perm_val perm; /* perm */
|
||||
struct samefile_file_id samefileid; /* samefile */
|
||||
mode_t type; /* type */
|
||||
struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
|
||||
time_t time; /* newer */
|
||||
unsigned long perm; /* perm */
|
||||
unsigned long type; /* type */
|
||||
FILE *stream; /* fprint fprint0 */
|
||||
struct format_val printf_vec; /* printf fprintf */
|
||||
} args;
|
||||
|
||||
/* The next predicate in the user input sequence,
|
||||
which represents the order in which the user supplied the
|
||||
which repesents the order in which the user supplied the
|
||||
predicates on the command line. */
|
||||
struct predicate *pred_next;
|
||||
|
||||
@@ -326,334 +190,143 @@ struct predicate
|
||||
processed. */
|
||||
struct predicate *pred_left;
|
||||
struct predicate *pred_right;
|
||||
|
||||
struct predicate_performance_info perf;
|
||||
|
||||
const struct parser_table* parser_entry;
|
||||
};
|
||||
|
||||
/* find.c, ftsfind.c */
|
||||
boolean is_fts_enabled(int *ftsoptions);
|
||||
int get_start_dirfd(void);
|
||||
int get_current_dirfd(void);
|
||||
|
||||
/* find library function declarations. */
|
||||
|
||||
/* dirname.c */
|
||||
char *dirname P_((char *path));
|
||||
|
||||
/* error.c */
|
||||
void error P_((int status, int errnum, char *message, ...));
|
||||
|
||||
/* listfile.c */
|
||||
void list_file P_((char *name, char *relname, struct stat *statp, FILE *stream));
|
||||
char *get_link_name P_((char *name, char *relname));
|
||||
|
||||
/* savedir.c */
|
||||
char *savedir P_((char *dir, unsigned name_size));
|
||||
|
||||
/* stpcpy.c */
|
||||
#if !HAVE_STPCPY
|
||||
char *stpcpy P_((char *dest, const char *src));
|
||||
#endif
|
||||
|
||||
/* xgetcwd.c */
|
||||
char *xgetcwd P_((void));
|
||||
|
||||
/* xmalloc.c */
|
||||
#if __STDC__
|
||||
#define VOID void
|
||||
#else
|
||||
#define VOID char
|
||||
#endif
|
||||
|
||||
VOID *xmalloc P_((size_t n));
|
||||
VOID *xrealloc P_((VOID *p, size_t n));
|
||||
|
||||
/* xstrdup.c */
|
||||
char *xstrdup P_((char *string));
|
||||
|
||||
/* find global function declarations. */
|
||||
|
||||
/* find.c */
|
||||
/* SymlinkOption represents the choice of
|
||||
* -P, -L or -P (default) on the command line.
|
||||
*/
|
||||
enum SymlinkOption
|
||||
{
|
||||
SYMLINK_NEVER_DEREF, /* Option -P */
|
||||
SYMLINK_ALWAYS_DEREF, /* Option -L */
|
||||
SYMLINK_DEREF_ARGSONLY /* Option -H */
|
||||
};
|
||||
extern enum SymlinkOption symlink_handling; /* defined in find.c. */
|
||||
|
||||
void set_follow_state PARAMS((enum SymlinkOption opt));
|
||||
void cleanup(void);
|
||||
|
||||
/* fstype.c */
|
||||
char *filesystem_type PARAMS((const struct stat *statp, const char *path));
|
||||
char * get_mounted_filesystems (void);
|
||||
dev_t * get_mounted_devices PARAMS((size_t *));
|
||||
|
||||
|
||||
|
||||
enum arg_type
|
||||
{
|
||||
ARG_OPTION, /* regular options like -maxdepth */
|
||||
ARG_NOOP, /* does nothing, returns true, internal use only */
|
||||
ARG_POSITIONAL_OPTION, /* options whose position is important (-follow) */
|
||||
ARG_TEST, /* a like -name */
|
||||
ARG_SPECIAL_PARSE, /* complex to parse, don't eat the test name before calling parse_xx(). */
|
||||
ARG_PUNCTUATION, /* like -o or ( */
|
||||
ARG_ACTION /* like -print */
|
||||
};
|
||||
|
||||
|
||||
struct parser_table;
|
||||
/* Pointer to a parser function. */
|
||||
typedef boolean (*PARSE_FUNC)(const struct parser_table *p,
|
||||
char *argv[], int *arg_ptr);
|
||||
struct parser_table
|
||||
{
|
||||
enum arg_type type;
|
||||
char *parser_name;
|
||||
PARSE_FUNC parser_func;
|
||||
PRED_FUNC pred_func;
|
||||
};
|
||||
char *filesystem_type P_((char *path, char *relpath, struct stat *statp));
|
||||
|
||||
/* parser.c */
|
||||
const struct parser_table* find_parser PARAMS((char *search_name));
|
||||
boolean parse_print PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
|
||||
void pred_sanity_check PARAMS((const struct predicate *predicates));
|
||||
void check_option_combinations (const struct predicate *p);
|
||||
void parse_begin_user_args PARAMS((char **args, int argno, const struct predicate *last, const struct predicate *predicates));
|
||||
void parse_end_user_args PARAMS((char **args, int argno, const struct predicate *last, const struct predicate *predicates));
|
||||
boolean parse_openparen PARAMS((const struct parser_table* entry, char *argv[], int *arg_ptr));
|
||||
boolean parse_closeparen PARAMS((const struct parser_table* entry, char *argv[], int *arg_ptr));
|
||||
PFB find_parser P_((char *search_name));
|
||||
boolean parse_close P_((char *argv[], int *arg_ptr));
|
||||
boolean parse_open P_((char *argv[], int *arg_ptr));
|
||||
boolean parse_print P_((char *argv[], int *arg_ptr));
|
||||
|
||||
/* pred.c */
|
||||
|
||||
typedef boolean PREDICATEFUNCTION(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
|
||||
PREDICATEFUNCTION pred_amin;
|
||||
PREDICATEFUNCTION pred_and;
|
||||
PREDICATEFUNCTION pred_anewer;
|
||||
PREDICATEFUNCTION pred_atime;
|
||||
PREDICATEFUNCTION pred_closeparen;
|
||||
PREDICATEFUNCTION pred_cmin;
|
||||
PREDICATEFUNCTION pred_cnewer;
|
||||
PREDICATEFUNCTION pred_comma;
|
||||
PREDICATEFUNCTION pred_ctime;
|
||||
PREDICATEFUNCTION pred_delete;
|
||||
PREDICATEFUNCTION pred_empty;
|
||||
PREDICATEFUNCTION pred_exec;
|
||||
PREDICATEFUNCTION pred_execdir;
|
||||
PREDICATEFUNCTION pred_executable;
|
||||
PREDICATEFUNCTION pred_false;
|
||||
PREDICATEFUNCTION pred_fls;
|
||||
PREDICATEFUNCTION pred_fprint;
|
||||
PREDICATEFUNCTION pred_fprint0;
|
||||
PREDICATEFUNCTION pred_fprintf;
|
||||
PREDICATEFUNCTION pred_fstype;
|
||||
PREDICATEFUNCTION pred_gid;
|
||||
PREDICATEFUNCTION pred_group;
|
||||
PREDICATEFUNCTION pred_ilname;
|
||||
PREDICATEFUNCTION pred_iname;
|
||||
PREDICATEFUNCTION pred_inum;
|
||||
PREDICATEFUNCTION pred_ipath;
|
||||
PREDICATEFUNCTION pred_links;
|
||||
PREDICATEFUNCTION pred_lname;
|
||||
PREDICATEFUNCTION pred_ls;
|
||||
PREDICATEFUNCTION pred_mmin;
|
||||
PREDICATEFUNCTION pred_mtime;
|
||||
PREDICATEFUNCTION pred_name;
|
||||
PREDICATEFUNCTION pred_negate;
|
||||
PREDICATEFUNCTION pred_newer;
|
||||
PREDICATEFUNCTION pred_newerXY;
|
||||
PREDICATEFUNCTION pred_nogroup;
|
||||
PREDICATEFUNCTION pred_nouser;
|
||||
PREDICATEFUNCTION pred_ok;
|
||||
PREDICATEFUNCTION pred_okdir;
|
||||
PREDICATEFUNCTION pred_openparen;
|
||||
PREDICATEFUNCTION pred_or;
|
||||
PREDICATEFUNCTION pred_path;
|
||||
PREDICATEFUNCTION pred_perm;
|
||||
PREDICATEFUNCTION pred_print;
|
||||
PREDICATEFUNCTION pred_print0;
|
||||
PREDICATEFUNCTION pred_prune;
|
||||
PREDICATEFUNCTION pred_quit;
|
||||
PREDICATEFUNCTION pred_readable;
|
||||
PREDICATEFUNCTION pred_regex;
|
||||
PREDICATEFUNCTION pred_samefile;
|
||||
PREDICATEFUNCTION pred_size;
|
||||
PREDICATEFUNCTION pred_true;
|
||||
PREDICATEFUNCTION pred_type;
|
||||
PREDICATEFUNCTION pred_uid;
|
||||
PREDICATEFUNCTION pred_used;
|
||||
PREDICATEFUNCTION pred_user;
|
||||
PREDICATEFUNCTION pred_writable;
|
||||
PREDICATEFUNCTION pred_xtype;
|
||||
|
||||
|
||||
|
||||
int launch PARAMS((const struct buildcmd_control *ctl,
|
||||
struct buildcmd_state *buildstate));
|
||||
|
||||
|
||||
char *find_pred_name PARAMS((PRED_FUNC pred_func));
|
||||
|
||||
|
||||
|
||||
void print_predicate PARAMS((FILE *fp, const struct predicate *p));
|
||||
void print_tree PARAMS((FILE*, struct predicate *node, int indent));
|
||||
void print_list PARAMS((FILE*, struct predicate *node));
|
||||
void print_optlist PARAMS((FILE *fp, const struct predicate *node));
|
||||
void show_success_rates(const struct predicate *node);
|
||||
|
||||
boolean pred_amin P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_and P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_anewer P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_atime P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_close P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_cmin P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_cnewer P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_comma P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_ctime P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_empty P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_exec P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_false P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_fls P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_fprint P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_fprint0 P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_fprintf P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_fstype P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_gid P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_group P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_ilname P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_iname P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_inum P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_ipath P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_links P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_lname P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_ls P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_mmin P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_mtime P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_name P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_negate P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_newer P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_nogroup P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_nouser P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_ok P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_open P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_or P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_path P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_perm P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_print P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_print0 P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_prune P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_regex P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_size P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_true P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_type P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_uid P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_used P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_user P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
boolean pred_xtype P_((char *pathname, struct stat *stat_buf, struct predicate *pred_ptr));
|
||||
char *find_pred_name P_((PFB pred_func));
|
||||
#ifdef DEBUG
|
||||
void print_tree P_((struct predicate *node, int indent));
|
||||
void print_list P_((struct predicate *node));
|
||||
#endif /* DEBUG */
|
||||
|
||||
/* tree.c */
|
||||
struct predicate * build_expression_tree PARAMS((int argc, char *argv[], int end_of_leading_options));
|
||||
struct predicate * get_eval_tree PARAMS((void));
|
||||
struct predicate *get_new_pred PARAMS((const struct parser_table *entry));
|
||||
struct predicate *get_new_pred_chk_op PARAMS((const struct parser_table *entry));
|
||||
float calculate_derived_rates PARAMS((struct predicate *p));
|
||||
struct predicate *get_expr P_((struct predicate **input, int prev_prec));
|
||||
boolean opt_expr P_((struct predicate **eval_treep));
|
||||
boolean mark_stat P_((struct predicate *tree));
|
||||
|
||||
/* util.c */
|
||||
struct predicate *insert_primary PARAMS((const struct parser_table *entry));
|
||||
struct predicate *insert_primary_withpred PARAMS((const struct parser_table *entry, PRED_FUNC fptr));
|
||||
void usage PARAMS((FILE *fp, int status, char *msg));
|
||||
extern boolean check_nofollow(void);
|
||||
void complete_pending_execs(struct predicate *p);
|
||||
void complete_pending_execdirs(int dirfd); /* Passing dirfd is an unpleasant CodeSmell. */
|
||||
const char *safely_quote_err_filename (int n, char const *arg);
|
||||
void fatal_file_error(const char *name) ATTRIBUTE_NORETURN;
|
||||
void nonfatal_file_error(const char *name);
|
||||
char *basename P_((char *fname));
|
||||
struct predicate *get_new_pred P_((void));
|
||||
struct predicate *get_new_pred_chk_op P_((void));
|
||||
struct predicate *insert_primary P_((boolean (*pred_func )()));
|
||||
void usage P_((char *msg));
|
||||
|
||||
int process_leading_options PARAMS((int argc, char *argv[]));
|
||||
void set_option_defaults PARAMS((struct options *p));
|
||||
|
||||
#if 0
|
||||
#define apply_predicate(pathname, stat_buf_ptr, node) \
|
||||
(*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
|
||||
#else
|
||||
boolean apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p);
|
||||
#endif
|
||||
|
||||
#define pred_is(node, fn) ( ((node)->pred_func) == (fn) )
|
||||
|
||||
|
||||
/* find.c. */
|
||||
int get_info PARAMS((const char *pathname, struct stat *p, struct predicate *pred_ptr));
|
||||
int following_links PARAMS((void));
|
||||
int digest_mode PARAMS((mode_t mode, const char *pathname, const char *name, struct stat *pstat, boolean leaf));
|
||||
boolean default_prints PARAMS((struct predicate *pred));
|
||||
boolean looks_like_expression PARAMS((const char *arg, boolean leading));
|
||||
|
||||
|
||||
enum DebugOption
|
||||
{
|
||||
DebugNone = 0,
|
||||
DebugExpressionTree = 1,
|
||||
DebugStat = 2,
|
||||
DebugSearch = 4,
|
||||
DebugTreeOpt = 8,
|
||||
DebugHelp = 16,
|
||||
DebugExec = 32,
|
||||
DebugSuccessRates = 64
|
||||
};
|
||||
|
||||
struct options
|
||||
{
|
||||
/* If true, process directory before contents. True unless -depth given. */
|
||||
boolean do_dir_first;
|
||||
/* If true, -depth was EXPLICITLY set (as opposed to having been turned
|
||||
* on by -delete, for example).
|
||||
*/
|
||||
boolean explicit_depth;
|
||||
|
||||
/* If >=0, don't descend more than this many levels of subdirectories. */
|
||||
int maxdepth;
|
||||
|
||||
/* If >=0, don't process files above this level. */
|
||||
int mindepth;
|
||||
|
||||
/* If true, do not assume that files in directories with nlink == 2
|
||||
are non-directories. */
|
||||
boolean no_leaf_check;
|
||||
|
||||
/* If true, don't cross filesystem boundaries. */
|
||||
boolean stay_on_filesystem;
|
||||
|
||||
/* If true, we ignore the problem where we find that a directory entry
|
||||
* no longer exists by the time we get around to processing it.
|
||||
*/
|
||||
boolean ignore_readdir_race;
|
||||
|
||||
/* If true, pass control characters through. If false, escape them
|
||||
* or turn them into harmless things.
|
||||
*/
|
||||
boolean literal_control_chars;
|
||||
|
||||
/* If true, we issue warning messages
|
||||
*/
|
||||
boolean warnings;
|
||||
|
||||
/* If true, avoid POSIX-incompatible behaviours
|
||||
* (this functionality is currently incomplete
|
||||
* and at the moment affects mainly warning messages).
|
||||
*/
|
||||
boolean posixly_correct;
|
||||
|
||||
struct timespec start_time; /* Time at start of execution. */
|
||||
|
||||
/* Either one day before now (the default), or the start of today (if -daystart is given). */
|
||||
struct timespec cur_day_start;
|
||||
|
||||
/* If true, cur_day_start has been adjusted to the start of the day. */
|
||||
boolean full_days;
|
||||
|
||||
int output_block_size; /* Output block size. */
|
||||
|
||||
/* bitmask for debug options */
|
||||
unsigned long debug_options;
|
||||
|
||||
enum SymlinkOption symlink_handling;
|
||||
|
||||
|
||||
/* Pointer to the function used to stat files. */
|
||||
int (*xstat) (const char *name, struct stat *statbuf);
|
||||
|
||||
|
||||
/* Indicate if we can implement safely_chdir() using the O_NOFOLLOW
|
||||
* flag to open(2).
|
||||
*/
|
||||
boolean open_nofollow_available;
|
||||
|
||||
/* The variety of regular expression that we support.
|
||||
* The default is POSIX Basic Regular Expressions, but this
|
||||
* can be changed with the positional option, -regextype.
|
||||
*/
|
||||
int regex_options;
|
||||
|
||||
/* Optimisation level. One is the default.
|
||||
*/
|
||||
unsigned short optimisation_level;
|
||||
|
||||
|
||||
/* How should we quote filenames in error messages and so forth?
|
||||
*/
|
||||
enum quoting_style err_quoting_style;
|
||||
};
|
||||
extern struct options options;
|
||||
|
||||
|
||||
struct state
|
||||
{
|
||||
/* Current depth; 0 means current path is a command line arg. */
|
||||
int curdepth;
|
||||
|
||||
/* If true, we have called stat on the current path. */
|
||||
boolean have_stat;
|
||||
|
||||
/* If true, we know the type of the current path. */
|
||||
boolean have_type;
|
||||
mode_t type; /* this is the actual type */
|
||||
|
||||
/* The file being operated on, relative to the current directory.
|
||||
Used for stat, readlink, remove, and opendir. */
|
||||
char *rel_pathname;
|
||||
/* The directory fd to which rel_pathname is relative. Thsi is relevant
|
||||
* when we're navigating the hierarchy with fts() and using FTS_CWDFD.
|
||||
*/
|
||||
int cwd_dir_fd;
|
||||
|
||||
/* Length of starting path. */
|
||||
int starting_path_length;
|
||||
|
||||
/* If true, don't descend past current directory.
|
||||
Can be set by -prune, -maxdepth, and -xdev/-mount. */
|
||||
boolean stop_at_current_level;
|
||||
|
||||
/* Status value to return to system. */
|
||||
int exit_status;
|
||||
|
||||
/* True if there are any execdirs. This saves us a pair of fchdir()
|
||||
* calls for every directory we leave if it is false. This is just
|
||||
* an optimisation. Set to true if you want to be conservative.
|
||||
*/
|
||||
boolean execdirs_outstanding;
|
||||
};
|
||||
|
||||
/* finddata.c */
|
||||
extern struct state state;
|
||||
extern char const *starting_dir;
|
||||
extern int starting_desc;
|
||||
extern char *program_name;
|
||||
|
||||
|
||||
extern struct predicate *predicates;
|
||||
extern struct predicate *last_pred;
|
||||
extern boolean do_dir_first;
|
||||
extern int maxdepth;
|
||||
extern int mindepth;
|
||||
extern int curdepth;
|
||||
extern time_t cur_day_start;
|
||||
extern boolean full_days;
|
||||
extern boolean no_leaf_check;
|
||||
extern boolean stay_on_filesystem;
|
||||
extern boolean stop_at_current_level;
|
||||
extern boolean have_stat;
|
||||
extern char *rel_pathname;
|
||||
#ifndef HAVE_FCHDIR
|
||||
extern char *starting_dir;
|
||||
#else
|
||||
extern int starting_desc;
|
||||
#endif
|
||||
extern int exit_status;
|
||||
extern int path_length;
|
||||
extern int (*xstat) ();
|
||||
extern boolean dereference;
|
||||
|
||||
+110
-1682
File diff suppressed because it is too large
Load Diff
+334
-1324
File diff suppressed because it is too large
Load Diff
+281
-208
@@ -1,9 +1,10 @@
|
||||
/* fstype.c -- determine type of file systems that files are on
|
||||
Copyright (C) 1990, 91, 92, 93, 94, 2000, 2004 Free Software Foundation, Inc.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
/* fstype.c -- determine type of filesystems that files are on
|
||||
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
the Free Software Foundation; either version 2, 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
|
||||
@@ -11,108 +12,144 @@
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.org>.
|
||||
*
|
||||
* Converted to use gnulib's read_file_system_list()
|
||||
* by James Youngman <jay@gnu.org> (which saves a lot
|
||||
* of manual hacking of configure.in).
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
/* The presence of unistd.h is assumed by gnulib these days, so we
|
||||
* might as well assume it too.
|
||||
*/
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_SYS_MNTIO_H
|
||||
#include <sys/mntio.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_MKDEV_H
|
||||
#include <sys/mkdev.h>
|
||||
#endif
|
||||
|
||||
#include "defs.h"
|
||||
#include "modetype.h"
|
||||
#include <errno.h>
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#include "defs.h"
|
||||
#include "../gnulib/lib/dirname.h"
|
||||
#include "xalloc.h"
|
||||
#include "modetype.h"
|
||||
char *strdup ();
|
||||
char *strstr ();
|
||||
|
||||
/* Need declaration of function `xstrtoumax' */
|
||||
#include "../gnulib/lib/xstrtol.h"
|
||||
static char *filesystem_type_uncached P_((char *path, char *relpath, struct stat *statp));
|
||||
static int xatoi P_((char *cp));
|
||||
|
||||
#include "extendbuf.h"
|
||||
#include "mountlist.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
|
||||
#include <mntent.h>
|
||||
#if !defined(MOUNTED)
|
||||
# if defined(MNT_MNTTAB) /* HP-UX. */
|
||||
# define MOUNTED MNT_MNTTAB
|
||||
# endif
|
||||
# if defined(MNTTABNAME) /* Dynix. */
|
||||
# define MOUNTED MNTTABNAME
|
||||
# endif
|
||||
#endif
|
||||
#ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
#else
|
||||
/* See locate.c for explanation as to why not use (String) */
|
||||
# define N_(String) String
|
||||
#endif
|
||||
|
||||
static char *file_system_type_uncached PARAMS((const struct stat *statp, const char *path));
|
||||
|
||||
|
||||
/* Get MNTTYPE_IGNORE if it is available. */
|
||||
#if HAVE_MNTENT_H
|
||||
# include <mntent.h>
|
||||
#endif
|
||||
#if HAVE_SYS_MNTTAB_H
|
||||
# include <stdio.h>
|
||||
# include <sys/mnttab.h>
|
||||
#ifdef FSTYPE_GETMNT /* Ultrix. */
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/fs_types.h>
|
||||
#endif
|
||||
|
||||
#ifdef FSTYPE_USG_STATFS /* SVR3. */
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/fstyp.h>
|
||||
#endif
|
||||
|
||||
#ifdef FSTYPE_STATVFS /* SVR4. */
|
||||
#include <sys/statvfs.h>
|
||||
#include <sys/fstyp.h>
|
||||
#endif
|
||||
|
||||
#ifdef FSTYPE_STATFS /* 4.4BSD. */
|
||||
#include <sys/param.h> /* NetBSD needs this. */
|
||||
#include <sys/mount.h>
|
||||
|
||||
|
||||
static void
|
||||
free_file_system_list(struct mount_entry *p)
|
||||
#ifndef MFSNAMELEN /* NetBSD defines this. */
|
||||
static char *
|
||||
fstype_to_string (t)
|
||||
short t;
|
||||
{
|
||||
while (p)
|
||||
#ifdef INITMOUNTNAMES /* Defined in 4.4BSD, not in NET/2. */
|
||||
static char *mn[] = INITMOUNTNAMES;
|
||||
if (t >= 0 && t <= MOUNT_MAXTYPE)
|
||||
return mn[t];
|
||||
else
|
||||
return "?";
|
||||
#else /* !INITMOUNTNAMES */
|
||||
switch (t)
|
||||
{
|
||||
struct mount_entry *pnext = p->me_next;
|
||||
|
||||
free(p->me_devname);
|
||||
free(p->me_mountdir);
|
||||
|
||||
if(p->me_type_malloced)
|
||||
free(p->me_type);
|
||||
p->me_next = NULL;
|
||||
free(p);
|
||||
p = pnext;
|
||||
case MOUNT_UFS:
|
||||
return "ufs";
|
||||
case MOUNT_NFS:
|
||||
return "nfs";
|
||||
#ifdef MOUNT_PC
|
||||
case MOUNT_PC:
|
||||
return "pc";
|
||||
#endif
|
||||
#ifdef MOUNT_MFS
|
||||
case MOUNT_MFS:
|
||||
return "mfs";
|
||||
#endif
|
||||
#ifdef MOUNT_LO
|
||||
case MOUNT_LO:
|
||||
return "lofs";
|
||||
#endif
|
||||
#ifdef MOUNT_TFS
|
||||
case MOUNT_TFS:
|
||||
return "tfs";
|
||||
#endif
|
||||
#ifdef MOUNT_TMP
|
||||
case MOUNT_TMP:
|
||||
return "tmp";
|
||||
#endif
|
||||
#ifdef MOUNT_MSDOS
|
||||
case MOUNT_MSDOS:
|
||||
return "msdos";
|
||||
#endif
|
||||
#ifdef MOUNT_ISO9660
|
||||
case MOUNT_ISO9660:
|
||||
return "iso9660fs";
|
||||
#endif
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
#endif /* !INITMOUNTNAMES */
|
||||
}
|
||||
#endif /* !MFSNAMELEN */
|
||||
#endif /* FSTYPE_STATFS */
|
||||
|
||||
#ifdef FSTYPE_AIX_STATFS /* AIX. */
|
||||
#include <sys/vmount.h>
|
||||
#include <sys/statfs.h>
|
||||
|
||||
#define FSTYPE_STATFS /* Otherwise like 4.4BSD. */
|
||||
#define f_type f_vfstype
|
||||
|
||||
static char *
|
||||
fstype_to_string (t)
|
||||
short t;
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case MNT_AIX:
|
||||
#if 0 /* NFS filesystems are actually MNT_AIX. */
|
||||
return "aix";
|
||||
#endif
|
||||
case MNT_NFS:
|
||||
return "nfs";
|
||||
case MNT_JFS:
|
||||
return "jfs";
|
||||
case MNT_CDROM:
|
||||
return "cdrom";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* FSTYPE_AIX_STATFS */
|
||||
|
||||
#ifdef AFS
|
||||
#include <netinet/in.h>
|
||||
@@ -128,7 +165,8 @@ free_file_system_list(struct mount_entry *p)
|
||||
#endif
|
||||
|
||||
static int
|
||||
in_afs (char *path)
|
||||
in_afs (path)
|
||||
char *path;
|
||||
{
|
||||
static char space[2048];
|
||||
struct ViceIoctl vi;
|
||||
@@ -144,16 +182,19 @@ in_afs (char *path)
|
||||
}
|
||||
#endif /* AFS */
|
||||
|
||||
/* Nonzero if the current file system's type is known. */
|
||||
/* Nonzero if the current filesystem's type is known. */
|
||||
static int fstype_known = 0;
|
||||
|
||||
/* Return a static string naming the type of file system that the file PATH,
|
||||
/* Return a static string naming the type of filesystem that the file PATH,
|
||||
described by STATP, is on.
|
||||
RELPATH is the file name relative to the current directory.
|
||||
Return "unknown" if its file system type is unknown. */
|
||||
Return "unknown" if its filesystem type is unknown. */
|
||||
|
||||
char *
|
||||
filesystem_type (const struct stat *statp, const char *path)
|
||||
filesystem_type (path, relpath, statp)
|
||||
char *path;
|
||||
char *relpath;
|
||||
struct stat *statp;
|
||||
{
|
||||
static char *current_fstype = NULL;
|
||||
static dev_t current_dev;
|
||||
@@ -165,149 +206,181 @@ filesystem_type (const struct stat *statp, const char *path)
|
||||
free (current_fstype);
|
||||
}
|
||||
current_dev = statp->st_dev;
|
||||
current_fstype = file_system_type_uncached (statp, path);
|
||||
current_fstype = filesystem_type_uncached (path, relpath, statp);
|
||||
return current_fstype;
|
||||
}
|
||||
|
||||
static int
|
||||
set_fstype_devno(struct mount_entry *p)
|
||||
{
|
||||
struct stat stbuf;
|
||||
|
||||
if (p->me_dev == (dev_t)-1)
|
||||
{
|
||||
set_stat_placeholders(&stbuf);
|
||||
if (0 == (options.xstat)(p->me_mountdir, &stbuf))
|
||||
{
|
||||
p->me_dev = stbuf.st_dev;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0; /* not needed */
|
||||
}
|
||||
|
||||
static struct mount_entry *
|
||||
must_read_fs_list(bool need_fs_type)
|
||||
{
|
||||
struct mount_entry *entries = read_file_system_list(need_fs_type);
|
||||
if (NULL == entries)
|
||||
{
|
||||
/* We cannot determine for sure which file we were trying to
|
||||
* use because gnulib has extracted all that stuff away.
|
||||
* Hence we cannot issue a specific error message here.
|
||||
*/
|
||||
error(1, 0, "Cannot read mounted file system list");
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Return a newly allocated string naming the type of file system that the
|
||||
/* Return a newly allocated string naming the type of filesystem that the
|
||||
file PATH, described by STATP, is on.
|
||||
RELPATH is the file name relative to the current directory.
|
||||
Return "unknown" if its file system type is unknown. */
|
||||
Return "unknown" if its filesystem type is unknown. */
|
||||
|
||||
static char *
|
||||
file_system_type_uncached (const struct stat *statp, const char *path)
|
||||
filesystem_type_uncached (path, relpath, statp)
|
||||
char *path;
|
||||
char *relpath;
|
||||
struct stat *statp;
|
||||
{
|
||||
struct mount_entry *entries, *entry;
|
||||
char *type;
|
||||
char *type = NULL;
|
||||
|
||||
(void) path;
|
||||
|
||||
#ifdef AFS
|
||||
if (in_afs(path))
|
||||
{
|
||||
fstype_known = 1;
|
||||
return xstrdup("afs");
|
||||
}
|
||||
#endif
|
||||
|
||||
entries = must_read_fs_list(true);
|
||||
for (type=NULL, entry=entries; entry; entry=entry->me_next)
|
||||
#ifdef FSTYPE_MNTENT /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
|
||||
char *table = MOUNTED;
|
||||
FILE *mfp;
|
||||
struct mntent *mnt;
|
||||
|
||||
mfp = setmntent (table, "r");
|
||||
if (mfp == NULL)
|
||||
error (1, errno, "%s", table);
|
||||
|
||||
/* Find the entry with the same device number as STATP, and return
|
||||
that entry's fstype. */
|
||||
while (type == NULL && (mnt = getmntent (mfp)))
|
||||
{
|
||||
char *devopt;
|
||||
dev_t dev;
|
||||
struct stat disk_stats;
|
||||
|
||||
#ifdef MNTTYPE_IGNORE
|
||||
if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
|
||||
if (!strcmp (mnt->mnt_type, MNTTYPE_IGNORE))
|
||||
continue;
|
||||
#endif
|
||||
set_fstype_devno(entry);
|
||||
if (entry->me_dev == statp->st_dev)
|
||||
|
||||
/* Newer systems like SunOS 4.1 keep the dev number in the mtab,
|
||||
in the options string. For older systems, we need to stat the
|
||||
directory that the filesystem is mounted on to get it.
|
||||
|
||||
Unfortunately, the HPUX 9.x mnttab entries created by automountq
|
||||
contain a dev= option but the option value does not match the
|
||||
st_dev value of the file (maybe the lower 16 bits match?). */
|
||||
|
||||
#if !defined(hpux) && !defined(__hpux__)
|
||||
devopt = strstr (mnt->mnt_opts, "dev=");
|
||||
if (devopt)
|
||||
{
|
||||
type = xstrdup(entry->me_type);
|
||||
break;
|
||||
if (devopt[4] == '0' && (devopt[5] == 'x' || devopt[5] == 'X'))
|
||||
dev = xatoi (devopt + 6);
|
||||
else
|
||||
dev = xatoi (devopt + 4);
|
||||
}
|
||||
else
|
||||
#endif /* not hpux */
|
||||
{
|
||||
if (stat (mnt->mnt_dir, &disk_stats) == -1)
|
||||
error (1, errno, "error in %s: %s", table, mnt->mnt_dir);
|
||||
dev = disk_stats.st_dev;
|
||||
}
|
||||
|
||||
if (dev == statp->st_dev)
|
||||
type = mnt->mnt_type;
|
||||
}
|
||||
free_file_system_list(entries);
|
||||
|
||||
/* Don't cache unknown values. */
|
||||
fstype_known = (type != NULL);
|
||||
|
||||
return type ? type : xstrdup(_("unknown"));
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
get_mounted_filesystems (void)
|
||||
{
|
||||
char *result = NULL;
|
||||
size_t alloc_size = 0u;
|
||||
size_t used = 0u;
|
||||
struct mount_entry *entries, *entry;
|
||||
|
||||
entries = must_read_fs_list(false);
|
||||
for (entry=entries; entry; entry=entry->me_next)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
#ifdef MNTTYPE_IGNORE
|
||||
if (!strcmp (entry->me_type, MNTTYPE_IGNORE))
|
||||
continue;
|
||||
if (endmntent (mfp) == 0)
|
||||
error (0, errno, "%s", table);
|
||||
#endif
|
||||
set_fstype_devno(entry);
|
||||
|
||||
len = strlen(entry->me_mountdir) + 1;
|
||||
result = extendbuf(result, used+len, &alloc_size);
|
||||
strcpy(&result[used], entry->me_mountdir);
|
||||
used += len; /* len already includes one for the \0 */
|
||||
}
|
||||
#ifdef FSTYPE_GETMNT /* Ultrix. */
|
||||
int offset = 0;
|
||||
struct fs_data fsd;
|
||||
|
||||
free_file_system_list(entries);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
dev_t *
|
||||
get_mounted_devices (size_t *n)
|
||||
{
|
||||
size_t alloc_size = 0u;
|
||||
size_t used = 0u;
|
||||
struct mount_entry *entries, *entry;
|
||||
dev_t *result = NULL;
|
||||
|
||||
/* Use read_file_system_list() rather than must_read_fs_list()
|
||||
* because on some system this is always called at startup,
|
||||
* and find should only exit fatally if it needs to use the
|
||||
* result of this operation. If we can't get the fs list
|
||||
* but we never need the information, there is no need to fail.
|
||||
*/
|
||||
for (entry = entries = read_file_system_list(false);
|
||||
entry;
|
||||
entry = entry->me_next)
|
||||
while (type == NULL
|
||||
&& getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY, 0) > 0)
|
||||
{
|
||||
result = extendbuf(result, sizeof(dev_t)*(used+1), &alloc_size);
|
||||
set_fstype_devno(entry);
|
||||
result[used] = entry->me_dev;
|
||||
++used;
|
||||
if (fsd.fd_req.dev == statp->st_dev)
|
||||
type = gt_names[fsd.fd_req.fstype];
|
||||
}
|
||||
free_file_system_list(entries);
|
||||
*n = used;
|
||||
return result;
|
||||
#endif
|
||||
|
||||
#ifdef FSTYPE_USG_STATFS /* SVR3. */
|
||||
struct statfs fss;
|
||||
char typebuf[FSTYPSZ];
|
||||
|
||||
if (statfs (relpath, &fss, sizeof (struct statfs), 0) == -1)
|
||||
{
|
||||
/* Don't die if a file was just removed. */
|
||||
if (errno != ENOENT)
|
||||
error (1, errno, "%s", path);
|
||||
}
|
||||
else if (!sysfs (GETFSTYP, fss.f_fstyp, typebuf))
|
||||
type = typebuf;
|
||||
#endif
|
||||
|
||||
#ifdef FSTYPE_STATVFS /* SVR4. */
|
||||
struct statvfs fss;
|
||||
|
||||
if (statvfs (relpath, &fss) == -1)
|
||||
{
|
||||
/* Don't die if a file was just removed. */
|
||||
if (errno != ENOENT)
|
||||
error (1, errno, "%s", path);
|
||||
}
|
||||
else
|
||||
type = fss.f_basetype;
|
||||
#endif
|
||||
|
||||
#ifdef FSTYPE_STATFS /* 4.4BSD. */
|
||||
struct statfs fss;
|
||||
char *p;
|
||||
|
||||
if (S_ISLNK (statp->st_mode))
|
||||
p = dirname (relpath);
|
||||
else
|
||||
p = relpath;
|
||||
|
||||
if (statfs (p, &fss) == -1)
|
||||
{
|
||||
/* Don't die if symlink to nonexisting file, or a file that was
|
||||
just removed. */
|
||||
if (errno != ENOENT)
|
||||
error (1, errno, "%s", path);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef MFSNAMELEN /* NetBSD. */
|
||||
type = xstrdup (fss.f_fstypename);
|
||||
#else
|
||||
type = fstype_to_string (fss.f_type);
|
||||
#endif
|
||||
}
|
||||
if (p != relpath)
|
||||
free (p);
|
||||
#endif
|
||||
|
||||
#ifdef AFS
|
||||
if ((!type || !strcmp (type, "xx")) && in_afs (relpath))
|
||||
type = "afs";
|
||||
#endif
|
||||
|
||||
/* An unknown value can be caused by an ENOENT error condition.
|
||||
Don't cache those values. */
|
||||
fstype_known = (type != NULL);
|
||||
|
||||
return xstrdup (type ? type : "unknown");
|
||||
}
|
||||
|
||||
#ifdef FSTYPE_MNTENT /* 4.3BSD etc. */
|
||||
/* Return the value of the hexadecimal number represented by CP.
|
||||
No prefix (like '0x') or suffix (like 'h') is expected to be
|
||||
part of CP. */
|
||||
|
||||
|
||||
static int
|
||||
xatoi (cp)
|
||||
char *cp;
|
||||
{
|
||||
int val;
|
||||
|
||||
val = 0;
|
||||
while (*cp)
|
||||
{
|
||||
if (*cp >= 'a' && *cp <= 'f')
|
||||
val = val * 16 + *cp - 'a' + 10;
|
||||
else if (*cp >= 'A' && *cp <= 'F')
|
||||
val = val * 16 + *cp - 'A' + 10;
|
||||
else if (*cp >= '0' && *cp <= '9')
|
||||
val = val * 16 + *cp - '0';
|
||||
else
|
||||
break;
|
||||
cp++;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
+1243
-2873
File diff suppressed because it is too large
Load Diff
+832
-1715
File diff suppressed because it is too large
Load Diff
+137
-1359
File diff suppressed because it is too large
Load Diff
+113
-994
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1 @@
|
||||
char *version_string = "4.1";
|
||||
Executable
+238
@@ -0,0 +1,238 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# install - install a program, script, or datafile
|
||||
# This comes from X11R5.
|
||||
#
|
||||
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||
# `make' implicit rules from creating a file called install from it
|
||||
# when there is no Makefile.
|
||||
#
|
||||
# This script is compatible with the BSD install script, but was written
|
||||
# from scratch.
|
||||
#
|
||||
|
||||
|
||||
# set DOITPROG to echo to test this script
|
||||
|
||||
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||
doit="${DOITPROG-}"
|
||||
|
||||
|
||||
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||
|
||||
mvprog="${MVPROG-mv}"
|
||||
cpprog="${CPPROG-cp}"
|
||||
chmodprog="${CHMODPROG-chmod}"
|
||||
chownprog="${CHOWNPROG-chown}"
|
||||
chgrpprog="${CHGRPPROG-chgrp}"
|
||||
stripprog="${STRIPPROG-strip}"
|
||||
rmprog="${RMPROG-rm}"
|
||||
mkdirprog="${MKDIRPROG-mkdir}"
|
||||
|
||||
tranformbasename=""
|
||||
transform_arg=""
|
||||
instcmd="$mvprog"
|
||||
chmodcmd="$chmodprog 0755"
|
||||
chowncmd=""
|
||||
chgrpcmd=""
|
||||
stripcmd=""
|
||||
rmcmd="$rmprog -f"
|
||||
mvcmd="$mvprog"
|
||||
src=""
|
||||
dst=""
|
||||
dir_arg=""
|
||||
|
||||
while [ x"$1" != x ]; do
|
||||
case $1 in
|
||||
-c) instcmd="$cpprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-d) dir_arg=true
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-m) chmodcmd="$chmodprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-o) chowncmd="$chownprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-g) chgrpcmd="$chgrpprog $2"
|
||||
shift
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-s) stripcmd="$stripprog"
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||
shift
|
||||
continue;;
|
||||
|
||||
*) if [ x"$src" = x ]
|
||||
then
|
||||
src=$1
|
||||
else
|
||||
# this colon is to work around a 386BSD /bin/sh bug
|
||||
:
|
||||
dst=$1
|
||||
fi
|
||||
shift
|
||||
continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ x"$src" = x ]
|
||||
then
|
||||
echo "install: no input file specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
instcmd=mkdir
|
||||
fi
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
exit 1
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# If destination is a directory, append the input filename; if your system
|
||||
# does not like double slashes in filenames, you may need to add some logic
|
||||
|
||||
if [ -d $dst ]
|
||||
then
|
||||
dst="$dst"/`basename $src`
|
||||
else
|
||||
true
|
||||
fi
|
||||
fi
|
||||
|
||||
## this sed command emulates the dirname command
|
||||
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Make sure that the destination directory exists.
|
||||
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
oIFS="${IFS}"
|
||||
# Some sh's can't handle IFS=/ for some reason.
|
||||
IFS='%'
|
||||
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||
IFS="${oIFS}"
|
||||
|
||||
pathcomp=''
|
||||
|
||||
while [ $# -ne 0 ] ; do
|
||||
pathcomp="${pathcomp}${1}"
|
||||
shift
|
||||
|
||||
if [ ! -d "${pathcomp}" ] ;
|
||||
then
|
||||
$mkdirprog "${pathcomp}"
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
pathcomp="${pathcomp}/"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ x"$dir_arg" != x ]
|
||||
then
|
||||
$doit $instcmd $dst &&
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
|
||||
else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
true
|
||||
fi
|
||||
|
||||
# Make a temp file name in the proper directory.
|
||||
|
||||
dsttmp=$dstdir/#inst.$$#
|
||||
|
||||
# Move or copy the file name to the temp name
|
||||
|
||||
$doit $instcmd $src $dsttmp &&
|
||||
|
||||
trap "rm -f ${dsttmp}" 0 &&
|
||||
|
||||
# and set any options; do chmod last to preserve setuid bits
|
||||
|
||||
# If any of these fail, we abort the whole thing. If we want to
|
||||
# ignore errors from any of these, just make sure not to ignore
|
||||
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||
|
||||
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
|
||||
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
|
||||
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
|
||||
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
|
||||
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
exit 0
|
||||
+15
-40
@@ -1,44 +1,19 @@
|
||||
## Process this file with automake to produce Makefile.in.
|
||||
LIBRARIES = find
|
||||
find_SOURCES = regex.c dirname.c error.c filemode.c getopt.c getopt1.c \
|
||||
idcache.c listfile.c modechange.c nextelem.c savedir.c xmalloc.c getline.c \
|
||||
xstrdup.c xgetcwd.c fnmatch.c $(find_OPT_SOURCES)
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.5 gnits
|
||||
# no-dependencies
|
||||
find_OPT_SOURCES = fileblocks.c memcmp.c memset.c mktime.c stpcpy.c strdup.c \
|
||||
strftime.c strspn.c strstr.c strtol.c alloca.c
|
||||
|
||||
noinst_LIBRARIES = libfind.a
|
||||
DIST_OTHER = fnmatch.h getopt.h modechange.h modetype.h pathmax.h \
|
||||
regex.h wait.h
|
||||
|
||||
if CROSS_COMPILING
|
||||
# The regexprops program needs to be a native executable, so we
|
||||
# can't build it with a cross-compiler.
|
||||
else
|
||||
noinst_PROGRAMS = regexprops
|
||||
regexprops_SOURCES = regexprops.c regextype.c
|
||||
endif
|
||||
|
||||
libfind_a_SOURCES = gnulib-version.c findutils-version.c
|
||||
EXTRA_DIST = modetype.h wait.h extendbuf.h savedirinfo.h buildcmd.h \
|
||||
gnulib-version.h gnulib-version.c findutils-version.h
|
||||
BUILT_SOURCES = gnulib-version.c
|
||||
SUFFIXES =
|
||||
MOSTLYCLEANFILES =
|
||||
CLEANFILES =
|
||||
DISTCLEANFILES =
|
||||
MAINTAINERCLEANFILES =
|
||||
|
||||
|
||||
INCLUDES = -I../gnulib/lib -I$(top_srcdir)/gnulib/lib
|
||||
LDADD = ../gnulib/lib/libgnulib.a @LIBINTL@
|
||||
|
||||
libfind_a_SOURCES += modetype.h nextelem.h printquoted.h listfile.h \
|
||||
regextype.h dircallback.h
|
||||
libfind_a_SOURCES += listfile.c nextelem.c extendbuf.c buildcmd.c savedirinfo.c \
|
||||
forcefindlib.c qmark.c printquoted.c regextype.c dircallback.c
|
||||
|
||||
EXTRA_DIST += waitpid.c forcefindlib.c
|
||||
|
||||
|
||||
libfind_a_LIBADD = @FINDLIBOBJS@
|
||||
libfind_a_DEPENDENCIES = @FINDLIBOBJS@
|
||||
# libfind_la_LIBADD = @LTFINDLIBOBJS@
|
||||
|
||||
# libfind_a_OBJECTS += @FINDLIBOBJS@
|
||||
# libfind_la_OBJECTS += @LTFINDLIBOBJS@
|
||||
CONFIG_HEADER = ../config.h
|
||||
INCLUDES = -I.. -I$(srcdir)
|
||||
|
||||
fnmatch.o: fnmatch.h
|
||||
getopt1.o: getopt.h
|
||||
listfile.o xgetcwd.o: pathmax.h
|
||||
modechange.o: modechange.h
|
||||
regex.o: regex.h
|
||||
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
# Makefile.in generated automatically by automake from Makefile.am.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
datadir = $(prefix)/share
|
||||
sysconfdir = $(prefix)/etc
|
||||
sharedstatedir = $(prefix)/com
|
||||
localstatedir = $(prefix)/var
|
||||
libdir = $(exec_prefix)/lib
|
||||
infodir = $(prefix)/info
|
||||
mandir = $(prefix)/man
|
||||
includedir = $(prefix)/include
|
||||
oldincludedir = /usr/include
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
ALL = ${PROGRAMS} ${LIBPROGRAMS} ${SCRIPTS} ${LIBSCRIPTS} ${LIBFILES}
|
||||
CC = @CC@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
ANSI2KNR = ./ansi2knr
|
||||
|
||||
DEFS = @DEFS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
find_OBJECTS = regex.o dirname.o error.o filemode.o getopt.o getopt1.o idcache.o listfile.o modechange.o nextelem.o savedir.o xmalloc.o getline.o xstrdup.o xgetcwd.o fnmatch.o
|
||||
LIBFILES = libfind.a
|
||||
AR = ar
|
||||
RANLIB = @RANLIB@
|
||||
ALLOCA = @ALLOCA@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
|
||||
SOURCES = ${find_SOURCES}
|
||||
DIST_CONF = Makefile.am Makefile.in
|
||||
DIST_FILES = $(DIST_CONF) $(SOURCES) $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER)
|
||||
|
||||
LIBRARIES = find
|
||||
find_SOURCES = regex.c dirname.c error.c filemode.c getopt.c getopt1.c \
|
||||
idcache.c listfile.c modechange.c nextelem.c savedir.c xmalloc.c getline.c \
|
||||
xstrdup.c xgetcwd.c fnmatch.c $(find_OPT_SOURCES)
|
||||
|
||||
find_OPT_SOURCES = fileblocks.c memcmp.c memset.c mktime.c stpcpy.c strdup.c \
|
||||
strftime.c strspn.c strstr.c strtol.c alloca.c
|
||||
|
||||
DIST_OTHER = fnmatch.h getopt.h modechange.h modetype.h pathmax.h \
|
||||
regex.h wait.h
|
||||
|
||||
CONFIG_HEADER = ../config.h
|
||||
INCLUDES = -I.. -I$(srcdir)
|
||||
|
||||
all:: ${ALL}
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $<
|
||||
|
||||
$(find_OBJECTS): ../config.h
|
||||
install:: install-libraries
|
||||
|
||||
install-libraries: $(LIBFILES)
|
||||
|
||||
uninstall:: uninstall-libraries
|
||||
|
||||
uninstall-libraries:
|
||||
|
||||
libfind.a: $(find_OBJECTS) @LIBOBJS@ @ALLOCA@
|
||||
rm -f libfind.a
|
||||
$(AR) cru libfind.a $(find_OBJECTS) @LIBOBJS@ @ALLOCA@
|
||||
$(RANLIB) libfind.a
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.o core
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f $(PROGRAMS) $(LIBPROGRAMS) $(LIBFILES) $(TEXFILES) $(CLEANFILES)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *.tab.c $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS $(INFOS)
|
||||
|
||||
dist: $(DIST_FILES) $(DIST_DIRS)
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
@for file in $(DIST_FILES); do \
|
||||
echo linking $$file; \
|
||||
ln $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file || \
|
||||
{ echo copying $$file instead; cp -p $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file;}; \
|
||||
done
|
||||
|
||||
check dvi info install uninstall::
|
||||
|
||||
tags:: TAGS
|
||||
|
||||
TAGS::
|
||||
cd $(srcdir); etags $(SOURCES)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
fnmatch.o: fnmatch.h
|
||||
getopt1.o: getopt.h
|
||||
listfile.o xgetcwd.o: pathmax.h
|
||||
modechange.o: modechange.h
|
||||
regex.o: regex.h
|
||||
+492
@@ -0,0 +1,492 @@
|
||||
/* alloca.c -- allocate automatically reclaimed memory
|
||||
(Mostly) portable public-domain implementation -- D A Gwyn
|
||||
|
||||
This implementation of the PWB library alloca function,
|
||||
which is used to allocate space off the run-time stack so
|
||||
that it is automatically reclaimed upon procedure exit,
|
||||
was inspired by discussions with J. Q. Johnson of Cornell.
|
||||
J.Otto Tennant <jot@cray.com> contributed the Cray support.
|
||||
|
||||
There are some preprocessor constants that can
|
||||
be defined when compiling for your specific system, for
|
||||
improved efficiency; however, the defaults should be okay.
|
||||
|
||||
The general concept of this implementation is to keep
|
||||
track of all alloca-allocated blocks, and reclaim any
|
||||
that are found to be deeper in the stack than the current
|
||||
invocation. This heuristic does not reclaim storage as
|
||||
soon as it becomes invalid, but it will do so eventually.
|
||||
|
||||
As a special case, alloca(0) reclaims storage without
|
||||
allocating any. It is a good idea to use alloca(0) in
|
||||
your main control loop, etc. to force garbage collection. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#include "blockinput.h"
|
||||
#endif
|
||||
|
||||
/* If compiling with GCC 2, this file's not needed. */
|
||||
#if !defined (__GNUC__) || __GNUC__ < 2
|
||||
|
||||
/* If someone has defined alloca as a macro,
|
||||
there must be some other way alloca is supposed to work. */
|
||||
#ifndef alloca
|
||||
|
||||
#ifdef emacs
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
-- this is for usg, in which emacs must undefine static
|
||||
in order to make unexec workable
|
||||
*/
|
||||
#ifndef STACK_DIRECTION
|
||||
you
|
||||
lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
|
||||
/* If your stack is a linked list of frames, you have to
|
||||
provide an "address metric" ADDRESS_FUNCTION macro. */
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
long i00afunc ();
|
||||
#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
|
||||
#else
|
||||
#define ADDRESS_FUNCTION(arg) &(arg)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer;
|
||||
#else
|
||||
typedef char *pointer;
|
||||
#endif
|
||||
|
||||
#define NULL 0
|
||||
|
||||
/* Different portions of Emacs need to call different versions of
|
||||
malloc. The Emacs executable needs alloca to call xmalloc, because
|
||||
ordinary malloc isn't protected from input signals. On the other
|
||||
hand, the utilities in lib-src need alloca to call malloc; some of
|
||||
them are very simple, and don't have an xmalloc routine.
|
||||
|
||||
Non-Emacs programs expect this to call use xmalloc.
|
||||
|
||||
Callers below should use malloc. */
|
||||
|
||||
#ifndef emacs
|
||||
#define malloc xmalloc
|
||||
#endif
|
||||
extern pointer malloc ();
|
||||
|
||||
/* Define STACK_DIRECTION if you know the direction of stack
|
||||
growth for your system; otherwise it will be automatically
|
||||
deduced at run-time.
|
||||
|
||||
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||
|
||||
#ifndef STACK_DIRECTION
|
||||
#define STACK_DIRECTION 0 /* Direction unknown. */
|
||||
#endif
|
||||
|
||||
#if STACK_DIRECTION != 0
|
||||
|
||||
#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
|
||||
|
||||
#else /* STACK_DIRECTION == 0; need run-time code. */
|
||||
|
||||
static int stack_dir; /* 1 or -1 once known. */
|
||||
#define STACK_DIR stack_dir
|
||||
|
||||
static void
|
||||
find_stack_direction ()
|
||||
{
|
||||
static char *addr = NULL; /* Address of first `dummy', once known. */
|
||||
auto char dummy; /* To get stack address. */
|
||||
|
||||
if (addr == NULL)
|
||||
{ /* Initial entry. */
|
||||
addr = ADDRESS_FUNCTION (dummy);
|
||||
|
||||
find_stack_direction (); /* Recurse once. */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second entry. */
|
||||
if (ADDRESS_FUNCTION (dummy) > addr)
|
||||
stack_dir = 1; /* Stack grew upward. */
|
||||
else
|
||||
stack_dir = -1; /* Stack grew downward. */
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* STACK_DIRECTION == 0 */
|
||||
|
||||
/* An "alloca header" is used to:
|
||||
(a) chain together all alloca'ed blocks;
|
||||
(b) keep track of stack depth.
|
||||
|
||||
It is very important that sizeof(header) agree with malloc
|
||||
alignment chunk size. The following default should work okay. */
|
||||
|
||||
#ifndef ALIGN_SIZE
|
||||
#define ALIGN_SIZE sizeof(double)
|
||||
#endif
|
||||
|
||||
typedef union hdr
|
||||
{
|
||||
char align[ALIGN_SIZE]; /* To force sizeof(header). */
|
||||
struct
|
||||
{
|
||||
union hdr *next; /* For chaining headers. */
|
||||
char *deep; /* For stack depth measure. */
|
||||
} h;
|
||||
} header;
|
||||
|
||||
static header *last_alloca_header = NULL; /* -> last alloca header. */
|
||||
|
||||
/* Return a pointer to at least SIZE bytes of storage,
|
||||
which will be automatically reclaimed upon exit from
|
||||
the procedure that called alloca. Originally, this space
|
||||
was supposed to be taken from the current stack frame of the
|
||||
caller, but that method cannot be made to work for some
|
||||
implementations of C, for example under Gould's UTX/32. */
|
||||
|
||||
pointer
|
||||
alloca (size)
|
||||
unsigned size;
|
||||
{
|
||||
auto char probe; /* Probes stack depth: */
|
||||
register char *depth = ADDRESS_FUNCTION (probe);
|
||||
|
||||
#if STACK_DIRECTION == 0
|
||||
if (STACK_DIR == 0) /* Unknown growth direction. */
|
||||
find_stack_direction ();
|
||||
#endif
|
||||
|
||||
/* Reclaim garbage, defined as all alloca'd storage that
|
||||
was allocated from deeper in the stack than currently. */
|
||||
|
||||
{
|
||||
register header *hp; /* Traverses linked list. */
|
||||
|
||||
#ifdef emacs
|
||||
BLOCK_INPUT;
|
||||
#endif
|
||||
|
||||
for (hp = last_alloca_header; hp != NULL;)
|
||||
if ((STACK_DIR > 0 && hp->h.deep > depth)
|
||||
|| (STACK_DIR < 0 && hp->h.deep < depth))
|
||||
{
|
||||
register header *np = hp->h.next;
|
||||
|
||||
free ((pointer) hp); /* Collect garbage. */
|
||||
|
||||
hp = np; /* -> next header. */
|
||||
}
|
||||
else
|
||||
break; /* Rest are not deeper. */
|
||||
|
||||
last_alloca_header = hp; /* -> last valid storage. */
|
||||
|
||||
#ifdef emacs
|
||||
UNBLOCK_INPUT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
return NULL; /* No allocation required. */
|
||||
|
||||
/* Allocate combined header + user data storage. */
|
||||
|
||||
{
|
||||
register pointer new = malloc (sizeof (header) + size);
|
||||
/* Address of header. */
|
||||
|
||||
((header *) new)->h.next = last_alloca_header;
|
||||
((header *) new)->h.deep = depth;
|
||||
|
||||
last_alloca_header = (header *) new;
|
||||
|
||||
/* User storage begins just after header. */
|
||||
|
||||
return (pointer) ((char *) new + sizeof (header));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (CRAY) && defined (CRAY_STACKSEG_END)
|
||||
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#ifndef CRAY_STACK
|
||||
#define CRAY_STACK
|
||||
#ifndef CRAY2
|
||||
/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
|
||||
struct stack_control_header
|
||||
{
|
||||
long shgrow:32; /* Number of times stack has grown. */
|
||||
long shaseg:32; /* Size of increments to stack. */
|
||||
long shhwm:32; /* High water mark of stack. */
|
||||
long shsize:32; /* Current size of stack (all segments). */
|
||||
};
|
||||
|
||||
/* The stack segment linkage control information occurs at
|
||||
the high-address end of a stack segment. (The stack
|
||||
grows from low addresses to high addresses.) The initial
|
||||
part of the stack segment linkage control information is
|
||||
0200 (octal) words. This provides for register storage
|
||||
for the routine which overflows the stack. */
|
||||
|
||||
struct stack_segment_linkage
|
||||
{
|
||||
long ss[0200]; /* 0200 overflow words. */
|
||||
long sssize:32; /* Number of words in this segment. */
|
||||
long ssbase:32; /* Offset to stack base. */
|
||||
long:32;
|
||||
long sspseg:32; /* Offset to linkage control of previous
|
||||
segment of stack. */
|
||||
long:32;
|
||||
long sstcpt:32; /* Pointer to task common address block. */
|
||||
long sscsnm; /* Private control structure number for
|
||||
microtasking. */
|
||||
long ssusr1; /* Reserved for user. */
|
||||
long ssusr2; /* Reserved for user. */
|
||||
long sstpid; /* Process ID for pid based multi-tasking. */
|
||||
long ssgvup; /* Pointer to multitasking thread giveup. */
|
||||
long sscray[7]; /* Reserved for Cray Research. */
|
||||
long ssa0;
|
||||
long ssa1;
|
||||
long ssa2;
|
||||
long ssa3;
|
||||
long ssa4;
|
||||
long ssa5;
|
||||
long ssa6;
|
||||
long ssa7;
|
||||
long sss0;
|
||||
long sss1;
|
||||
long sss2;
|
||||
long sss3;
|
||||
long sss4;
|
||||
long sss5;
|
||||
long sss6;
|
||||
long sss7;
|
||||
};
|
||||
|
||||
#else /* CRAY2 */
|
||||
/* The following structure defines the vector of words
|
||||
returned by the STKSTAT library routine. */
|
||||
struct stk_stat
|
||||
{
|
||||
long now; /* Current total stack size. */
|
||||
long maxc; /* Amount of contiguous space which would
|
||||
be required to satisfy the maximum
|
||||
stack demand to date. */
|
||||
long high_water; /* Stack high-water mark. */
|
||||
long overflows; /* Number of stack overflow ($STKOFEN) calls. */
|
||||
long hits; /* Number of internal buffer hits. */
|
||||
long extends; /* Number of block extensions. */
|
||||
long stko_mallocs; /* Block allocations by $STKOFEN. */
|
||||
long underflows; /* Number of stack underflow calls ($STKRETN). */
|
||||
long stko_free; /* Number of deallocations by $STKRETN. */
|
||||
long stkm_free; /* Number of deallocations by $STKMRET. */
|
||||
long segments; /* Current number of stack segments. */
|
||||
long maxs; /* Maximum number of stack segments so far. */
|
||||
long pad_size; /* Stack pad size. */
|
||||
long current_address; /* Current stack segment address. */
|
||||
long current_size; /* Current stack segment size. This
|
||||
number is actually corrupted by STKSTAT to
|
||||
include the fifteen word trailer area. */
|
||||
long initial_address; /* Address of initial segment. */
|
||||
long initial_size; /* Size of initial segment. */
|
||||
};
|
||||
|
||||
/* The following structure describes the data structure which trails
|
||||
any stack segment. I think that the description in 'asdef' is
|
||||
out of date. I only describe the parts that I am sure about. */
|
||||
|
||||
struct stk_trailer
|
||||
{
|
||||
long this_address; /* Address of this block. */
|
||||
long this_size; /* Size of this block (does not include
|
||||
this trailer). */
|
||||
long unknown2;
|
||||
long unknown3;
|
||||
long link; /* Address of trailer block of previous
|
||||
segment. */
|
||||
long unknown5;
|
||||
long unknown6;
|
||||
long unknown7;
|
||||
long unknown8;
|
||||
long unknown9;
|
||||
long unknown10;
|
||||
long unknown11;
|
||||
long unknown12;
|
||||
long unknown13;
|
||||
long unknown14;
|
||||
};
|
||||
|
||||
#endif /* CRAY2 */
|
||||
#endif /* not CRAY_STACK */
|
||||
|
||||
#ifdef CRAY2
|
||||
/* Determine a "stack measure" for an arbitrary ADDRESS.
|
||||
I doubt that "lint" will like this much. */
|
||||
|
||||
static long
|
||||
i00afunc (long *address)
|
||||
{
|
||||
struct stk_stat status;
|
||||
struct stk_trailer *trailer;
|
||||
long *block, size;
|
||||
long result = 0;
|
||||
|
||||
/* We want to iterate through all of the segments. The first
|
||||
step is to get the stack status structure. We could do this
|
||||
more quickly and more directly, perhaps, by referencing the
|
||||
$LM00 common block, but I know that this works. */
|
||||
|
||||
STKSTAT (&status);
|
||||
|
||||
/* Set up the iteration. */
|
||||
|
||||
trailer = (struct stk_trailer *) (status.current_address
|
||||
+ status.current_size
|
||||
- 15);
|
||||
|
||||
/* There must be at least one stack segment. Therefore it is
|
||||
a fatal error if "trailer" is null. */
|
||||
|
||||
if (trailer == 0)
|
||||
abort ();
|
||||
|
||||
/* Discard segments that do not contain our argument address. */
|
||||
|
||||
while (trailer != 0)
|
||||
{
|
||||
block = (long *) trailer->this_address;
|
||||
size = trailer->this_size;
|
||||
if (block == 0 || size == 0)
|
||||
abort ();
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
if ((block <= address) && (address < (block + size)))
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set the result to the offset in this segment and add the sizes
|
||||
of all predecessor segments. */
|
||||
|
||||
result = address - block;
|
||||
|
||||
if (trailer == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (trailer->this_size <= 0)
|
||||
abort ();
|
||||
result += trailer->this_size;
|
||||
trailer = (struct stk_trailer *) trailer->link;
|
||||
}
|
||||
while (trailer != 0);
|
||||
|
||||
/* We are done. Note that if you present a bogus address (one
|
||||
not in any segment), you will get a different number back, formed
|
||||
from subtracting the address of the first block. This is probably
|
||||
not what you want. */
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
#else /* not CRAY2 */
|
||||
/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
|
||||
Determine the number of the cell within the stack,
|
||||
given the address of the cell. The purpose of this
|
||||
routine is to linearize, in some sense, stack addresses
|
||||
for alloca. */
|
||||
|
||||
static long
|
||||
i00afunc (long address)
|
||||
{
|
||||
long stkl = 0;
|
||||
|
||||
long size, pseg, this_segment, stack;
|
||||
long result = 0;
|
||||
|
||||
struct stack_segment_linkage *ssptr;
|
||||
|
||||
/* Register B67 contains the address of the end of the
|
||||
current stack segment. If you (as a subprogram) store
|
||||
your registers on the stack and find that you are past
|
||||
the contents of B67, you have overflowed the segment.
|
||||
|
||||
B67 also points to the stack segment linkage control
|
||||
area, which is what we are really interested in. */
|
||||
|
||||
stkl = CRAY_STACKSEG_END ();
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
|
||||
/* If one subtracts 'size' from the end of the segment,
|
||||
one has the address of the first word of the segment.
|
||||
|
||||
If this is not the first segment, 'pseg' will be
|
||||
nonzero. */
|
||||
|
||||
pseg = ssptr->sspseg;
|
||||
size = ssptr->sssize;
|
||||
|
||||
this_segment = stkl - size;
|
||||
|
||||
/* It is possible that calling this routine itself caused
|
||||
a stack overflow. Discard stack segments which do not
|
||||
contain the target address. */
|
||||
|
||||
while (!(this_segment <= address && address <= stkl))
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
|
||||
#endif
|
||||
if (pseg == 0)
|
||||
break;
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
this_segment = stkl - size;
|
||||
}
|
||||
|
||||
result = address - this_segment;
|
||||
|
||||
/* If you subtract pseg from the current end of the stack,
|
||||
you get the address of the previous stack segment's end.
|
||||
This seems a little convoluted to me, but I'll bet you save
|
||||
a cycle somewhere. */
|
||||
|
||||
while (pseg != 0)
|
||||
{
|
||||
#ifdef DEBUG_I00AFUNC
|
||||
fprintf (stderr, "%011o %011o\n", pseg, size);
|
||||
#endif
|
||||
stkl = stkl - pseg;
|
||||
ssptr = (struct stack_segment_linkage *) stkl;
|
||||
size = ssptr->sssize;
|
||||
pseg = ssptr->sspseg;
|
||||
result += size;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
#endif /* not CRAY2 */
|
||||
#endif /* CRAY */
|
||||
|
||||
#endif /* no alloca */
|
||||
#endif /* not GCC version 2 */
|
||||
@@ -0,0 +1,70 @@
|
||||
/* dirname.c -- return all but the last element in a path
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
#endif
|
||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#ifndef strrchr
|
||||
#define strrchr rindex
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Return the leading directories part of PATH,
|
||||
allocated with malloc. If out of memory, return 0.
|
||||
Assumes that trailing slashes have already been
|
||||
removed. */
|
||||
|
||||
char *
|
||||
dirname (path)
|
||||
char *path;
|
||||
{
|
||||
char *newpath;
|
||||
char *slash;
|
||||
int length; /* Length of result, not including NUL. */
|
||||
|
||||
slash = strrchr (path, '/');
|
||||
if (slash == 0)
|
||||
{
|
||||
/* File is in the current directory. */
|
||||
path = ".";
|
||||
length = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove any trailing slashes from the result. */
|
||||
while (slash > path && *slash == '/')
|
||||
--slash;
|
||||
|
||||
length = slash - path + 1;
|
||||
}
|
||||
newpath = (char *) malloc (length + 1);
|
||||
if (newpath == 0)
|
||||
return 0;
|
||||
strncpy (newpath, path, length);
|
||||
newpath[length] = 0;
|
||||
return newpath;
|
||||
}
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/* error.c -- error handler for noninteractive utilities
|
||||
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if HAVE_VPRINTF || HAVE_DOPRNT
|
||||
# if __STDC__
|
||||
# include <stdarg.h>
|
||||
# define VA_START(args, lastarg) va_start(args, lastarg)
|
||||
# else
|
||||
# include <varargs.h>
|
||||
# define VA_START(args, lastarg) va_start(args)
|
||||
# endif
|
||||
#else
|
||||
# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
|
||||
# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else
|
||||
void exit ();
|
||||
#endif
|
||||
|
||||
/* If NULL, error will flush stdout, then print on stderr the program
|
||||
name, a colon and a space. Otherwise, error will call this
|
||||
function without parameters instead. */
|
||||
void (*error_print_progname) () = NULL;
|
||||
|
||||
/* The calling program should define program_name and set it to the
|
||||
name of the executing program. */
|
||||
extern char *program_name;
|
||||
|
||||
#if HAVE_STRERROR
|
||||
char *strerror ();
|
||||
#else
|
||||
static char *
|
||||
private_strerror (errnum)
|
||||
int errnum;
|
||||
{
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
if (errnum > 0 && errnum <= sys_nerr)
|
||||
return sys_errlist[errnum];
|
||||
return "Unknown system error";
|
||||
}
|
||||
#define strerror private_strerror
|
||||
#endif
|
||||
|
||||
/* Print the program name and error message MESSAGE, which is a printf-style
|
||||
format string with optional args.
|
||||
If ERRNUM is nonzero, print its corresponding system error message.
|
||||
Exit with status STATUS if it is nonzero. */
|
||||
/* VARARGS */
|
||||
|
||||
void
|
||||
#if defined(VA_START) && __STDC__
|
||||
error (int status, int errnum, const char *message, ...)
|
||||
#else
|
||||
error (status, errnum, message, va_alist)
|
||||
int status;
|
||||
int errnum;
|
||||
char *message;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
#ifdef VA_START
|
||||
va_list args;
|
||||
#endif
|
||||
|
||||
if (error_print_progname)
|
||||
(*error_print_progname) ();
|
||||
else
|
||||
{
|
||||
fflush (stdout);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
}
|
||||
|
||||
#ifdef VA_START
|
||||
VA_START (args, message);
|
||||
# if HAVE_VPRINTF
|
||||
vfprintf (stderr, message, args);
|
||||
# else
|
||||
_doprnt (message, args, stderr);
|
||||
# endif
|
||||
va_end (args);
|
||||
#else
|
||||
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
#endif
|
||||
|
||||
if (errnum)
|
||||
fprintf (stderr, ": %s", strerror (errnum));
|
||||
putc ('\n', stderr);
|
||||
fflush (stderr);
|
||||
if (status)
|
||||
exit (status);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/* Convert file size to number of blocks on System V-like machines.
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by Brian L. Matthews, blm@6sceng.UUCP. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_ST_BLOCKS) && !defined(_POSIX_SOURCE)
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef NINDIR
|
||||
/* Some SysV's, like Irix, seem to lack these. Hope they're correct. */
|
||||
/* Size of a indirect block, in bytes. */
|
||||
#ifndef BSIZE
|
||||
#define BSIZE 1024
|
||||
#endif
|
||||
|
||||
/* Number of inode pointers per indirect block. */
|
||||
#define NINDIR (BSIZE/sizeof(daddr_t))
|
||||
#endif /* !NINDIR */
|
||||
|
||||
/* Number of direct block addresses in an inode. */
|
||||
#define NDIR 10
|
||||
|
||||
/* Return the number of 512-byte blocks in a file of SIZE bytes. */
|
||||
|
||||
long
|
||||
st_blocks (size)
|
||||
long size;
|
||||
{
|
||||
long datablks = (size + 512 - 1) / 512;
|
||||
long indrblks = 0;
|
||||
|
||||
if (datablks > NDIR)
|
||||
{
|
||||
indrblks = (datablks - NDIR - 1) / NINDIR + 1;
|
||||
|
||||
if (datablks > NDIR + NINDIR)
|
||||
{
|
||||
indrblks += (datablks - NDIR - NINDIR - 1) / (NINDIR * NINDIR) + 1;
|
||||
|
||||
if (datablks > NDIR + NINDIR + NINDIR * NINDIR)
|
||||
indrblks++;
|
||||
}
|
||||
}
|
||||
|
||||
return datablks + indrblks;
|
||||
}
|
||||
#endif
|
||||
+237
@@ -0,0 +1,237 @@
|
||||
/* filemode.c -- make a string describing file modes
|
||||
Copyright (C) 1985, 1990, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifndef S_IREAD
|
||||
#define S_IREAD S_IRUSR
|
||||
#define S_IWRITE S_IWUSR
|
||||
#define S_IEXEC S_IXUSR
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#undef S_ISBLK
|
||||
#undef S_ISCHR
|
||||
#undef S_ISDIR
|
||||
#undef S_ISFIFO
|
||||
#undef S_ISLNK
|
||||
#undef S_ISMPB
|
||||
#undef S_ISMPC
|
||||
#undef S_ISNWK
|
||||
#undef S_ISREG
|
||||
#undef S_ISSOCK
|
||||
#endif /* STAT_MACROS_BROKEN. */
|
||||
|
||||
#if !defined(S_ISBLK) && defined(S_IFBLK)
|
||||
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
#if !defined(S_ISCHR) && defined(S_IFCHR)
|
||||
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
||||
#endif
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISREG) && defined(S_IFREG)
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if !defined(S_ISFIFO) && defined(S_IFIFO)
|
||||
#define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
||||
#endif
|
||||
#if !defined(S_ISLNK) && defined(S_IFLNK)
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
|
||||
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
|
||||
#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
|
||||
#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
|
||||
#endif
|
||||
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
|
||||
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
||||
#endif
|
||||
|
||||
void mode_string ();
|
||||
static char ftypelet ();
|
||||
static void rwx ();
|
||||
static void setst ();
|
||||
|
||||
/* filemodestring - fill in string STR with an ls-style ASCII
|
||||
representation of the st_mode field of file stats block STATP.
|
||||
10 characters are stored in STR; no terminating null is added.
|
||||
The characters stored in STR are:
|
||||
|
||||
0 File type. 'd' for directory, 'c' for character
|
||||
special, 'b' for block special, 'm' for multiplex,
|
||||
'l' for symbolic link, 's' for socket, 'p' for fifo,
|
||||
'-' for regular, '?' for any other file type
|
||||
|
||||
1 'r' if the owner may read, '-' otherwise.
|
||||
|
||||
2 'w' if the owner may write, '-' otherwise.
|
||||
|
||||
3 'x' if the owner may execute, 's' if the file is
|
||||
set-user-id, '-' otherwise.
|
||||
'S' if the file is set-user-id, but the execute
|
||||
bit isn't set.
|
||||
|
||||
4 'r' if group members may read, '-' otherwise.
|
||||
|
||||
5 'w' if group members may write, '-' otherwise.
|
||||
|
||||
6 'x' if group members may execute, 's' if the file is
|
||||
set-group-id, '-' otherwise.
|
||||
'S' if it is set-group-id but not executable.
|
||||
|
||||
7 'r' if any user may read, '-' otherwise.
|
||||
|
||||
8 'w' if any user may write, '-' otherwise.
|
||||
|
||||
9 'x' if any user may execute, 't' if the file is "sticky"
|
||||
(will be retained in swap space after execution), '-'
|
||||
otherwise.
|
||||
'T' if the file is sticky but not executable. */
|
||||
|
||||
void
|
||||
filemodestring (statp, str)
|
||||
struct stat *statp;
|
||||
char *str;
|
||||
{
|
||||
mode_string (statp->st_mode, str);
|
||||
}
|
||||
|
||||
/* Like filemodestring, but only the relevant part of the `struct stat'
|
||||
is given as an argument. */
|
||||
|
||||
void
|
||||
mode_string (mode, str)
|
||||
unsigned short mode;
|
||||
char *str;
|
||||
{
|
||||
str[0] = ftypelet ((long) mode);
|
||||
rwx ((mode & 0700) << 0, &str[1]);
|
||||
rwx ((mode & 0070) << 3, &str[4]);
|
||||
rwx ((mode & 0007) << 6, &str[7]);
|
||||
setst (mode, str);
|
||||
}
|
||||
|
||||
/* Return a character indicating the type of file described by
|
||||
file mode BITS:
|
||||
'd' for directories
|
||||
'b' for block special files
|
||||
'c' for character special files
|
||||
'm' for multiplexor files
|
||||
'l' for symbolic links
|
||||
's' for sockets
|
||||
'p' for fifos
|
||||
'-' for regular files
|
||||
'?' for any other file type. */
|
||||
|
||||
static char
|
||||
ftypelet (bits)
|
||||
long bits;
|
||||
{
|
||||
#ifdef S_ISBLK
|
||||
if (S_ISBLK (bits))
|
||||
return 'b';
|
||||
#endif
|
||||
if (S_ISCHR (bits))
|
||||
return 'c';
|
||||
if (S_ISDIR (bits))
|
||||
return 'd';
|
||||
if (S_ISREG (bits))
|
||||
return '-';
|
||||
#ifdef S_ISFIFO
|
||||
if (S_ISFIFO (bits))
|
||||
return 'p';
|
||||
#endif
|
||||
#ifdef S_ISLNK
|
||||
if (S_ISLNK (bits))
|
||||
return 'l';
|
||||
#endif
|
||||
#ifdef S_ISSOCK
|
||||
if (S_ISSOCK (bits))
|
||||
return 's';
|
||||
#endif
|
||||
#ifdef S_ISMPC
|
||||
if (S_ISMPC (bits))
|
||||
return 'm';
|
||||
#endif
|
||||
#ifdef S_ISNWK
|
||||
if (S_ISNWK (bits))
|
||||
return 'n';
|
||||
#endif
|
||||
return '?';
|
||||
}
|
||||
|
||||
/* Look at read, write, and execute bits in BITS and set
|
||||
flags in CHARS accordingly. */
|
||||
|
||||
static void
|
||||
rwx (bits, chars)
|
||||
unsigned short bits;
|
||||
char *chars;
|
||||
{
|
||||
chars[0] = (bits & S_IREAD) ? 'r' : '-';
|
||||
chars[1] = (bits & S_IWRITE) ? 'w' : '-';
|
||||
chars[2] = (bits & S_IEXEC) ? 'x' : '-';
|
||||
}
|
||||
|
||||
/* Set the 's' and 't' flags in file attributes string CHARS,
|
||||
according to the file mode BITS. */
|
||||
|
||||
static void
|
||||
setst (bits, chars)
|
||||
unsigned short bits;
|
||||
char *chars;
|
||||
{
|
||||
#ifdef S_ISUID
|
||||
if (bits & S_ISUID)
|
||||
{
|
||||
if (chars[3] != 'x')
|
||||
/* Set-uid, but not executable by owner. */
|
||||
chars[3] = 'S';
|
||||
else
|
||||
chars[3] = 's';
|
||||
}
|
||||
#endif
|
||||
#ifdef S_ISGID
|
||||
if (bits & S_ISGID)
|
||||
{
|
||||
if (chars[6] != 'x')
|
||||
/* Set-gid, but not executable by group. */
|
||||
chars[6] = 'S';
|
||||
else
|
||||
chars[6] = 's';
|
||||
}
|
||||
#endif
|
||||
#ifdef S_ISVTX
|
||||
if (bits & S_ISVTX)
|
||||
{
|
||||
if (chars[9] != 'x')
|
||||
/* Sticky, but not executable by others. */
|
||||
chars[9] = 'T';
|
||||
else
|
||||
chars[9] = 't';
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register char c;
|
||||
|
||||
/* Note that this evalutes C many times. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_FILE_NAME) && *n == '/')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD (*n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
|
||||
if (((flags & FNM_FILE_NAME) && *n == '/') ||
|
||||
(c == '?' && *n == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '\0')
|
||||
return 0;
|
||||
|
||||
{
|
||||
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
|
||||
c1 = FOLD (c1);
|
||||
for (--p; *n != '\0'; ++n)
|
||||
if ((c == '[' || FOLD (*n) == c1) &&
|
||||
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
register int not;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || *p == '^');
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
register char cstart = c, cend = c;
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
cstart = cend = *p++;
|
||||
|
||||
cstart = cend = FOLD (cstart);
|
||||
|
||||
if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
if ((flags & FNM_FILE_NAME) && c == '/')
|
||||
/* [/] can never match. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
cend = FOLD (cend);
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
|
||||
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
|
||||
goto matched;
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:;
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD (*n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
@@ -0,0 +1,67 @@
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _FNMATCH_H
|
||||
|
||||
#define _FNMATCH_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
|
||||
#undef __P
|
||||
#define __P(args) args
|
||||
#else /* Not C++ or ANSI C. */
|
||||
#undef __P
|
||||
#define __P(args) ()
|
||||
/* We can get away without defining `const' here only because in this file
|
||||
it is used only inside the prototype for `fnmatch', which is elided in
|
||||
non-ANSI C where `const' is problematical. */
|
||||
#endif /* C++ or ANSI C. */
|
||||
|
||||
|
||||
/* We #undef these before defining them because some losing systems
|
||||
(HP-UX A.08.07 for example) define these in <unistd.h>. */
|
||||
#undef FNM_PATHNAME
|
||||
#undef FNM_NOESCAPE
|
||||
#undef FNM_PERIOD
|
||||
|
||||
/* Bits set in the FLAGS argument to `fnmatch'. */
|
||||
#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
|
||||
#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
|
||||
#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
|
||||
|
||||
#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
|
||||
#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
|
||||
#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
|
||||
#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
|
||||
#endif
|
||||
|
||||
/* Value returned by `fnmatch' if STRING does not match PATTERN. */
|
||||
#define FNM_NOMATCH 1
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN,
|
||||
returning zero if it matches, FNM_NOMATCH if not. */
|
||||
extern int fnmatch __P ((const char *__pattern, const char *__string,
|
||||
int __flags));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* fnmatch.h */
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/* getline.c -- Replacement for GNU C library function getline
|
||||
|
||||
Copyright (C) 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by Jan Brittenson, bson@gnu.ai.mit.edu. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#define NDEBUG
|
||||
#include <assert.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc (), *realloc ();
|
||||
#endif
|
||||
|
||||
/* Always add at least this many bytes when extending the buffer. */
|
||||
#define MIN_CHUNK 64
|
||||
|
||||
/* Read up to (and including) a TERMINATOR from STREAM into *LINEPTR
|
||||
+ OFFSET (and null-terminate it). *LINEPTR is a pointer returned from
|
||||
malloc (or NULL), pointing to *N characters of space. It is realloc'd
|
||||
as necessary. Return the number of characters read (not including the
|
||||
null terminator), or -1 on error or EOF. */
|
||||
|
||||
int
|
||||
getstr (lineptr, n, stream, terminator, offset)
|
||||
char **lineptr;
|
||||
size_t *n;
|
||||
FILE *stream;
|
||||
char terminator;
|
||||
int offset;
|
||||
{
|
||||
int nchars_avail; /* Allocated but unused chars in *LINEPTR. */
|
||||
char *read_pos; /* Where we're reading into *LINEPTR. */
|
||||
int ret;
|
||||
|
||||
if (!lineptr || !n || !stream)
|
||||
return -1;
|
||||
|
||||
if (!*lineptr)
|
||||
{
|
||||
*n = MIN_CHUNK;
|
||||
*lineptr = malloc (*n);
|
||||
if (!*lineptr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
nchars_avail = *n - offset;
|
||||
read_pos = *lineptr + offset;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
register int c = getc (stream);
|
||||
|
||||
/* We always want at least one char left in the buffer, since we
|
||||
always (unless we get an error while reading the first char)
|
||||
NUL-terminate the line buffer. */
|
||||
|
||||
assert(*n - nchars_avail == read_pos - *lineptr);
|
||||
if (nchars_avail < 1)
|
||||
{
|
||||
if (*n > MIN_CHUNK)
|
||||
*n *= 2;
|
||||
else
|
||||
*n += MIN_CHUNK;
|
||||
|
||||
nchars_avail = *n + *lineptr - read_pos;
|
||||
*lineptr = realloc (*lineptr, *n);
|
||||
if (!*lineptr)
|
||||
return -1;
|
||||
read_pos = *n - nchars_avail + *lineptr;
|
||||
assert(*n - nchars_avail == read_pos - *lineptr);
|
||||
}
|
||||
|
||||
if (c == EOF || ferror (stream))
|
||||
{
|
||||
/* Return partial line, if any. */
|
||||
if (read_pos == *lineptr)
|
||||
return -1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
*read_pos++ = c;
|
||||
nchars_avail--;
|
||||
|
||||
if (c == terminator)
|
||||
/* Return the line. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Done - NUL terminate and return the number of chars read. */
|
||||
*read_pos = '\0';
|
||||
|
||||
ret = read_pos - (*lineptr + offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
getline (lineptr, n, stream)
|
||||
char **lineptr;
|
||||
size_t *n;
|
||||
FILE *stream;
|
||||
{
|
||||
return getstr (lineptr, n, stream, '\n', 0);
|
||||
}
|
||||
+748
@@ -0,0 +1,748 @@
|
||||
/* Getopt for GNU.
|
||||
NOTE: getopt is now part of the C library, so if you don't know what
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
|
||||
As `getopt' works, it permutes the elements of ARGV so that,
|
||||
when it is done, all the options precede everything else. Thus
|
||||
all application programs are extended to handle flexible argument order.
|
||||
|
||||
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||
Then the behavior is completely standard.
|
||||
|
||||
GNU application programs can use a third alternative mode in which
|
||||
they can distinguish the relative order of options and other arguments. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = NULL;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
/* XXX 1003.2 says this must be 1 before any call. */
|
||||
int optind = 0;
|
||||
|
||||
/* The next char to be scanned in the option-element
|
||||
in which the last option character we returned was found.
|
||||
This allows us to pick up the scan where we left off.
|
||||
|
||||
If this is zero, or a null string, it means resume the scan
|
||||
by advancing to the next ARGV-element. */
|
||||
|
||||
static char *nextchar;
|
||||
|
||||
/* Callers store zero here to inhibit the error message
|
||||
for unrecognized options. */
|
||||
|
||||
int opterr = 1;
|
||||
|
||||
/* Set to an option character which was unrecognized.
|
||||
This must be initialized on some systems to avoid linking in the
|
||||
system's own getopt implementation. */
|
||||
|
||||
int optopt = '?';
|
||||
|
||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||
|
||||
If the caller did not specify anything,
|
||||
the default is REQUIRE_ORDER if the environment variable
|
||||
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options;
|
||||
stop option processing when the first non-option is seen.
|
||||
This is what Unix does.
|
||||
This mode of operation is selected by either setting the environment
|
||||
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||
of the list of option characters.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||
so that eventually all the non-options are at the end. This allows options
|
||||
to be given in any order, even with programs that were not written to
|
||||
expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written
|
||||
to expect options and other ARGV-elements in any order and that care about
|
||||
the ordering of the two. We describe each non-option ARGV-element
|
||||
as if it were the argument of an option with character code 1.
|
||||
Using `-' as the first character of the list of option characters
|
||||
selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless
|
||||
of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
`--' can cause `getopt' to return EOF with `optind' != ARGC. */
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
static char *posixly_correct;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index strchr
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
whose names are inconsistent. */
|
||||
|
||||
char *getenv ();
|
||||
|
||||
static char *
|
||||
my_index (str, chr)
|
||||
const char *str;
|
||||
int chr;
|
||||
{
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (char *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
If not using GCC, it is ok not to declare it. */
|
||||
#ifdef __GNUC__
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
/* Describe the part of ARGV that contains non-options that have
|
||||
been skipped. `first_nonopt' is the index in ARGV of the first of them;
|
||||
`last_nonopt' is the index after the last of them. */
|
||||
|
||||
static int first_nonopt;
|
||||
static int last_nonopt;
|
||||
|
||||
/* Exchange two adjacent subsequences of ARGV.
|
||||
One subsequence is elements [first_nonopt,last_nonopt)
|
||||
which contains all the non-options that have been skipped so far.
|
||||
The other is elements [last_nonopt,optind), which contains all
|
||||
the options processed since those non-options were skipped.
|
||||
|
||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||
the new indices of the non-options in ARGV after they are moved. */
|
||||
|
||||
static void
|
||||
exchange (argv)
|
||||
char **argv;
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = optind;
|
||||
char *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
{
|
||||
if (top - middle > middle - bottom)
|
||||
{
|
||||
/* Bottom segment is the short one. */
|
||||
int len = middle - bottom;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the top part of the top segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||
argv[top - (middle - bottom) + i] = tem;
|
||||
}
|
||||
/* Exclude the moved bottom segment from further swapping. */
|
||||
top -= len;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Top segment is the short one. */
|
||||
int len = top - middle;
|
||||
register int i;
|
||||
|
||||
/* Swap it with the bottom part of the bottom segment. */
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
tem = argv[bottom + i];
|
||||
argv[bottom + i] = argv[middle + i];
|
||||
argv[middle + i] = tem;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const char *
|
||||
_getopt_initialize (optstring)
|
||||
const char *optstring;
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
|
||||
If an element of ARGV starts with '-', and is not exactly "-" or "--",
|
||||
then it is an option element. The characters of this element
|
||||
(aside from the initial '-') are option characters. If `getopt'
|
||||
is called repeatedly, it returns successively each of the option characters
|
||||
from each of the option elements.
|
||||
|
||||
If `getopt' finds another option character, it returns that character,
|
||||
updating `optind' and `nextchar' so that the next call to `getopt' can
|
||||
resume the scan with the following option character or ARGV-element.
|
||||
|
||||
If there are no more option characters, `getopt' returns `EOF'.
|
||||
Then `optind' is the index in ARGV of the first ARGV-element
|
||||
that is not an option. (The ARGV-elements have been permuted
|
||||
so that those that are not options now come last.)
|
||||
|
||||
OPTSTRING is a string containing the legitimate option characters.
|
||||
If an option character is seen that is not listed in OPTSTRING,
|
||||
return '?' after printing an error message. If you set `opterr' to
|
||||
zero, the error message is suppressed but we still return '?'.
|
||||
|
||||
If a char in OPTSTRING is followed by a colon, that means it wants an arg,
|
||||
so the following text in the same ARGV-element, or the text of the following
|
||||
ARGV-element, is returned in `optarg'. Two colons mean an option that
|
||||
wants an optional arg; if there is text in the current ARGV-element,
|
||||
it is returned in `optarg', otherwise `optarg' is set to zero.
|
||||
|
||||
If OPTSTRING starts with `-' or `+', it requests different methods of
|
||||
handling the non-option ARGV-elements.
|
||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||
|
||||
Long-named options begin with `--' instead of `-'.
|
||||
Their names may be abbreviated as long as the abbreviation is unique
|
||||
or is an exact match for some defined option. If they have an
|
||||
argument, it follows the option name in the same ARGV-element, separated
|
||||
from the option name by a `=', or else the in next ARGV-element.
|
||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||
`flag' field is nonzero, the value of the option's `val' field
|
||||
if the `flag' field is zero.
|
||||
|
||||
The elements of ARGV aren't really const, because we permute them.
|
||||
But we pretend they're const in the prototype to be compatible
|
||||
with other systems.
|
||||
|
||||
LONGOPTS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
|
||||
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||
It is only valid when a long-named option has been found by the most
|
||||
recent call.
|
||||
|
||||
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||
long-named options. */
|
||||
|
||||
int
|
||||
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
const struct option *longopts;
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
optarg = NULL;
|
||||
|
||||
if (optind == 0)
|
||||
optstring = _getopt_initialize (optstring);
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
|
||||
if (optind != argc && !strcmp (argv[optind], "--"))
|
||||
{
|
||||
optind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||
exchange ((char **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = optind;
|
||||
last_nonopt = argc;
|
||||
|
||||
optind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (optind == argc)
|
||||
{
|
||||
/* Set the next-arg-index to point at the non-options
|
||||
that we previously skipped, so the caller will digest them. */
|
||||
if (first_nonopt != last_nonopt)
|
||||
optind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
optarg = argv[optind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[optind][1] == '-'
|
||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound;
|
||||
int option_index;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if (nameend - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
exact = 1;
|
||||
break;
|
||||
}
|
||||
else if (pfound == NULL)
|
||||
{
|
||||
/* First nonexact match found. */
|
||||
pfound = p;
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
if (ambig && !exact)
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||
argv[0], argv[optind]);
|
||||
nextchar += strlen (nextchar);
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind - 1][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr,
|
||||
"%s: option `--%s' doesn't allow an argument\n",
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr,
|
||||
"%s: option `%c%s' doesn't allow an argument\n",
|
||||
argv[0], argv[optind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (optind < argc)
|
||||
optarg = argv[optind++];
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||
argv[0], argv[optind - 1]);
|
||||
nextchar += strlen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += strlen (nextchar);
|
||||
if (longind != NULL)
|
||||
*longind = option_index;
|
||||
if (pfound->flag)
|
||||
{
|
||||
*(pfound->flag) = pfound->val;
|
||||
return 0;
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (argv[optind][1] == '-')
|
||||
/* --option */
|
||||
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||
argv[0], argv[optind][0], nextchar);
|
||||
}
|
||||
nextchar = (char *) "";
|
||||
optind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
char *temp = my_index (optstring, c);
|
||||
|
||||
/* Increment `optind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++optind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
optarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
optind++;
|
||||
}
|
||||
else if (optind == argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `optind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
optarg = argv[optind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getopt (argc, argv, optstring)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *optstring;
|
||||
{
|
||||
return _getopt_internal (argc, argv, optstring,
|
||||
(const struct option *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
/* Compile with -DTEST to make an executable for use in testing
|
||||
the above definition of `getopt'. */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
|
||||
c = getopt (argc, argv, "abc:d:0123456789");
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
the argument value is returned here.
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
extern char *optarg;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
and for communication between successive calls to `getopt'.
|
||||
|
||||
On entry to `getopt', zero means this is the first call; initialize.
|
||||
|
||||
When `getopt' returns EOF, this is the index of the first of the
|
||||
non-option elements that the caller should itself scan.
|
||||
|
||||
Otherwise, `optind' communicates from one call to the next
|
||||
how much of ARGV has been scanned so far. */
|
||||
|
||||
extern int optind;
|
||||
|
||||
/* Callers store zero here to inhibit the error message `getopt' prints
|
||||
for unrecognized options. */
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
To have a long-named option do something other than set an `int' to
|
||||
a compiled-in constant, such as set a value from `optarg', set the
|
||||
option's `flag' field to zero and its `val' field to a nonzero
|
||||
value (the equivalent single-letter option character, if there is
|
||||
one). For long options that have a zero `flag' field, `getopt'
|
||||
returns the contents of the `val' field. */
|
||||
|
||||
struct option
|
||||
{
|
||||
#if defined (__STDC__) && __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if defined (__STDC__) && __STDC__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined (__STDC__) || !__STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
int c;
|
||||
int digit_optind = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"add", 1, 0, 0},
|
||||
{"append", 0, 0, 0},
|
||||
{"delete", 1, 0, 0},
|
||||
{"verbose", 0, 0, 0},
|
||||
{"create", 0, 0, 0},
|
||||
{"file", 1, 0, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "abc:d:0123456789",
|
||||
long_options, &option_index);
|
||||
if (c == EOF)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
break;
|
||||
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
if (digit_optind != 0 && digit_optind != this_option_optind)
|
||||
printf ("digits occur in two different argv-elements.\n");
|
||||
digit_optind = this_option_optind;
|
||||
printf ("option %c\n", c);
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
printf ("option a\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
printf ("option b\n");
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("?? getopt returned character code 0%o ??\n", c);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
{
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
#endif /* TEST */
|
||||
+210
@@ -0,0 +1,210 @@
|
||||
/* idcache.c -- map user and group IDs, cached for speed
|
||||
Copyright (C) 1985, 1988, 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifndef _POSIX_VERSION
|
||||
struct passwd *getpwuid ();
|
||||
struct passwd *getpwnam ();
|
||||
struct group *getgrgid ();
|
||||
struct group *getgrnam ();
|
||||
#endif
|
||||
|
||||
char *xmalloc ();
|
||||
char *xstrdup ();
|
||||
|
||||
struct userid
|
||||
{
|
||||
union
|
||||
{
|
||||
uid_t u;
|
||||
gid_t g;
|
||||
} id;
|
||||
char *name;
|
||||
struct userid *next;
|
||||
};
|
||||
|
||||
static struct userid *user_alist;
|
||||
|
||||
/* The members of this list have names not in the local passwd file. */
|
||||
static struct userid *nouser_alist;
|
||||
|
||||
/* Translate UID to a login name or a stringified number,
|
||||
with cache. */
|
||||
|
||||
char *
|
||||
getuser (uid)
|
||||
uid_t uid;
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct passwd *pwent;
|
||||
char usernum_string[20];
|
||||
|
||||
for (tail = user_alist; tail; tail = tail->next)
|
||||
if (tail->id.u == uid)
|
||||
return tail->name;
|
||||
|
||||
pwent = getpwuid (uid);
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->id.u = uid;
|
||||
if (pwent == 0)
|
||||
{
|
||||
sprintf (usernum_string, "%u", (unsigned) uid);
|
||||
tail->name = xstrdup (usernum_string);
|
||||
}
|
||||
else
|
||||
tail->name = xstrdup (pwent->pw_name);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
tail->next = user_alist;
|
||||
user_alist = tail;
|
||||
return tail->name;
|
||||
}
|
||||
|
||||
/* Translate USER to a UID, with cache.
|
||||
Return NULL if there is no such user.
|
||||
(We also cache which user names have no passwd entry,
|
||||
so we don't keep looking them up.) */
|
||||
|
||||
uid_t *
|
||||
getuidbyname (user)
|
||||
char *user;
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct passwd *pwent;
|
||||
|
||||
for (tail = user_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *user && !strcmp (tail->name, user))
|
||||
return &tail->id.u;
|
||||
|
||||
for (tail = nouser_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *user && !strcmp (tail->name, user))
|
||||
return 0;
|
||||
|
||||
pwent = getpwnam (user);
|
||||
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->name = xstrdup (user);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
if (pwent)
|
||||
{
|
||||
tail->id.u = pwent->pw_uid;
|
||||
tail->next = user_alist;
|
||||
user_alist = tail;
|
||||
return &tail->id.u;
|
||||
}
|
||||
|
||||
tail->next = nouser_alist;
|
||||
nouser_alist = tail;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use the same struct as for userids. */
|
||||
static struct userid *group_alist;
|
||||
static struct userid *nogroup_alist;
|
||||
|
||||
/* Translate GID to a group name or a stringified number,
|
||||
with cache. */
|
||||
|
||||
char *
|
||||
getgroup (gid)
|
||||
gid_t gid;
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct group *grent;
|
||||
char groupnum_string[20];
|
||||
|
||||
for (tail = group_alist; tail; tail = tail->next)
|
||||
if (tail->id.g == gid)
|
||||
return tail->name;
|
||||
|
||||
grent = getgrgid (gid);
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->id.g = gid;
|
||||
if (grent == 0)
|
||||
{
|
||||
sprintf (groupnum_string, "%u", (unsigned int) gid);
|
||||
tail->name = xstrdup (groupnum_string);
|
||||
}
|
||||
else
|
||||
tail->name = xstrdup (grent->gr_name);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
tail->next = group_alist;
|
||||
group_alist = tail;
|
||||
return tail->name;
|
||||
}
|
||||
|
||||
/* Translate GROUP to a UID, with cache.
|
||||
Return NULL if there is no such group.
|
||||
(We also cache which group names have no group entry,
|
||||
so we don't keep looking them up.) */
|
||||
|
||||
gid_t *
|
||||
getgidbyname (group)
|
||||
char *group;
|
||||
{
|
||||
register struct userid *tail;
|
||||
struct group *grent;
|
||||
|
||||
for (tail = group_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *group && !strcmp (tail->name, group))
|
||||
return &tail->id.g;
|
||||
|
||||
for (tail = nogroup_alist; tail; tail = tail->next)
|
||||
/* Avoid a function call for the most common case. */
|
||||
if (*tail->name == *group && !strcmp (tail->name, group))
|
||||
return 0;
|
||||
|
||||
grent = getgrnam (group);
|
||||
|
||||
tail = (struct userid *) xmalloc (sizeof (struct userid));
|
||||
tail->name = xstrdup (group);
|
||||
|
||||
/* Add to the head of the list, so most recently used is first. */
|
||||
if (grent)
|
||||
{
|
||||
tail->id.g = grent->gr_gid;
|
||||
tail->next = group_alist;
|
||||
group_alist = tail;
|
||||
return &tail->id.g;
|
||||
}
|
||||
|
||||
tail->next = nogroup_alist;
|
||||
nogroup_alist = tail;
|
||||
return 0;
|
||||
}
|
||||
+106
-266
@@ -1,46 +1,44 @@
|
||||
/* listfile.c -- display a long listing of a file
|
||||
Copyright (C) 1991, 1993, 2000, 2004, 2005, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1991, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h> /* for readlink() */
|
||||
#include <openat.h>
|
||||
|
||||
#include "human.h"
|
||||
#include "xalloc.h"
|
||||
#include "pathmax.h"
|
||||
#include "error.h"
|
||||
#include "filemode.h"
|
||||
#include "dircallback.h"
|
||||
#include "idcache.h"
|
||||
|
||||
#include "listfile.h"
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *getenv ();
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Since major is a function on SVR4, we can't use `ifndef major'. */
|
||||
#ifdef MAJOR_IN_MKDEV
|
||||
@@ -52,31 +50,6 @@
|
||||
#define HAVE_MAJOR
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#define textdomain(Domain)
|
||||
#define bindtextdomain(Package, Directory)
|
||||
#endif
|
||||
#ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
#else
|
||||
/* See locate.c for explanation as to why not use (String) */
|
||||
# define N_(String) String
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#undef S_ISCHR
|
||||
#undef S_ISBLK
|
||||
@@ -89,69 +62,40 @@
|
||||
#ifndef S_ISBLK
|
||||
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
#if defined S_IFLNK && !defined S_ISLNK
|
||||
#if defined(S_IFLNK) && !defined(S_ISLNK)
|
||||
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
|
||||
/* Get or fake the disk device blocksize.
|
||||
Usually defined by sys/param.h (if at all). */
|
||||
#ifndef DEV_BSIZE
|
||||
# ifdef BSIZE
|
||||
# define DEV_BSIZE BSIZE
|
||||
# else /* !BSIZE */
|
||||
# define DEV_BSIZE 4096
|
||||
# endif /* !BSIZE */
|
||||
#endif /* !DEV_BSIZE */
|
||||
|
||||
/* Extract or fake data from a `struct stat'.
|
||||
ST_BLKSIZE: Preferred I/O blocksize for the file, in bytes.
|
||||
ST_NBLOCKS: Number of blocks in the file, including indirect blocks.
|
||||
ST_NBLOCKSIZE: Size of blocks used when calculating ST_NBLOCKS. */
|
||||
#ifndef HAVE_STRUCT_STAT_ST_BLOCKS
|
||||
# define ST_BLKSIZE(statbuf) DEV_BSIZE
|
||||
# if defined _POSIX_SOURCE || !defined BSIZE /* fileblocks.c uses BSIZE. */
|
||||
# define ST_NBLOCKS(statbuf) \
|
||||
(S_ISREG ((statbuf).st_mode) \
|
||||
|| S_ISDIR ((statbuf).st_mode) \
|
||||
? (statbuf).st_size / ST_NBLOCKSIZE + ((statbuf).st_size % ST_NBLOCKSIZE != 0) : 0)
|
||||
# else /* !_POSIX_SOURCE && BSIZE */
|
||||
# define ST_NBLOCKS(statbuf) \
|
||||
(S_ISREG ((statbuf).st_mode) \
|
||||
|| S_ISDIR ((statbuf).st_mode) \
|
||||
? st_blocks ((statbuf).st_size) : 0)
|
||||
# endif /* !_POSIX_SOURCE && BSIZE */
|
||||
#else /* HAVE_STRUCT_STAT_ST_BLOCKS */
|
||||
/* Some systems, like Sequents, return st_blksize of 0 on pipes. */
|
||||
# define ST_BLKSIZE(statbuf) ((statbuf).st_blksize > 0 \
|
||||
? (statbuf).st_blksize : DEV_BSIZE)
|
||||
# if defined hpux || defined __hpux__ || defined __hpux
|
||||
/* HP-UX counts st_blocks in 1024-byte units.
|
||||
This loses when mixing HP-UX and BSD filesystems with NFS. */
|
||||
# define ST_NBLOCKSIZE 1024
|
||||
# else /* !hpux */
|
||||
# if defined _AIX && defined _I386
|
||||
/* AIX PS/2 counts st_blocks in 4K units. */
|
||||
# define ST_NBLOCKSIZE (4 * 1024)
|
||||
# else /* not AIX PS/2 */
|
||||
# if defined _CRAY
|
||||
# define ST_NBLOCKS(statbuf) \
|
||||
(S_ISREG ((statbuf).st_mode) \
|
||||
|| S_ISDIR ((statbuf).st_mode) \
|
||||
? (statbuf).st_blocks * ST_BLKSIZE(statbuf)/ST_NBLOCKSIZE : 0)
|
||||
# endif /* _CRAY */
|
||||
# endif /* not AIX PS/2 */
|
||||
# endif /* !hpux */
|
||||
#endif /* HAVE_STRUCT_STAT_ST_BLOCKS */
|
||||
|
||||
#ifndef ST_NBLOCKS
|
||||
# define ST_NBLOCKS(statbuf) \
|
||||
(S_ISREG ((statbuf).st_mode) \
|
||||
|| S_ISDIR ((statbuf).st_mode) \
|
||||
? (statbuf).st_blocks : 0)
|
||||
#if defined(S_ISLNK)
|
||||
int readlink ();
|
||||
#endif
|
||||
|
||||
#ifndef ST_NBLOCKSIZE
|
||||
# define ST_NBLOCKSIZE 512
|
||||
/* Extract or fake data from a `struct stat'.
|
||||
ST_NBLOCKS: Number of 512-byte blocks in the file
|
||||
(including indirect blocks).
|
||||
HP-UX, perhaps uniquely, counts st_blocks in 1024-byte units.
|
||||
This workaround loses when mixing HP-UX and 4BSD filesystems, though. */
|
||||
#ifdef _POSIX_SOURCE
|
||||
# define ST_NBLOCKS(statp) (((statp)->st_size + 512 - 1) / 512)
|
||||
#else
|
||||
# ifndef HAVE_ST_BLOCKS
|
||||
# define ST_NBLOCKS(statp) (st_blocks ((statp)->st_size))
|
||||
# else
|
||||
# if defined(hpux) || defined(__hpux__)
|
||||
# define ST_NBLOCKS(statp) ((statp)->st_blocks * 2)
|
||||
# else
|
||||
# define ST_NBLOCKS(statp) ((statp)->st_blocks)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Convert B 512-byte blocks to kilobytes if K is nonzero,
|
||||
otherwise return it unchanged. */
|
||||
#define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b))
|
||||
|
||||
#ifndef _POSIX_VERSION
|
||||
struct passwd *getpwuid ();
|
||||
struct group *getgrgid ();
|
||||
#endif
|
||||
|
||||
#ifdef major /* Might be defined in sys/types.h. */
|
||||
@@ -163,148 +107,86 @@
|
||||
#endif
|
||||
#undef HAVE_MAJOR
|
||||
|
||||
char *xmalloc ();
|
||||
void error ();
|
||||
void mode_string ();
|
||||
|
||||
static void print_name (register const char *p, FILE *stream, int literal_control_chars);
|
||||
|
||||
|
||||
size_t
|
||||
file_blocksize(const struct stat *p)
|
||||
{
|
||||
return ST_NBLOCKSIZE;
|
||||
}
|
||||
|
||||
|
||||
char *get_link_name ();
|
||||
char *getgroup ();
|
||||
char *getuser ();
|
||||
void print_name_with_quoting ();
|
||||
|
||||
/* NAME is the name to print.
|
||||
RELNAME is the path to access it from the current directory.
|
||||
STATP is the results of stat or lstat on it.
|
||||
Use CURRENT_TIME to decide whether to print yyyy or hh:mm.
|
||||
Use OUTPUT_BLOCK_SIZE to determine how to print file block counts
|
||||
and sizes.
|
||||
STREAM is the stdio stream to print on. */
|
||||
|
||||
void
|
||||
list_file (const char *name,
|
||||
int dirfd,
|
||||
char *relname,
|
||||
const struct stat *statp,
|
||||
time_t current_time,
|
||||
int output_block_size,
|
||||
int literal_control_chars,
|
||||
FILE *stream)
|
||||
list_file (name, relname, statp, stream)
|
||||
char *name;
|
||||
char *relname;
|
||||
struct stat *statp;
|
||||
FILE *stream;
|
||||
{
|
||||
char modebuf[12];
|
||||
struct tm const *when_local;
|
||||
char const *user_name;
|
||||
char const *group_name;
|
||||
char hbuf[LONGEST_HUMAN_READABLE + 1];
|
||||
static int kilobytes = -1; /* -1 = uninitialized, 0 = 512, 1 = 1024. */
|
||||
char modebuf[20];
|
||||
char timebuf[40];
|
||||
time_t current_time = time ((time_t *) 0);
|
||||
|
||||
#if HAVE_ST_DM_MODE
|
||||
/* Cray DMF: look at the file's migrated, not real, status */
|
||||
strmode (statp->st_dm_mode, modebuf);
|
||||
#else
|
||||
strmode (statp->st_mode, modebuf);
|
||||
#endif
|
||||
if (kilobytes == -1)
|
||||
kilobytes = getenv ("POSIXLY_CORRECT") == 0;
|
||||
|
||||
fprintf (stream, "%6s ",
|
||||
human_readable ((uintmax_t) statp->st_ino, hbuf,
|
||||
human_ceiling,
|
||||
1, 1));
|
||||
mode_string (statp->st_mode, modebuf);
|
||||
modebuf[10] = '\0';
|
||||
|
||||
fprintf (stream, "%4s ",
|
||||
human_readable ((uintmax_t) ST_NBLOCKS (*statp), hbuf,
|
||||
human_ceiling,
|
||||
ST_NBLOCKSIZE, output_block_size));
|
||||
strcpy (timebuf, ctime (&statp->st_mtime));
|
||||
if (current_time > statp->st_mtime + 6L * 30L * 24L * 60L * 60L /* Old. */
|
||||
|| current_time < statp->st_mtime - 60L * 60L) /* In the future. */
|
||||
{
|
||||
/* The file is fairly old or in the future.
|
||||
POSIX says the cutoff is 6 months old;
|
||||
approximate this by 6*30 days.
|
||||
Allow a 1 hour slop factor for what is considered "the future",
|
||||
to allow for NFS server/client clock disagreement.
|
||||
Show the year instead of the time of day. */
|
||||
strcpy (timebuf + 11, timebuf + 19);
|
||||
}
|
||||
timebuf[16] = 0;
|
||||
|
||||
fprintf (stream, "%6lu ", statp->st_ino);
|
||||
|
||||
/* modebuf includes the space between the mode and the number of links,
|
||||
as the POSIX "optional alternate access method flag". */
|
||||
fprintf (stream, "%s%3lu ", modebuf, (unsigned long) statp->st_nlink);
|
||||
fprintf (stream, "%4u ", convert_blocks (ST_NBLOCKS (statp), kilobytes));
|
||||
|
||||
user_name = getuser (statp->st_uid);
|
||||
if (user_name)
|
||||
fprintf (stream, "%-8s ", user_name);
|
||||
else
|
||||
fprintf (stream, "%-8lu ", (unsigned long) statp->st_uid);
|
||||
/* The space between the mode and the number of links is the POSIX
|
||||
"optional alternate access method flag". */
|
||||
fprintf (stream, "%s %3u ", modebuf, statp->st_nlink);
|
||||
|
||||
group_name = getgroup (statp->st_gid);
|
||||
if (group_name)
|
||||
fprintf (stream, "%-8s ", group_name);
|
||||
else
|
||||
fprintf (stream, "%-8lu ", (unsigned long) statp->st_gid);
|
||||
fprintf (stream, "%-8.8s ", getuser (statp->st_uid));
|
||||
|
||||
fprintf (stream, "%-8.8s ", getgroup (statp->st_gid));
|
||||
|
||||
if (S_ISCHR (statp->st_mode) || S_ISBLK (statp->st_mode))
|
||||
#ifdef HAVE_ST_RDEV
|
||||
fprintf (stream, "%3lu, %3lu ",
|
||||
(unsigned long) major (statp->st_rdev),
|
||||
(unsigned long) minor (statp->st_rdev));
|
||||
fprintf (stream, "%3u, %3u ", major (statp->st_rdev), minor (statp->st_rdev));
|
||||
#else
|
||||
fprintf (stream, " ");
|
||||
#endif
|
||||
else
|
||||
fprintf (stream, "%8s ",
|
||||
human_readable ((uintmax_t) statp->st_size, hbuf,
|
||||
human_ceiling,
|
||||
1,
|
||||
output_block_size < 0 ? output_block_size : 1));
|
||||
fprintf (stream, "%8lu ", statp->st_size);
|
||||
|
||||
if ((when_local = localtime (&statp->st_mtime)))
|
||||
{
|
||||
char init_bigbuf[256];
|
||||
char *buf = init_bigbuf;
|
||||
size_t bufsize = sizeof init_bigbuf;
|
||||
fprintf (stream, "%s ", timebuf + 4);
|
||||
|
||||
/* Use strftime rather than ctime, because the former can produce
|
||||
locale-dependent names for the month (%b).
|
||||
|
||||
Output the year if the file is fairly old or in the future.
|
||||
POSIX says the cutoff is 6 months old;
|
||||
approximate this by 6*30 days.
|
||||
Allow a 1 hour slop factor for what is considered "the future",
|
||||
to allow for NFS server/client clock disagreement. */
|
||||
char const *fmt =
|
||||
((current_time - 6 * 30 * 24 * 60 * 60 <= statp->st_mtime
|
||||
&& statp->st_mtime <= current_time + 60 * 60)
|
||||
? "%b %e %H:%M"
|
||||
: "%b %e %Y");
|
||||
|
||||
while (!strftime (buf, bufsize, fmt, when_local))
|
||||
buf = alloca (bufsize *= 2);
|
||||
|
||||
fprintf (stream, "%s ", buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The time cannot be represented as a local time;
|
||||
print it as a huge integer number of seconds. */
|
||||
int width = 12;
|
||||
|
||||
if (statp->st_mtime < 0)
|
||||
{
|
||||
char const *num = human_readable (- (uintmax_t) statp->st_mtime,
|
||||
hbuf, human_ceiling, 1, 1);
|
||||
int sign_width = width - strlen (num);
|
||||
fprintf (stream, "%*s%s ",
|
||||
sign_width < 0 ? 0 : sign_width, "-", num);
|
||||
}
|
||||
else
|
||||
fprintf (stream, "%*s ", width,
|
||||
human_readable ((uintmax_t) statp->st_mtime, hbuf,
|
||||
human_ceiling,
|
||||
1, 1));
|
||||
}
|
||||
|
||||
print_name (name, stream, literal_control_chars);
|
||||
print_name_with_quoting (name, stream);
|
||||
|
||||
#ifdef S_ISLNK
|
||||
if (S_ISLNK (statp->st_mode))
|
||||
{
|
||||
char *linkname = get_link_name_at (name, dirfd, relname);
|
||||
char *linkname = get_link_name (name, relname);
|
||||
|
||||
if (linkname)
|
||||
{
|
||||
fputs (" -> ", stream);
|
||||
print_name (linkname, stream, literal_control_chars);
|
||||
print_name_with_quoting (linkname, stream);
|
||||
free (linkname);
|
||||
}
|
||||
}
|
||||
@@ -312,16 +194,10 @@ list_file (const char *name,
|
||||
putc ('\n', stream);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_name_without_quoting (const char *p, FILE *stream)
|
||||
{
|
||||
fprintf(stream, "%s", p);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
print_name_with_quoting (register const char *p, FILE *stream)
|
||||
void
|
||||
print_name_with_quoting (p, stream)
|
||||
register char *p;
|
||||
FILE *stream;
|
||||
{
|
||||
register unsigned char c;
|
||||
|
||||
@@ -370,17 +246,11 @@ print_name_with_quoting (register const char *p, FILE *stream)
|
||||
}
|
||||
}
|
||||
|
||||
static void print_name (register const char *p, FILE *stream, int literal_control_chars)
|
||||
{
|
||||
if (literal_control_chars)
|
||||
print_name_without_quoting(p, stream);
|
||||
else
|
||||
print_name_with_quoting(p, stream);
|
||||
}
|
||||
|
||||
#ifdef S_ISLNK
|
||||
static char *
|
||||
get_link_name (const char *name, char *relname)
|
||||
char *
|
||||
get_link_name (name, relname)
|
||||
char *name;
|
||||
char *relname;
|
||||
{
|
||||
register char *linkname;
|
||||
register int linklen;
|
||||
@@ -389,7 +259,7 @@ get_link_name (const char *name, char *relname)
|
||||
mount points with some automounters.
|
||||
So allocate a pessimistic PATH_MAX + 1 bytes. */
|
||||
#define LINK_BUF PATH_MAX
|
||||
linkname = xmalloc (LINK_BUF + 1);
|
||||
linkname = (char *) xmalloc (LINK_BUF + 1);
|
||||
linklen = readlink (relname, linkname, LINK_BUF);
|
||||
if (linklen < 0)
|
||||
{
|
||||
@@ -400,34 +270,4 @@ get_link_name (const char *name, char *relname)
|
||||
linkname[linklen] = '\0';
|
||||
return linkname;
|
||||
}
|
||||
|
||||
struct link_name_args
|
||||
{
|
||||
const char *name;
|
||||
char *relname;
|
||||
char *result;
|
||||
};
|
||||
|
||||
static int
|
||||
get_link_name_cb(void *context)
|
||||
{
|
||||
struct link_name_args *args = context;
|
||||
args->result = get_link_name(args->name, args->relname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
get_link_name_at (const char *name, int dirfd, char *relname)
|
||||
{
|
||||
struct link_name_args args;
|
||||
args.result = NULL;
|
||||
args.name = name;
|
||||
args.relname = relname;
|
||||
if (0 == run_in_dir(dirfd, get_link_name_cb, &args))
|
||||
return args.result;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/* memcmp.c -- compare memory.
|
||||
Return:
|
||||
<0 if S1 < S2,
|
||||
0 if strings are identical,
|
||||
>0 if S1 > S2.
|
||||
Stops looking after N characters. Doesn't stop at nulls.
|
||||
In the public domain.
|
||||
By David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
int
|
||||
#if __STDC__
|
||||
memcmp (void const *v1, void const *v2, size_t n)
|
||||
{
|
||||
register char *s1 = (char *) v1, *s2 = (char *) v2;
|
||||
#else
|
||||
memcmp (s1, s2, n)
|
||||
register char *s1, *s2;
|
||||
register unsigned n;
|
||||
{
|
||||
#endif
|
||||
register int diff;
|
||||
|
||||
while (n--)
|
||||
{
|
||||
diff = *s1++ - *s2++;
|
||||
if (diff)
|
||||
return diff;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* memset.c -- set an area of memory to a given value
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
char *
|
||||
memset (str, c, len)
|
||||
char *str;
|
||||
int c;
|
||||
unsigned len;
|
||||
{
|
||||
register char *st = str;
|
||||
|
||||
while (len-- > 0)
|
||||
*st++ = c;
|
||||
return str;
|
||||
}
|
||||
+502
@@ -0,0 +1,502 @@
|
||||
/* Copyright (C) 1993, 1994 Free Software Foundation, Inc.
|
||||
Contributed by Noel Cragg (noel@cs.oberlin.edu), with fixes by
|
||||
Michael E. Calwas (calwas@ttd.teradyne.com) and
|
||||
Wade Hampton (tasi029@tmn.com).
|
||||
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If
|
||||
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Define this to have a standalone program to test this implementation of
|
||||
mktime. */
|
||||
/* #define DEBUG */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h> /* Some systems define `time_t' here. */
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#ifndef __isleap
|
||||
/* Nonzero if YEAR is a leap year (every 4 years,
|
||||
except every 100th isn't, and every 400th is). */
|
||||
#define __isleap(year) \
|
||||
((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
|
||||
#endif
|
||||
|
||||
#ifndef __P
|
||||
#if defined (__GNUC__) || (defined (__STDC__) && __STDC__)
|
||||
#define __P(args) args
|
||||
#else
|
||||
#define __P(args) ()
|
||||
#endif /* GCC. */
|
||||
#endif /* Not __P. */
|
||||
|
||||
/* How many days are in each month. */
|
||||
const unsigned short int __mon_lengths[2][12] =
|
||||
{
|
||||
/* Normal years. */
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
|
||||
/* Leap years. */
|
||||
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
|
||||
};
|
||||
|
||||
|
||||
static int times_through_search; /* This library routine should never
|
||||
hang -- make sure we always return
|
||||
when we're searching for a value */
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
int debugging_enabled = 0;
|
||||
|
||||
/* Print the values in a `struct tm'. */
|
||||
static void
|
||||
printtm (it)
|
||||
struct tm *it;
|
||||
{
|
||||
printf ("%02d/%02d/%04d %02d:%02d:%02d (%s) yday:%03d dst:%d gmtoffset:%ld",
|
||||
it->tm_mon + 1,
|
||||
it->tm_mday,
|
||||
it->tm_year + 1900,
|
||||
it->tm_hour,
|
||||
it->tm_min,
|
||||
it->tm_sec,
|
||||
it->tm_zone,
|
||||
it->tm_yday,
|
||||
it->tm_isdst,
|
||||
it->tm_gmtoff);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static time_t
|
||||
dist_tm (t1, t2)
|
||||
struct tm *t1;
|
||||
struct tm *t2;
|
||||
{
|
||||
time_t distance = 0;
|
||||
unsigned long int v1, v2;
|
||||
int diff_flag = 0;
|
||||
|
||||
v1 = v2 = 0;
|
||||
|
||||
#define doit(x, secs) \
|
||||
v1 += t1->x * secs; \
|
||||
v2 += t2->x * secs; \
|
||||
if (!diff_flag) \
|
||||
{ \
|
||||
if (t1->x < t2->x) \
|
||||
diff_flag = -1; \
|
||||
else if (t1->x > t2->x) \
|
||||
diff_flag = 1; \
|
||||
}
|
||||
|
||||
doit (tm_year, 31536000); /* Okay, not all years have 365 days. */
|
||||
doit (tm_mon, 2592000); /* Okay, not all months have 30 days. */
|
||||
doit (tm_mday, 86400);
|
||||
doit (tm_hour, 3600);
|
||||
doit (tm_min, 60);
|
||||
doit (tm_sec, 1);
|
||||
|
||||
#undef doit
|
||||
|
||||
/* We should also make sure that the sign of DISTANCE is correct -- if
|
||||
DIFF_FLAG is positive, the distance should be positive and vice versa. */
|
||||
|
||||
distance = (v1 > v2) ? (v1 - v2) : (v2 - v1);
|
||||
if (diff_flag < 0)
|
||||
distance = -distance;
|
||||
|
||||
if (times_through_search > 20) /* Arbitrary # of calls, but makes sure we
|
||||
never hang if there's a problem with
|
||||
this algorithm. */
|
||||
{
|
||||
distance = diff_flag;
|
||||
}
|
||||
|
||||
/* We need this DIFF_FLAG business because it is forseeable that the
|
||||
distance may be zero when, in actuality, the two structures are
|
||||
different. This is usually the case when the dates are 366 days apart
|
||||
and one of the years is a leap year. */
|
||||
|
||||
if (distance == 0 && diff_flag)
|
||||
distance = 86400 * diff_flag;
|
||||
|
||||
return distance;
|
||||
}
|
||||
|
||||
|
||||
/* MKTIME converts the values in a struct tm to a time_t. The values
|
||||
in tm_wday and tm_yday are ignored; other values can be put outside
|
||||
of legal ranges since they will be normalized. This routine takes
|
||||
care of that normalization. */
|
||||
|
||||
void
|
||||
do_normalization (tmptr)
|
||||
struct tm *tmptr;
|
||||
{
|
||||
|
||||
#define normalize(foo,x,y,bar); \
|
||||
while (tmptr->foo < x) \
|
||||
{ \
|
||||
tmptr->bar--; \
|
||||
tmptr->foo = (y - (x - tmptr->foo) + 1); \
|
||||
} \
|
||||
while (tmptr->foo > y) \
|
||||
{ \
|
||||
tmptr->foo = (x + (tmptr->foo - y) - 1); \
|
||||
tmptr->bar++; \
|
||||
}
|
||||
|
||||
normalize (tm_sec, 0, 59, tm_min);
|
||||
normalize (tm_min, 0, 59, tm_hour);
|
||||
normalize (tm_hour, 0, 23, tm_mday);
|
||||
|
||||
/* Do the month first, so day range can be found. */
|
||||
normalize (tm_mon, 0, 11, tm_year);
|
||||
|
||||
/* Since the day range modifies the month, we should be careful how
|
||||
we reference the array of month lengths -- it is possible that
|
||||
the month will go negative, hence the modulo...
|
||||
|
||||
Also, tm_year is the year - 1900, so we have to 1900 to have it
|
||||
work correctly. */
|
||||
|
||||
normalize (tm_mday, 1,
|
||||
__mon_lengths[__isleap (tmptr->tm_year + 1900)]
|
||||
[((tmptr->tm_mon < 0)
|
||||
? (12 + (tmptr->tm_mon % 12))
|
||||
: (tmptr->tm_mon % 12)) ],
|
||||
tm_mon);
|
||||
|
||||
/* Do the month again, because the day may have pushed it out of range. */
|
||||
normalize (tm_mon, 0, 11, tm_year);
|
||||
|
||||
/* Do the day again, because the month may have changed the range. */
|
||||
normalize (tm_mday, 1,
|
||||
__mon_lengths[__isleap (tmptr->tm_year + 1900)]
|
||||
[((tmptr->tm_mon < 0)
|
||||
? (12 + (tmptr->tm_mon % 12))
|
||||
: (tmptr->tm_mon % 12)) ],
|
||||
tm_mon);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debugging_enabled)
|
||||
{
|
||||
printf (" After normalizing:\n ");
|
||||
printtm (tmptr);
|
||||
putchar ('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Here's where the work gets done. */
|
||||
|
||||
#define BAD_STRUCT_TM ((time_t) -1)
|
||||
|
||||
time_t
|
||||
_mktime_internal (timeptr, producer)
|
||||
struct tm *timeptr;
|
||||
struct tm *(*producer) __P ((const time_t *));
|
||||
{
|
||||
struct tm our_tm; /* our working space */
|
||||
struct tm *me = &our_tm; /* a pointer to the above */
|
||||
time_t result; /* the value we return */
|
||||
|
||||
*me = *timeptr; /* copy the struct tm that was passed
|
||||
in by the caller */
|
||||
|
||||
|
||||
/***************************/
|
||||
/* Normalize the structure */
|
||||
/***************************/
|
||||
|
||||
/* This routine assumes that the value of TM_ISDST is -1, 0, or 1.
|
||||
If the user didn't pass it in that way, fix it. */
|
||||
|
||||
if (me->tm_isdst > 0)
|
||||
me->tm_isdst = 1;
|
||||
else if (me->tm_isdst < 0)
|
||||
me->tm_isdst = -1;
|
||||
|
||||
do_normalization (me);
|
||||
|
||||
/* Get out of here if it's not possible to represent this struct.
|
||||
If any of the values in the normalized struct tm are negative,
|
||||
our algorithms won't work. Luckily, we only need to check the
|
||||
year at this point; normalization guarantees that all values will
|
||||
be in correct ranges EXCEPT the year. */
|
||||
|
||||
if (me->tm_year < 0)
|
||||
return BAD_STRUCT_TM;
|
||||
|
||||
/*************************************************/
|
||||
/* Find the appropriate time_t for the structure */
|
||||
/*************************************************/
|
||||
|
||||
/* Modified b-search -- make intelligent guesses as to where the
|
||||
time might lie along the timeline, assuming that our target time
|
||||
lies a linear distance (w/o considering time jumps of a
|
||||
particular region).
|
||||
|
||||
Assume that time does not fluctuate at all along the timeline --
|
||||
e.g., assume that a day will always take 86400 seconds, etc. --
|
||||
and come up with a hypothetical value for the time_t
|
||||
representation of the struct tm TARGET, in relation to the guess
|
||||
variable -- it should be pretty close!
|
||||
|
||||
After testing this, the maximum number of iterations that I had
|
||||
on any number that I tried was 3! Not bad.
|
||||
|
||||
The reason this is not a subroutine is that we will modify some
|
||||
fields in the struct tm (yday and mday). I've never felt good
|
||||
about side-effects when writing structured code... */
|
||||
|
||||
{
|
||||
struct tm *guess_tm;
|
||||
time_t guess = 0;
|
||||
time_t distance = 0;
|
||||
time_t last_distance = 0;
|
||||
|
||||
times_through_search = 0;
|
||||
|
||||
do
|
||||
{
|
||||
guess += distance;
|
||||
|
||||
times_through_search++;
|
||||
|
||||
guess_tm = (*producer) (&guess);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (debugging_enabled)
|
||||
{
|
||||
printf (" Guessing time_t == %d\n ", (int) guess);
|
||||
printtm (guess_tm);
|
||||
putchar ('\n');
|
||||
}
|
||||
#endif
|
||||
|
||||
/* How far is our guess from the desired struct tm? */
|
||||
distance = dist_tm (me, guess_tm);
|
||||
|
||||
/* Handle periods of time where a period of time is skipped.
|
||||
For example, 2:15 3 April 1994 does not exist, because DST
|
||||
is in effect. The distance function will alternately
|
||||
return values of 3600 and -3600, because it doesn't know
|
||||
that the requested time doesn't exist. In these situations
|
||||
(even if the skip is not exactly an hour) the distances
|
||||
returned will be the same, but alternating in sign. We
|
||||
want the later time, so check to see that the distance is
|
||||
oscillating and we've chosen the correct of the two
|
||||
possibilities.
|
||||
|
||||
Useful: 3 Apr 94 765356300, 30 Oct 94 783496000 */
|
||||
|
||||
if ((distance == -last_distance) && (distance < last_distance))
|
||||
{
|
||||
/* If the caller specified that the DST flag was off, it's
|
||||
not possible to represent this time. */
|
||||
if (me->tm_isdst == 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf (" Distance is oscillating -- dst flag nixes struct!\n");
|
||||
#endif
|
||||
return BAD_STRUCT_TM;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
printf (" Distance is oscillating -- chose the later time.\n");
|
||||
#endif
|
||||
distance = 0;
|
||||
}
|
||||
|
||||
if ((distance == 0) && (me->tm_isdst != -1)
|
||||
&& (me->tm_isdst != guess_tm->tm_isdst))
|
||||
{
|
||||
/* If we're in this code, we've got the right time but the
|
||||
wrong daylight savings flag. We need to move away from
|
||||
the time that we have and approach the other time from
|
||||
the other direction. That is, if I've requested the
|
||||
non-DST version of a time and I get the DST version
|
||||
instead, I want to put us forward in time and search
|
||||
backwards to get the other time. I checked all of the
|
||||
configuration files for the tz package -- no entry
|
||||
saves more than two hours, so I think we'll be safe by
|
||||
moving 24 hours in one direction. IF THE AMOUNT OF
|
||||
TIME SAVED IN THE CONFIGURATION FILES CHANGES, THIS
|
||||
VALUE MAY NEED TO BE ADJUSTED. Luckily, we can never
|
||||
have more than one level of overlaps, or this would
|
||||
never work. */
|
||||
|
||||
#define SKIP_VALUE 86400
|
||||
|
||||
if (guess_tm->tm_isdst == 0)
|
||||
/* we got the later one, but want the earlier one */
|
||||
distance = -SKIP_VALUE;
|
||||
else
|
||||
distance = SKIP_VALUE;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf (" Got the right time, wrong DST value -- adjusting\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
last_distance = distance;
|
||||
|
||||
} while (distance != 0);
|
||||
|
||||
/* Check to see that the dst flag matches */
|
||||
|
||||
if (me->tm_isdst != -1)
|
||||
{
|
||||
if (me->tm_isdst != guess_tm->tm_isdst)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf (" DST flag doesn't match! FIXME?\n");
|
||||
#endif
|
||||
return BAD_STRUCT_TM;
|
||||
}
|
||||
}
|
||||
|
||||
result = guess; /* Success! */
|
||||
|
||||
/* On successful completion, the values of tm_wday and tm_yday
|
||||
have to be set appropriately. */
|
||||
|
||||
/* me->tm_yday = guess_tm->tm_yday;
|
||||
me->tm_mday = guess_tm->tm_mday; */
|
||||
|
||||
*me = *guess_tm;
|
||||
}
|
||||
|
||||
/* Update the caller's version of the structure */
|
||||
|
||||
*timeptr = *me;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
time_t
|
||||
#ifdef DEBUG /* make it work even if the system's
|
||||
libc has it's own mktime routine */
|
||||
my_mktime (timeptr)
|
||||
#else
|
||||
mktime (timeptr)
|
||||
#endif
|
||||
struct tm *timeptr;
|
||||
{
|
||||
return _mktime_internal (timeptr, localtime);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
int time;
|
||||
int result_time;
|
||||
struct tm *tmptr;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
long q;
|
||||
|
||||
printf ("starting long test...\n");
|
||||
|
||||
for (q = 10000000; q < 1000000000; q += 599)
|
||||
{
|
||||
struct tm *tm = localtime ((time_t *) &q);
|
||||
if ((q % 10000) == 0) { printf ("%ld\n", q); fflush (stdout); }
|
||||
if (q != my_mktime (tm))
|
||||
{ printf ("failed for %ld\n", q); fflush (stdout); }
|
||||
}
|
||||
|
||||
printf ("test finished\n");
|
||||
|
||||
exit (0);
|
||||
}
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
printf ("wrong # of args\n");
|
||||
exit (0);
|
||||
}
|
||||
|
||||
debugging_enabled = 1; /* We want to see the info */
|
||||
|
||||
++argv;
|
||||
time = atoi (*argv);
|
||||
|
||||
tmptr = localtime ((time_t *) &time);
|
||||
printf ("Localtime tells us that a time_t of %d represents\n ", time);
|
||||
printtm (tmptr);
|
||||
putchar ('\n');
|
||||
|
||||
printf (" Given localtime's return val, mktime returns %d which is\n ",
|
||||
(int) my_mktime (tmptr));
|
||||
printtm (tmptr);
|
||||
putchar ('\n');
|
||||
|
||||
#if 0
|
||||
tmptr->tm_sec -= 20;
|
||||
tmptr->tm_min -= 20;
|
||||
tmptr->tm_hour -= 20;
|
||||
tmptr->tm_mday -= 20;
|
||||
tmptr->tm_mon -= 20;
|
||||
tmptr->tm_year -= 20;
|
||||
tmptr->tm_gmtoff -= 20000; /* This has no effect! */
|
||||
tmptr->tm_zone = NULL; /* Nor does this! */
|
||||
tmptr->tm_isdst = -1;
|
||||
#endif
|
||||
|
||||
tmptr->tm_hour += 1;
|
||||
tmptr->tm_isdst = -1;
|
||||
|
||||
printf ("\n\nchanged ranges: ");
|
||||
printtm (tmptr);
|
||||
putchar ('\n');
|
||||
|
||||
result_time = my_mktime (tmptr);
|
||||
printf ("\nmktime: %d\n", result_time);
|
||||
|
||||
tmptr->tm_isdst = 0;
|
||||
|
||||
printf ("\n\nchanged ranges: ");
|
||||
printtm (tmptr);
|
||||
putchar ('\n');
|
||||
|
||||
result_time = my_mktime (tmptr);
|
||||
printf ("\nmktime: %d\n", result_time);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
compile-command: "gcc -g mktime.c -o mktime -DDEBUG"
|
||||
End:
|
||||
*/
|
||||
@@ -0,0 +1,341 @@
|
||||
/* modechange.c -- file mode manipulation
|
||||
Copyright (C) 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@ai.mit.edu> */
|
||||
|
||||
/* The ASCII mode string is compiled into a linked list of `struct
|
||||
modechange', which can then be applied to each file to be changed.
|
||||
We do this instead of re-parsing the ASCII string for each file
|
||||
because the compiled form requires less computation to use; when
|
||||
changing the mode of many files, this probably results in a
|
||||
performance gain. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "modechange.h"
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
#undef S_ISDIR
|
||||
#endif /* STAT_MACROS_BROKEN. */
|
||||
|
||||
#if !defined(S_ISDIR) && defined(S_IFDIR)
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* Return newly allocated memory to hold one element of type TYPE. */
|
||||
#define talloc(type) ((type *) malloc (sizeof (type)))
|
||||
|
||||
#define isodigit(c) ((c) >= '0' && (c) <= '7')
|
||||
|
||||
static int oatoi ();
|
||||
|
||||
/* Return a linked list of file mode change operations created from
|
||||
MODE_STRING, an ASCII string that contains either an octal number
|
||||
specifying an absolute mode, or symbolic mode change operations with
|
||||
the form:
|
||||
[ugoa...][[+-=][rwxXstugo...]...][,...]
|
||||
MASKED_OPS is a bitmask indicating which symbolic mode operators (=+-)
|
||||
should not affect bits set in the umask when no users are given.
|
||||
Operators not selected in MASKED_OPS ignore the umask.
|
||||
|
||||
Return MODE_INVALID if `mode_string' does not contain a valid
|
||||
representation of file mode change operations;
|
||||
return MODE_MEMORY_EXHAUSTED if there is insufficient memory. */
|
||||
|
||||
struct mode_change *
|
||||
mode_compile (mode_string, masked_ops)
|
||||
register char *mode_string;
|
||||
unsigned masked_ops;
|
||||
{
|
||||
struct mode_change *head; /* First element of the linked list. */
|
||||
struct mode_change *change; /* An element of the linked list. */
|
||||
int i; /* General purpose temporary. */
|
||||
unsigned short umask_value; /* The umask value (surprise). */
|
||||
unsigned short affected_bits; /* Which bits in the mode are operated on. */
|
||||
unsigned short affected_masked; /* `affected_bits' modified by umask. */
|
||||
unsigned ops_to_mask; /* Operators to actually use umask on. */
|
||||
|
||||
i = oatoi (mode_string);
|
||||
if (i >= 0)
|
||||
{
|
||||
if (i > 07777)
|
||||
return MODE_INVALID;
|
||||
head = talloc (struct mode_change);
|
||||
if (head == NULL)
|
||||
return MODE_MEMORY_EXHAUSTED;
|
||||
head->next = NULL;
|
||||
head->op = '=';
|
||||
head->flags = 0;
|
||||
head->value = i;
|
||||
head->affected = 07777; /* Affect all permissions. */
|
||||
return head;
|
||||
}
|
||||
|
||||
umask_value = umask (0);
|
||||
umask (umask_value); /* Restore the old value. */
|
||||
|
||||
head = NULL;
|
||||
#ifdef lint
|
||||
change = NULL;
|
||||
#endif
|
||||
--mode_string;
|
||||
|
||||
/* One loop iteration for each "ugoa...=+-rwxXstugo...[=+-rwxXstugo...]". */
|
||||
do
|
||||
{
|
||||
affected_bits = 0;
|
||||
ops_to_mask = 0;
|
||||
/* Turn on all the bits in `affected_bits' for each group given. */
|
||||
for (++mode_string;; ++mode_string)
|
||||
switch (*mode_string)
|
||||
{
|
||||
case 'u':
|
||||
affected_bits |= 04700;
|
||||
break;
|
||||
case 'g':
|
||||
affected_bits |= 02070;
|
||||
break;
|
||||
case 'o':
|
||||
affected_bits |= 01007;
|
||||
break;
|
||||
case 'a':
|
||||
affected_bits |= 07777;
|
||||
break;
|
||||
default:
|
||||
goto no_more_affected;
|
||||
}
|
||||
|
||||
no_more_affected:
|
||||
/* If none specified, affect all bits, except perhaps those
|
||||
set in the umask. */
|
||||
if (affected_bits == 0)
|
||||
{
|
||||
affected_bits = 07777;
|
||||
ops_to_mask = masked_ops;
|
||||
}
|
||||
|
||||
while (*mode_string == '=' || *mode_string == '+' || *mode_string == '-')
|
||||
{
|
||||
/* Add the element to the tail of the list, so the operations
|
||||
are performed in the correct order. */
|
||||
if (head == NULL)
|
||||
{
|
||||
head = talloc (struct mode_change);
|
||||
if (head == NULL)
|
||||
return MODE_MEMORY_EXHAUSTED;
|
||||
change = head;
|
||||
}
|
||||
else
|
||||
{
|
||||
change->next = talloc (struct mode_change);
|
||||
if (change->next == NULL)
|
||||
{
|
||||
mode_free (change);
|
||||
return MODE_MEMORY_EXHAUSTED;
|
||||
}
|
||||
change = change->next;
|
||||
}
|
||||
|
||||
change->next = NULL;
|
||||
change->op = *mode_string; /* One of "=+-". */
|
||||
affected_masked = affected_bits;
|
||||
if (ops_to_mask & (*mode_string == '=' ? MODE_MASK_EQUALS
|
||||
: *mode_string == '+' ? MODE_MASK_PLUS
|
||||
: MODE_MASK_MINUS))
|
||||
affected_masked &= ~umask_value;
|
||||
change->affected = affected_masked;
|
||||
change->value = 0;
|
||||
change->flags = 0;
|
||||
|
||||
/* Set `value' according to the bits set in `affected_masked'. */
|
||||
for (++mode_string;; ++mode_string)
|
||||
switch (*mode_string)
|
||||
{
|
||||
case 'r':
|
||||
change->value |= 00444 & affected_masked;
|
||||
break;
|
||||
case 'w':
|
||||
change->value |= 00222 & affected_masked;
|
||||
break;
|
||||
case 'X':
|
||||
change->flags |= MODE_X_IF_ANY_X;
|
||||
/* Fall through. */
|
||||
case 'x':
|
||||
change->value |= 00111 & affected_masked;
|
||||
break;
|
||||
case 's':
|
||||
/* Set the setuid/gid bits if `u' or `g' is selected. */
|
||||
change->value |= 06000 & affected_masked;
|
||||
break;
|
||||
case 't':
|
||||
/* Set the "save text image" bit if `o' is selected. */
|
||||
change->value |= 01000 & affected_masked;
|
||||
break;
|
||||
case 'u':
|
||||
/* Set the affected bits to the value of the `u' bits
|
||||
on the same file. */
|
||||
if (change->value)
|
||||
goto invalid;
|
||||
change->value = 00700;
|
||||
change->flags |= MODE_COPY_EXISTING;
|
||||
break;
|
||||
case 'g':
|
||||
/* Set the affected bits to the value of the `g' bits
|
||||
on the same file. */
|
||||
if (change->value)
|
||||
goto invalid;
|
||||
change->value = 00070;
|
||||
change->flags |= MODE_COPY_EXISTING;
|
||||
break;
|
||||
case 'o':
|
||||
/* Set the affected bits to the value of the `o' bits
|
||||
on the same file. */
|
||||
if (change->value)
|
||||
goto invalid;
|
||||
change->value = 00007;
|
||||
change->flags |= MODE_COPY_EXISTING;
|
||||
break;
|
||||
default:
|
||||
goto no_more_values;
|
||||
}
|
||||
no_more_values:;
|
||||
}
|
||||
} while (*mode_string == ',');
|
||||
if (*mode_string == 0)
|
||||
return head;
|
||||
invalid:
|
||||
mode_free (head);
|
||||
return MODE_INVALID;
|
||||
}
|
||||
|
||||
/* Return file mode OLDMODE, adjusted as indicated by the list of change
|
||||
operations CHANGES. If OLDMODE is a directory, the type `X'
|
||||
change affects it even if no execute bits were set in OLDMODE.
|
||||
The returned value has the S_IFMT bits cleared. */
|
||||
|
||||
unsigned short
|
||||
mode_adjust (oldmode, changes)
|
||||
unsigned oldmode;
|
||||
register struct mode_change *changes;
|
||||
{
|
||||
unsigned short newmode; /* The adjusted mode and one operand. */
|
||||
unsigned short value; /* The other operand. */
|
||||
|
||||
newmode = oldmode & 07777;
|
||||
|
||||
for (; changes; changes = changes->next)
|
||||
{
|
||||
if (changes->flags & MODE_COPY_EXISTING)
|
||||
{
|
||||
/* Isolate in `value' the bits in `newmode' to copy, given in
|
||||
the mask `changes->value'. */
|
||||
value = newmode & changes->value;
|
||||
|
||||
if (changes->value & 00700)
|
||||
/* Copy `u' permissions onto `g' and `o'. */
|
||||
value |= (value >> 3) | (value >> 6);
|
||||
else if (changes->value & 00070)
|
||||
/* Copy `g' permissions onto `u' and `o'. */
|
||||
value |= (value << 3) | (value >> 3);
|
||||
else
|
||||
/* Copy `o' permissions onto `u' and `g'. */
|
||||
value |= (value << 3) | (value << 6);
|
||||
|
||||
/* In order to change only `u', `g', or `o' permissions,
|
||||
or some combination thereof, clear unselected bits.
|
||||
This can not be done in mode_compile because the value
|
||||
to which the `changes->affected' mask is applied depends
|
||||
on the old mode of each file. */
|
||||
value &= changes->affected;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = changes->value;
|
||||
/* If `X', do not affect the execute bits if the file is not a
|
||||
directory and no execute bits are already set. */
|
||||
if ((changes->flags & MODE_X_IF_ANY_X)
|
||||
&& !S_ISDIR (oldmode)
|
||||
&& (newmode & 00111) == 0)
|
||||
value &= ~00111; /* Clear the execute bits. */
|
||||
}
|
||||
|
||||
switch (changes->op)
|
||||
{
|
||||
case '=':
|
||||
/* Preserve the previous values in `newmode' of bits that are
|
||||
not affected by this change operation. */
|
||||
newmode = (newmode & ~changes->affected) | value;
|
||||
break;
|
||||
case '+':
|
||||
newmode |= value;
|
||||
break;
|
||||
case '-':
|
||||
newmode &= ~value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return newmode;
|
||||
}
|
||||
|
||||
/* Free the memory used by the list of file mode change operations
|
||||
CHANGES. */
|
||||
|
||||
void
|
||||
mode_free (changes)
|
||||
register struct mode_change *changes;
|
||||
{
|
||||
register struct mode_change *next;
|
||||
|
||||
while (changes)
|
||||
{
|
||||
next = changes->next;
|
||||
free (changes);
|
||||
changes = next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return a positive integer containing the value of the ASCII
|
||||
octal number S. If S is not an octal number, return -1. */
|
||||
|
||||
static int
|
||||
oatoi (s)
|
||||
char *s;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (*s == 0)
|
||||
return -1;
|
||||
for (i = 0; isodigit (*s); ++s)
|
||||
i = i * 8 + *s - '0';
|
||||
if (*s)
|
||||
return -1;
|
||||
return i;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/* modechange.h -- definitions for file mode manipulation
|
||||
Copyright (C) 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Masks for the `flags' field in a `struct mode_change'. */
|
||||
|
||||
/* Affect the execute bits only if at least one execute bit is set already,
|
||||
or if the file is a directory. */
|
||||
#define MODE_X_IF_ANY_X 01
|
||||
|
||||
/* If set, copy some existing permissions for u, g, or o onto the other two.
|
||||
Which of u, g, or o is copied is determined by which bits are set in the
|
||||
`value' field. */
|
||||
#define MODE_COPY_EXISTING 02
|
||||
|
||||
struct mode_change
|
||||
{
|
||||
char op; /* One of "=+-". */
|
||||
char flags; /* Special operations. */
|
||||
unsigned short affected; /* Set for u/g/o/s/s/t, if to be affected. */
|
||||
unsigned short value; /* Bits to add/remove. */
|
||||
struct mode_change *next; /* Link to next change in list. */
|
||||
};
|
||||
|
||||
/* Masks for mode_compile argument. */
|
||||
#define MODE_MASK_EQUALS 1
|
||||
#define MODE_MASK_PLUS 2
|
||||
#define MODE_MASK_MINUS 4
|
||||
|
||||
/* Error return values for mode_compile. */
|
||||
#define MODE_INVALID (struct mode_change *) 0
|
||||
#define MODE_MEMORY_EXHAUSTED (struct mode_change *) 1
|
||||
|
||||
#ifdef __STDC__
|
||||
struct mode_change *mode_compile (char *, unsigned);
|
||||
unsigned short mode_adjust (unsigned, struct mode_change *);
|
||||
void mode_free (struct mode_change *);
|
||||
#else
|
||||
struct mode_change *mode_compile ();
|
||||
unsigned short mode_adjust ();
|
||||
void mode_free ();
|
||||
#endif
|
||||
+10
-71
@@ -1,28 +1,25 @@
|
||||
/* modetype.h -- file type bits definitions for POSIX systems
|
||||
Requires sys/types.h sys/stat.h.
|
||||
Copyright (C) 1990, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* POSIX.1 doesn't mention the S_IFMT bits; instead, it uses S_IStype
|
||||
test macros. To make storing file types more convenient, define
|
||||
them; the values don't need to correspond to what the kernel uses,
|
||||
because of the way we use them. */
|
||||
#ifndef INC_MODETYPE_H
|
||||
#define INC_MODETYPE_H 1
|
||||
|
||||
#ifndef S_IFMT /* Doesn't have traditional Unix macros. */
|
||||
#define S_IFBLK 1
|
||||
#define S_IFCHR 2
|
||||
@@ -37,9 +34,6 @@
|
||||
#ifdef S_ISSOCK
|
||||
#define S_IFSOCK 64
|
||||
#endif
|
||||
#ifdef S_ISDOOR
|
||||
#define S_IFDOOR 128
|
||||
#endif
|
||||
#endif /* !S_IFMT */
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
@@ -50,7 +44,6 @@
|
||||
#undef S_ISFIFO
|
||||
#undef S_ISLNK
|
||||
#undef S_ISSOCK
|
||||
#undef S_ISDOOR
|
||||
#undef S_ISMPB
|
||||
#undef S_ISMPC
|
||||
#undef S_ISNWK
|
||||
@@ -79,64 +72,10 @@
|
||||
#if !defined(S_ISSOCK) && defined(S_IFSOCK)
|
||||
#define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#if !defined(S_ISDOOR) && defined(S_IFDOOR)
|
||||
#define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
|
||||
#endif
|
||||
#if !defined(S_ISMPB) && defined(S_IFMPB) /* V7 */
|
||||
/* Also available on Coherent, according to
|
||||
* Albert D. Cahalan (acahalan@cs.uml.edu)
|
||||
*/
|
||||
#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB) /* multiplexed block device */
|
||||
#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC) /* multiplexed char device */
|
||||
/* GNU BFD library source uses type letter 'm' for these */
|
||||
#define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
|
||||
#define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
|
||||
#endif
|
||||
|
||||
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
|
||||
/* Apparently HPUX ls gives 'n' as the type letter for these. */
|
||||
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* The above macros don't handle
|
||||
* /bin/ls letters Mode What is it?
|
||||
* S_IFNAM (Xenix "name files")
|
||||
* H S_ISCDF (HPUX Context Dependent Files)
|
||||
* S_IFCMP
|
||||
* S_IFSHAD
|
||||
*/
|
||||
|
||||
/*
|
||||
In message <199907051927.PAA01106@jupiter.cs.uml.edu>
|
||||
Albert Cahalan wrote:-
|
||||
|
||||
BTW, I believe many of these can't actually exist on disk.
|
||||
Some of these (like S_IFSHAD AFAIK) are not seen by userspace.
|
||||
|
||||
hex name ls octal description
|
||||
0000 000000 SCO out-of-service inode, BSD unknown type
|
||||
1000 S_IFIFO p| 010000 fifo (named pipe)
|
||||
2000 S_IFCHR c 020000 character special
|
||||
3000 S_IFMPC 030000 multiplexed character device (Coherent)
|
||||
4000 S_IFDIR d/ 040000 directory
|
||||
5000 S_IFNAM 050000 XENIX special named file
|
||||
6000 S_IFBLK b 060000 block special
|
||||
7000 S_IFMPB 070000 multiplexed block device (Coherent)
|
||||
8000 S_IFREG - 100000 regular
|
||||
9000 S_IFCMP 110000 VxFS compressed (file?)
|
||||
9000 S_IFNWK 110000 HP-UX network special
|
||||
a000 S_IFLNK l@ 120000 symbolic link
|
||||
b000 S_IFSHAD 130000 Solaris shadow inode for ACL
|
||||
c000 S_IFSOCK s= 140000 socket (also "S_IFSOC" on VxFS)
|
||||
d000 S_IFDOOR D 150000 Solaris door
|
||||
e000 S_IFWHT w% 160000 BSD whiteout (not used for inode)
|
||||
f000 S_IFMT 170000 mask (not used for inode)
|
||||
hex name ls octal description
|
||||
0200 S_ISVTX 001000 save swapped text even after use
|
||||
0400 S_ISGID 002000 set group ID on execution
|
||||
0400 S_ENFMT 002000 SysV forced file locking (shared w/ S_ISGID)
|
||||
0800 S_CDF 004000 HP-UX hidden directory
|
||||
0800 S_ISUID 004000 set user ID on execution
|
||||
|
||||
|
||||
*/
|
||||
|
||||
+19
-20
@@ -1,28 +1,29 @@
|
||||
/* Return the next element of a path.
|
||||
Copyright (C) 1992,2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.org>,
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>,
|
||||
inspired by John P. Rouillard <rouilj@cs.umb.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined HAVE_STRING_H || defined STDC_HEADERS
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
@@ -30,12 +31,9 @@
|
||||
#define strchr index
|
||||
#endif
|
||||
#endif
|
||||
#if defined STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "nextelem.h"
|
||||
|
||||
char *strdup ();
|
||||
void free ();
|
||||
|
||||
/* Return the next element of a colon-separated path.
|
||||
A null entry in the path is equivalent to "." (the current directory).
|
||||
@@ -45,7 +43,8 @@
|
||||
return NULL if there are no more elements. */
|
||||
|
||||
char *
|
||||
next_element (const char *new_path, int curdir_ok)
|
||||
next_element (new_path)
|
||||
char *new_path;
|
||||
{
|
||||
static char *path = NULL; /* Freshly allocated copy of NEW_PATH. */
|
||||
static char *end; /* Start of next element to return. */
|
||||
@@ -66,7 +65,7 @@ next_element (const char *new_path, int curdir_ok)
|
||||
if (final_colon)
|
||||
{
|
||||
final_colon = 0;
|
||||
return curdir_ok ? "." : "";
|
||||
return ".";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -79,7 +78,7 @@ next_element (const char *new_path, int curdir_ok)
|
||||
{
|
||||
/* An empty path element. */
|
||||
*end++ = '\0';
|
||||
return curdir_ok ? "." : "";
|
||||
return ".";
|
||||
}
|
||||
else if (end == NULL)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/* Define PATH_MAX somehow. Requires sys/types.h.
|
||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _PATHMAX_H
|
||||
#define _PATHMAX_H
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define
|
||||
PATH_MAX but might cause redefinition warnings when sys/param.h is
|
||||
later included (as on MORE/BSD 4.3). */
|
||||
#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__))
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_PATH_MAX
|
||||
#define _POSIX_PATH_MAX 255
|
||||
#endif
|
||||
|
||||
#if !defined(PATH_MAX) && defined(_PC_PATH_MAX)
|
||||
#define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX))
|
||||
#endif
|
||||
|
||||
/* Don't include sys/param.h if it already has been. */
|
||||
#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN)
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#if !defined(PATH_MAX) && defined(MAXPATHLEN)
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX _POSIX_PATH_MAX
|
||||
#endif
|
||||
|
||||
#endif /* _PATHMAX_H */
|
||||
+5244
File diff suppressed because it is too large
Load Diff
+487
@@ -0,0 +1,487 @@
|
||||
/* Definitions for data structures and routines for the regular
|
||||
expression library, version 0.12.
|
||||
|
||||
Copyright (C) 1985, 89, 90, 91, 92, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef __REGEXP_LIBRARY_H__
|
||||
#define __REGEXP_LIBRARY_H__
|
||||
|
||||
/* POSIX says that <sys/types.h> must be included (by the caller) before
|
||||
<regex.h>. */
|
||||
|
||||
#ifdef VMS
|
||||
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
|
||||
should be there. */
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* The following bits are used to determine the regexp syntax we
|
||||
recognize. The set/not-set meanings are chosen so that Emacs syntax
|
||||
remains the value 0. The bits are given in alphabetical order, and
|
||||
the definitions shifted by one from the previous bit; thus, when we
|
||||
add or remove a bit, only one other definition need change. */
|
||||
typedef unsigned reg_syntax_t;
|
||||
|
||||
/* If this bit is not set, then \ inside a bracket expression is literal.
|
||||
If set, then such a \ quotes the following character. */
|
||||
#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
|
||||
|
||||
/* If this bit is not set, then + and ? are operators, and \+ and \? are
|
||||
literals.
|
||||
If set, then \+ and \? are operators and + and ? are literals. */
|
||||
#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
|
||||
|
||||
/* If this bit is set, then character classes are supported. They are:
|
||||
[:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
|
||||
[:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
|
||||
If not set, then character classes are not supported. */
|
||||
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
|
||||
|
||||
/* If this bit is set, then ^ and $ are always anchors (outside bracket
|
||||
expressions, of course).
|
||||
If this bit is not set, then it depends:
|
||||
^ is an anchor if it is at the beginning of a regular
|
||||
expression or after an open-group or an alternation operator;
|
||||
$ is an anchor if it is at the end of a regular expression, or
|
||||
before a close-group or an alternation operator.
|
||||
|
||||
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
|
||||
POSIX draft 11.2 says that * etc. in leading positions is undefined.
|
||||
We already implemented a previous draft which made those constructs
|
||||
invalid, though, so we haven't changed the code back. */
|
||||
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
|
||||
|
||||
/* If this bit is set, then special characters are always special
|
||||
regardless of where they are in the pattern.
|
||||
If this bit is not set, then special characters are special only in
|
||||
some contexts; otherwise they are ordinary. Specifically,
|
||||
* + ? and intervals are only special when not after the beginning,
|
||||
open-group, or alternation operator. */
|
||||
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
|
||||
|
||||
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
|
||||
immediately after an alternation or begin-group operator. */
|
||||
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
|
||||
|
||||
/* If this bit is set, then . matches newline.
|
||||
If not set, then it doesn't. */
|
||||
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
|
||||
|
||||
/* If this bit is set, then . doesn't match NUL.
|
||||
If not set, then it does. */
|
||||
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
|
||||
|
||||
/* If this bit is set, nonmatching lists [^...] do not match newline.
|
||||
If not set, they do. */
|
||||
#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
|
||||
|
||||
/* If this bit is set, either \{...\} or {...} defines an
|
||||
interval, depending on RE_NO_BK_BRACES.
|
||||
If not set, \{, \}, {, and } are literals. */
|
||||
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
|
||||
|
||||
/* If this bit is set, +, ? and | aren't recognized as operators.
|
||||
If not set, they are. */
|
||||
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
|
||||
|
||||
/* If this bit is set, newline is an alternation operator.
|
||||
If not set, newline is literal. */
|
||||
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
|
||||
|
||||
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
|
||||
are literals.
|
||||
If not set, then `\{...\}' defines an interval. */
|
||||
#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
|
||||
|
||||
/* If this bit is set, (...) defines a group, and \( and \) are literals.
|
||||
If not set, \(...\) defines a group, and ( and ) are literals. */
|
||||
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
|
||||
|
||||
/* If this bit is set, then \<digit> matches <digit>.
|
||||
If not set, then \<digit> is a back-reference. */
|
||||
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
|
||||
|
||||
/* If this bit is set, then | is an alternation operator, and \| is literal.
|
||||
If not set, then \| is an alternation operator, and | is literal. */
|
||||
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
|
||||
|
||||
/* If this bit is set, then an ending range point collating higher
|
||||
than the starting range point, as in [z-a], is invalid.
|
||||
If not set, then when ending range point collates higher than the
|
||||
starting range point, the range is ignored. */
|
||||
#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
|
||||
|
||||
/* If this bit is set, then an unmatched ) is ordinary.
|
||||
If not set, then an unmatched ) is invalid. */
|
||||
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
|
||||
|
||||
/* This global variable defines the particular regexp syntax to use (for
|
||||
some interfaces). When a regexp is compiled, the syntax used is
|
||||
stored in the pattern buffer, so changing this does not affect
|
||||
already-compiled regexps. */
|
||||
extern reg_syntax_t re_syntax_options;
|
||||
|
||||
/* Define combinations of the above bits for the standard possibilities.
|
||||
(The [[[ comments delimit what gets put into the Texinfo file, so
|
||||
don't delete them!) */
|
||||
/* [[[begin syntaxes]]] */
|
||||
#define RE_SYNTAX_EMACS 0
|
||||
|
||||
#define RE_SYNTAX_AWK \
|
||||
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
|
||||
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
|
||||
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
|
||||
| RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||
|
||||
#define RE_SYNTAX_POSIX_AWK \
|
||||
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
|
||||
|
||||
#define RE_SYNTAX_GREP \
|
||||
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
|
||||
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
|
||||
| RE_NEWLINE_ALT)
|
||||
|
||||
#define RE_SYNTAX_EGREP \
|
||||
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
|
||||
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
|
||||
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
|
||||
| RE_NO_BK_VBAR)
|
||||
|
||||
#define RE_SYNTAX_POSIX_EGREP \
|
||||
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
|
||||
|
||||
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
|
||||
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
|
||||
|
||||
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
|
||||
|
||||
/* Syntax bits common to both basic and extended POSIX regex syntax. */
|
||||
#define _RE_SYNTAX_POSIX_COMMON \
|
||||
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
|
||||
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
|
||||
|
||||
#define RE_SYNTAX_POSIX_BASIC \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
|
||||
|
||||
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
|
||||
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
|
||||
isn't minimal, since other operators, such as \`, aren't disabled. */
|
||||
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
|
||||
|
||||
#define RE_SYNTAX_POSIX_EXTENDED \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
|
||||
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
|
||||
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
|
||||
| RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||
|
||||
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
|
||||
replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
|
||||
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
|
||||
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
|
||||
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
|
||||
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
|
||||
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||
/* [[[end syntaxes]]] */
|
||||
|
||||
/* Maximum number of duplicates an interval can allow. Some systems
|
||||
(erroneously) define this in other header files, but we want our
|
||||
value, so remove any previous define. */
|
||||
#ifdef RE_DUP_MAX
|
||||
#undef RE_DUP_MAX
|
||||
#endif
|
||||
#define RE_DUP_MAX ((1 << 15) - 1)
|
||||
|
||||
|
||||
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
|
||||
|
||||
/* If this bit is set, then use extended regular expression syntax.
|
||||
If not set, then use basic regular expression syntax. */
|
||||
#define REG_EXTENDED 1
|
||||
|
||||
/* If this bit is set, then ignore case when matching.
|
||||
If not set, then case is significant. */
|
||||
#define REG_ICASE (REG_EXTENDED << 1)
|
||||
|
||||
/* If this bit is set, then anchors do not match at newline
|
||||
characters in the string.
|
||||
If not set, then anchors do match at newlines. */
|
||||
#define REG_NEWLINE (REG_ICASE << 1)
|
||||
|
||||
/* If this bit is set, then report only success or fail in regexec.
|
||||
If not set, then returns differ between not matching and errors. */
|
||||
#define REG_NOSUB (REG_NEWLINE << 1)
|
||||
|
||||
|
||||
/* POSIX `eflags' bits (i.e., information for regexec). */
|
||||
|
||||
/* If this bit is set, then the beginning-of-line operator doesn't match
|
||||
the beginning of the string (presumably because it's not the
|
||||
beginning of a line).
|
||||
If not set, then the beginning-of-line operator does match the
|
||||
beginning of the string. */
|
||||
#define REG_NOTBOL 1
|
||||
|
||||
/* Like REG_NOTBOL, except for the end-of-line. */
|
||||
#define REG_NOTEOL (1 << 1)
|
||||
|
||||
|
||||
/* If any error codes are removed, changed, or added, update the
|
||||
`re_error_msg' table in regex.c. */
|
||||
typedef enum
|
||||
{
|
||||
REG_NOERROR = 0, /* Success. */
|
||||
REG_NOMATCH, /* Didn't find a match (for regexec). */
|
||||
|
||||
/* POSIX regcomp return error codes. (In the order listed in the
|
||||
standard.) */
|
||||
REG_BADPAT, /* Invalid pattern. */
|
||||
REG_ECOLLATE, /* Not implemented. */
|
||||
REG_ECTYPE, /* Invalid character class name. */
|
||||
REG_EESCAPE, /* Trailing backslash. */
|
||||
REG_ESUBREG, /* Invalid back reference. */
|
||||
REG_EBRACK, /* Unmatched left bracket. */
|
||||
REG_EPAREN, /* Parenthesis imbalance. */
|
||||
REG_EBRACE, /* Unmatched \{. */
|
||||
REG_BADBR, /* Invalid contents of \{\}. */
|
||||
REG_ERANGE, /* Invalid range end. */
|
||||
REG_ESPACE, /* Ran out of memory. */
|
||||
REG_BADRPT, /* No preceding re for repetition op. */
|
||||
|
||||
/* Error codes we've added. */
|
||||
REG_EEND, /* Premature end. */
|
||||
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
|
||||
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
|
||||
} reg_errcode_t;
|
||||
|
||||
/* This data structure represents a compiled pattern. Before calling
|
||||
the pattern compiler, the fields `buffer', `allocated', `fastmap',
|
||||
`translate', and `no_sub' can be set. After the pattern has been
|
||||
compiled, the `re_nsub' field is available. All other fields are
|
||||
private to the regex routines. */
|
||||
|
||||
struct re_pattern_buffer
|
||||
{
|
||||
/* [[[begin pattern_buffer]]] */
|
||||
/* Space that holds the compiled pattern. It is declared as
|
||||
`unsigned char *' because its elements are
|
||||
sometimes used as array indexes. */
|
||||
unsigned char *buffer;
|
||||
|
||||
/* Number of bytes to which `buffer' points. */
|
||||
unsigned long allocated;
|
||||
|
||||
/* Number of bytes actually used in `buffer'. */
|
||||
unsigned long used;
|
||||
|
||||
/* Syntax setting with which the pattern was compiled. */
|
||||
reg_syntax_t syntax;
|
||||
|
||||
/* Pointer to a fastmap, if any, otherwise zero. re_search uses
|
||||
the fastmap, if there is one, to skip over impossible
|
||||
starting points for matches. */
|
||||
char *fastmap;
|
||||
|
||||
/* Either a translate table to apply to all characters before
|
||||
comparing them, or zero for no translation. The translation
|
||||
is applied to a pattern when it is compiled and to a string
|
||||
when it is matched. */
|
||||
char *translate;
|
||||
|
||||
/* Number of subexpressions found by the compiler. */
|
||||
size_t re_nsub;
|
||||
|
||||
/* Zero if this pattern cannot match the empty string, one else.
|
||||
Well, in truth it's used only in `re_search_2', to see
|
||||
whether or not we should use the fastmap, so we don't set
|
||||
this absolutely perfectly; see `re_compile_fastmap' (the
|
||||
`duplicate' case). */
|
||||
unsigned can_be_null : 1;
|
||||
|
||||
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
|
||||
for `max (RE_NREGS, re_nsub + 1)' groups.
|
||||
If REGS_REALLOCATE, reallocate space if necessary.
|
||||
If REGS_FIXED, use what's there. */
|
||||
#define REGS_UNALLOCATED 0
|
||||
#define REGS_REALLOCATE 1
|
||||
#define REGS_FIXED 2
|
||||
unsigned regs_allocated : 2;
|
||||
|
||||
/* Set to zero when `regex_compile' compiles a pattern; set to one
|
||||
by `re_compile_fastmap' if it updates the fastmap. */
|
||||
unsigned fastmap_accurate : 1;
|
||||
|
||||
/* If set, `re_match_2' does not return information about
|
||||
subexpressions. */
|
||||
unsigned no_sub : 1;
|
||||
|
||||
/* If set, a beginning-of-line anchor doesn't match at the
|
||||
beginning of the string. */
|
||||
unsigned not_bol : 1;
|
||||
|
||||
/* Similarly for an end-of-line anchor. */
|
||||
unsigned not_eol : 1;
|
||||
|
||||
/* If true, an anchor at a newline matches. */
|
||||
unsigned newline_anchor : 1;
|
||||
|
||||
/* [[[end pattern_buffer]]] */
|
||||
};
|
||||
|
||||
typedef struct re_pattern_buffer regex_t;
|
||||
|
||||
/* Type for byte offsets within the string. POSIX mandates this. */
|
||||
typedef int regoff_t;
|
||||
|
||||
|
||||
/* This is the structure we store register match data in. See
|
||||
regex.texinfo for a full description of what registers match. */
|
||||
struct re_registers
|
||||
{
|
||||
unsigned num_regs;
|
||||
regoff_t *start;
|
||||
regoff_t *end;
|
||||
};
|
||||
|
||||
|
||||
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
|
||||
`re_match_2' returns information about at least this many registers
|
||||
the first time a `regs' structure is passed. */
|
||||
#ifndef RE_NREGS
|
||||
#define RE_NREGS 30
|
||||
#endif
|
||||
|
||||
|
||||
/* POSIX specification for registers. Aside from the different names than
|
||||
`re_registers', POSIX uses an array of structures, instead of a
|
||||
structure of arrays. */
|
||||
typedef struct
|
||||
{
|
||||
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
|
||||
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
|
||||
} regmatch_t;
|
||||
|
||||
/* Declarations for routines. */
|
||||
|
||||
/* To avoid duplicating every routine declaration -- once with a
|
||||
prototype (if we are ANSI), and once without (if we aren't) -- we
|
||||
use the following macro to declare argument types. This
|
||||
unfortunately clutters up the declarations a bit, but I think it's
|
||||
worth it. */
|
||||
|
||||
#if __STDC__
|
||||
|
||||
#define _RE_ARGS(args) args
|
||||
|
||||
#else /* not __STDC__ */
|
||||
|
||||
#define _RE_ARGS(args) ()
|
||||
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
/* Sets the current default syntax to SYNTAX, and return the old syntax.
|
||||
You can also simply assign to the `re_syntax_options' variable. */
|
||||
extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
|
||||
|
||||
/* Compile the regular expression PATTERN, with length LENGTH
|
||||
and syntax given by the global `re_syntax_options', into the buffer
|
||||
BUFFER. Return NULL if successful, and an error string if not. */
|
||||
extern const char *re_compile_pattern
|
||||
_RE_ARGS ((const char *pattern, int length,
|
||||
struct re_pattern_buffer *buffer));
|
||||
|
||||
|
||||
/* Compile a fastmap for the compiled pattern in BUFFER; used to
|
||||
accelerate searches. Return 0 if successful and -2 if was an
|
||||
internal error. */
|
||||
extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
|
||||
|
||||
|
||||
/* Search in the string STRING (with length LENGTH) for the pattern
|
||||
compiled into BUFFER. Start searching at position START, for RANGE
|
||||
characters. Return the starting position of the match, -1 for no
|
||||
match, or -2 for an internal error. Also return register
|
||||
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
|
||||
extern int re_search
|
||||
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
|
||||
int length, int start, int range, struct re_registers *regs));
|
||||
|
||||
|
||||
/* Like `re_search', but search in the concatenation of STRING1 and
|
||||
STRING2. Also, stop searching at index START + STOP. */
|
||||
extern int re_search_2
|
||||
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
|
||||
int length1, const char *string2, int length2,
|
||||
int start, int range, struct re_registers *regs, int stop));
|
||||
|
||||
|
||||
/* Like `re_search', but return how many characters in STRING the regexp
|
||||
in BUFFER matched, starting at position START. */
|
||||
extern int re_match
|
||||
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
|
||||
int length, int start, struct re_registers *regs));
|
||||
|
||||
|
||||
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
|
||||
extern int re_match_2
|
||||
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
|
||||
int length1, const char *string2, int length2,
|
||||
int start, struct re_registers *regs, int stop));
|
||||
|
||||
|
||||
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
|
||||
ENDS. Subsequent matches using BUFFER and REGS will use this memory
|
||||
for recording register information. STARTS and ENDS must be
|
||||
allocated with malloc, and must each be at least `NUM_REGS * sizeof
|
||||
(regoff_t)' bytes long.
|
||||
|
||||
If NUM_REGS == 0, then subsequent matches should allocate their own
|
||||
register data.
|
||||
|
||||
Unless this function is called, the first search or match using
|
||||
PATTERN_BUFFER will allocate its own register data, without
|
||||
freeing the old data. */
|
||||
extern void re_set_registers
|
||||
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
|
||||
unsigned num_regs, regoff_t *starts, regoff_t *ends));
|
||||
|
||||
#ifdef _REGEX_RE_COMP
|
||||
/* 4.2 bsd compatibility. */
|
||||
extern char *re_comp _RE_ARGS ((const char *));
|
||||
extern int re_exec _RE_ARGS ((const char *));
|
||||
#endif
|
||||
|
||||
/* POSIX compatibility. */
|
||||
extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
|
||||
extern int regexec
|
||||
_RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
|
||||
regmatch_t pmatch[], int eflags));
|
||||
extern size_t regerror
|
||||
_RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
|
||||
size_t errbuf_size));
|
||||
extern void regfree _RE_ARGS ((regex_t *preg));
|
||||
|
||||
#endif /* not __REGEXP_LIBRARY_H__ */
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
make-backup-files: t
|
||||
version-control: t
|
||||
trim-versions-without-asking: nil
|
||||
End:
|
||||
*/
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
/* savedir.c -- save the list of files in a directory in a string
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#else
|
||||
# define dirent direct
|
||||
# define NAMLEN(dirent) (dirent)->d_namlen
|
||||
# if HAVE_SYS_NDIR_H
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# if HAVE_SYS_DIR_H
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# if HAVE_NDIR_H
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef CLOSEDIR_VOID
|
||||
/* Fake a return value. */
|
||||
#define CLOSEDIR(d) (closedir (d), 0)
|
||||
#else
|
||||
#define CLOSEDIR(d) closedir (d)
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
char *realloc ();
|
||||
#endif
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
char *stpcpy ();
|
||||
|
||||
/* Return a freshly allocated string containing the filenames
|
||||
in directory DIR, separated by '\0' characters;
|
||||
the end is marked by two '\0' characters in a row.
|
||||
NAME_SIZE is the number of bytes to initially allocate
|
||||
for the string; it will be enlarged as needed.
|
||||
Return NULL if DIR cannot be opened or if out of memory. */
|
||||
|
||||
char *
|
||||
savedir (dir, name_size)
|
||||
char *dir;
|
||||
unsigned name_size;
|
||||
{
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
char *name_space;
|
||||
char *namep;
|
||||
|
||||
dirp = opendir (dir);
|
||||
if (dirp == NULL)
|
||||
return NULL;
|
||||
|
||||
name_space = (char *) malloc (name_size);
|
||||
if (name_space == NULL)
|
||||
{
|
||||
closedir (dirp);
|
||||
return NULL;
|
||||
}
|
||||
namep = name_space;
|
||||
|
||||
while ((dp = readdir (dirp)) != NULL)
|
||||
{
|
||||
/* Skip "." and ".." (some NFS filesystems' directories lack them). */
|
||||
if (dp->d_name[0] != '.'
|
||||
|| (dp->d_name[1] != '\0'
|
||||
&& (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
|
||||
{
|
||||
unsigned size_needed = (namep - name_space) + NAMLEN (dp) + 2;
|
||||
|
||||
if (size_needed > name_size)
|
||||
{
|
||||
char *new_name_space;
|
||||
|
||||
while (size_needed > name_size)
|
||||
name_size += 1024;
|
||||
|
||||
new_name_space = realloc (name_space, name_size);
|
||||
if (new_name_space == NULL)
|
||||
{
|
||||
closedir (dirp);
|
||||
return NULL;
|
||||
}
|
||||
namep += new_name_space - name_space;
|
||||
name_space = new_name_space;
|
||||
}
|
||||
namep = stpcpy (namep, dp->d_name) + 1;
|
||||
}
|
||||
}
|
||||
*namep = '\0';
|
||||
if (CLOSEDIR (dirp))
|
||||
{
|
||||
free (name_space);
|
||||
return NULL;
|
||||
}
|
||||
return name_space;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/* stpcpy.c -- copy a string and return pointer to end of new string
|
||||
Copyright (C) 1989, 1990 Free Software Foundation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
|
||||
|
||||
char *
|
||||
stpcpy (dest, src)
|
||||
char *dest;
|
||||
const char *src;
|
||||
{
|
||||
while ((*dest++ = *src++) != '\0')
|
||||
/* Do nothing. */ ;
|
||||
return dest - 1;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/* strdup.c -- return a newly allocated copy of a string
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *malloc ();
|
||||
char *strcpy ();
|
||||
#endif
|
||||
|
||||
/* Return a newly allocated copy of STR,
|
||||
or 0 if out of memory. */
|
||||
|
||||
char *
|
||||
strdup (str)
|
||||
const char *str;
|
||||
{
|
||||
char *newstr;
|
||||
|
||||
newstr = (char *) malloc (strlen (str) + 1);
|
||||
if (newstr)
|
||||
strcpy (newstr, str);
|
||||
return newstr;
|
||||
}
|
||||
+469
@@ -0,0 +1,469 @@
|
||||
/* strftime - custom formatting of date and/or time
|
||||
Copyright (C) 1989, 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Note: this version of strftime lacks locale support,
|
||||
but it is standalone.
|
||||
|
||||
Performs `%' substitutions similar to those in printf. Except
|
||||
where noted, substituted fields have a fixed size; numeric fields are
|
||||
padded if necessary. Padding is with zeros by default; for fields
|
||||
that display a single number, padding can be changed or inhibited by
|
||||
following the `%' with one of the modifiers described below. Unknown
|
||||
field specifiers are copied as normal characters. All other
|
||||
characters are copied to the output without change.
|
||||
|
||||
Supports a superset of the ANSI C field specifiers.
|
||||
|
||||
Literal character fields:
|
||||
% %
|
||||
n newline
|
||||
t tab
|
||||
|
||||
Numeric modifiers (a nonstandard extension):
|
||||
- do not pad the field
|
||||
_ pad the field with spaces
|
||||
|
||||
Time fields:
|
||||
%H hour (00..23)
|
||||
%I hour (01..12)
|
||||
%k hour ( 0..23)
|
||||
%l hour ( 1..12)
|
||||
%M minute (00..59)
|
||||
%p locale's AM or PM
|
||||
%r time, 12-hour (hh:mm:ss [AP]M)
|
||||
%R time, 24-hour (hh:mm)
|
||||
%s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension)
|
||||
%S second (00..61)
|
||||
%T time, 24-hour (hh:mm:ss)
|
||||
%X locale's time representation (%H:%M:%S)
|
||||
%Z time zone (EDT), or nothing if no time zone is determinable
|
||||
|
||||
Date fields:
|
||||
%a locale's abbreviated weekday name (Sun..Sat)
|
||||
%A locale's full weekday name, variable length (Sunday..Saturday)
|
||||
%b locale's abbreviated month name (Jan..Dec)
|
||||
%B locale's full month name, variable length (January..December)
|
||||
%c locale's date and time (Sat Nov 04 12:02:33 EST 1989)
|
||||
%C century (00..99)
|
||||
%d day of month (01..31)
|
||||
%e day of month ( 1..31)
|
||||
%D date (mm/dd/yy)
|
||||
%h same as %b
|
||||
%j day of year (001..366)
|
||||
%m month (01..12)
|
||||
%U week number of year with Sunday as first day of week (00..53)
|
||||
%w day of week (0..6)
|
||||
%W week number of year with Monday as first day of week (00..53)
|
||||
%x locale's date representation (mm/dd/yy)
|
||||
%y last two digits of year (00..99)
|
||||
%Y year (1970...)
|
||||
|
||||
David MacKenzie <djm@gnu.ai.mit.edu> */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#if defined(TM_IN_SYS_TIME) || (!defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME))
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
time_t mktime ();
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
#endif
|
||||
|
||||
/* Types of padding for numbers in date and time. */
|
||||
enum padding
|
||||
{
|
||||
none, blank, zero
|
||||
};
|
||||
|
||||
static char const* const days[] =
|
||||
{
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
|
||||
};
|
||||
|
||||
static char const * const months[] =
|
||||
{
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December"
|
||||
};
|
||||
|
||||
/* Add character C to STRING and increment LENGTH,
|
||||
unless LENGTH would exceed MAX. */
|
||||
|
||||
#define add_char(c) \
|
||||
do \
|
||||
{ \
|
||||
if (length + 1 <= max) \
|
||||
string[length++] = (c); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Add a 2 digit number to STRING, padding if specified.
|
||||
Return the number of characters added, up to MAX. */
|
||||
|
||||
static int
|
||||
add_num2 (string, num, max, pad)
|
||||
char *string;
|
||||
int num;
|
||||
int max;
|
||||
enum padding pad;
|
||||
{
|
||||
int top = num / 10;
|
||||
int length = 0;
|
||||
|
||||
if (top == 0 && pad == blank)
|
||||
add_char (' ');
|
||||
else if (top != 0 || pad == zero)
|
||||
add_char (top + '0');
|
||||
add_char (num % 10 + '0');
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Add a 3 digit number to STRING, padding if specified.
|
||||
Return the number of characters added, up to MAX. */
|
||||
|
||||
static int
|
||||
add_num3 (string, num, max, pad)
|
||||
char *string;
|
||||
int num;
|
||||
int max;
|
||||
enum padding pad;
|
||||
{
|
||||
int top = num / 100;
|
||||
int mid = (num - top * 100) / 10;
|
||||
int length = 0;
|
||||
|
||||
if (top == 0 && pad == blank)
|
||||
add_char (' ');
|
||||
else if (top != 0 || pad == zero)
|
||||
add_char (top + '0');
|
||||
if (mid == 0 && top == 0 && pad == blank)
|
||||
add_char (' ');
|
||||
else if (mid != 0 || top != 0 || pad == zero)
|
||||
add_char (mid + '0');
|
||||
add_char (num % 10 + '0');
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Like strncpy except return the number of characters copied. */
|
||||
|
||||
static int
|
||||
add_str (to, from, max)
|
||||
char *to;
|
||||
const char *from;
|
||||
int max;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; from[i] && i <= max; ++i)
|
||||
to[i] = from[i];
|
||||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
add_num_time_t (string, max, num)
|
||||
char *string;
|
||||
int max;
|
||||
time_t num;
|
||||
{
|
||||
/* This buffer is large enough to hold the character representation
|
||||
(including the trailing NUL) of any unsigned decimal quantity
|
||||
whose binary representation fits in 128 bits. */
|
||||
char buf[40];
|
||||
int length;
|
||||
|
||||
if (sizeof (num) > 16)
|
||||
abort ();
|
||||
sprintf (buf, "%lu", (unsigned long) num);
|
||||
length = add_str (string, buf, max);
|
||||
return length;
|
||||
}
|
||||
|
||||
/* Return the week in the year of the time in TM, with the weeks
|
||||
starting on Sundays. */
|
||||
|
||||
static int
|
||||
sun_week (tm)
|
||||
struct tm *tm;
|
||||
{
|
||||
int dl;
|
||||
|
||||
/* Set `dl' to the day in the year of the last day of the week previous
|
||||
to the one containing the day specified in TM. If the day specified
|
||||
in TM is in the first week of the year, `dl' will be negative or 0.
|
||||
Otherwise, calculate the number of complete weeks before our week
|
||||
(dl / 7) and add any partial week at the start of the year (dl % 7). */
|
||||
dl = tm->tm_yday - tm->tm_wday;
|
||||
return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0);
|
||||
}
|
||||
|
||||
/* Return the week in the year of the time in TM, with the weeks
|
||||
starting on Mondays. */
|
||||
|
||||
static int
|
||||
mon_week (tm)
|
||||
struct tm *tm;
|
||||
{
|
||||
int dl, wday;
|
||||
|
||||
if (tm->tm_wday == 0)
|
||||
wday = 6;
|
||||
else
|
||||
wday = tm->tm_wday - 1;
|
||||
dl = tm->tm_yday - wday;
|
||||
return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0);
|
||||
}
|
||||
|
||||
#if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)
|
||||
char *
|
||||
zone_name (tp)
|
||||
struct tm *tp;
|
||||
{
|
||||
char *timezone ();
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
gettimeofday (&tv, &tz);
|
||||
return timezone (tz.tz_minuteswest, tp->tm_isdst);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Format the time given in TM according to FORMAT, and put the
|
||||
results in STRING.
|
||||
Return the number of characters (not including terminating null)
|
||||
that were put into STRING, or 0 if the length would have
|
||||
exceeded MAX. */
|
||||
|
||||
size_t
|
||||
strftime (string, max, format, tm)
|
||||
char *string;
|
||||
size_t max;
|
||||
const char *format;
|
||||
const struct tm *tm;
|
||||
{
|
||||
enum padding pad; /* Type of padding to apply. */
|
||||
size_t length = 0; /* Characters put in STRING so far. */
|
||||
|
||||
for (; *format && length < max; ++format)
|
||||
{
|
||||
if (*format != '%')
|
||||
add_char (*format);
|
||||
else
|
||||
{
|
||||
++format;
|
||||
/* Modifiers: */
|
||||
if (*format == '-')
|
||||
{
|
||||
pad = none;
|
||||
++format;
|
||||
}
|
||||
else if (*format == '_')
|
||||
{
|
||||
pad = blank;
|
||||
++format;
|
||||
}
|
||||
else
|
||||
pad = zero;
|
||||
|
||||
switch (*format)
|
||||
{
|
||||
/* Literal character fields: */
|
||||
case 0:
|
||||
case '%':
|
||||
add_char ('%');
|
||||
break;
|
||||
case 'n':
|
||||
add_char ('\n');
|
||||
break;
|
||||
case 't':
|
||||
add_char ('\t');
|
||||
break;
|
||||
default:
|
||||
add_char (*format);
|
||||
break;
|
||||
|
||||
/* Time fields: */
|
||||
case 'H':
|
||||
case 'k':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_hour, max - length,
|
||||
*format == 'H' ? pad : blank);
|
||||
break;
|
||||
case 'I':
|
||||
case 'l':
|
||||
{
|
||||
int hour12;
|
||||
|
||||
if (tm->tm_hour == 0)
|
||||
hour12 = 12;
|
||||
else if (tm->tm_hour > 12)
|
||||
hour12 = tm->tm_hour - 12;
|
||||
else
|
||||
hour12 = tm->tm_hour;
|
||||
length +=
|
||||
add_num2 (&string[length], hour12, max - length,
|
||||
*format == 'I' ? pad : blank);
|
||||
}
|
||||
break;
|
||||
case 'M':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_min, max - length, pad);
|
||||
break;
|
||||
case 'p':
|
||||
if (tm->tm_hour < 12)
|
||||
add_char ('A');
|
||||
else
|
||||
add_char ('P');
|
||||
add_char ('M');
|
||||
break;
|
||||
case 'r':
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%I:%M:%S %p", tm);
|
||||
break;
|
||||
case 'R':
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%H:%M", tm);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
{
|
||||
struct tm writable_tm;
|
||||
writable_tm = *tm;
|
||||
length += add_num_time_t (&string[length], max - length,
|
||||
mktime (&writable_tm));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_sec, max - length, pad);
|
||||
break;
|
||||
case 'T':
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%H:%M:%S", tm);
|
||||
break;
|
||||
case 'X':
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%H:%M:%S", tm);
|
||||
break;
|
||||
case 'Z':
|
||||
#ifdef HAVE_TM_ZONE
|
||||
length += add_str (&string[length], tm->tm_zone, max - length);
|
||||
#else
|
||||
#ifdef HAVE_TZNAME
|
||||
if (tm->tm_isdst && tzname[1] && *tzname[1])
|
||||
length += add_str (&string[length], tzname[1], max - length);
|
||||
else
|
||||
length += add_str (&string[length], tzname[0], max - length);
|
||||
#else
|
||||
length += add_str (&string[length], zone_name (tm), max - length);
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* Date fields: */
|
||||
case 'a':
|
||||
add_char (days[tm->tm_wday][0]);
|
||||
add_char (days[tm->tm_wday][1]);
|
||||
add_char (days[tm->tm_wday][2]);
|
||||
break;
|
||||
case 'A':
|
||||
length +=
|
||||
add_str (&string[length], days[tm->tm_wday], max - length);
|
||||
break;
|
||||
case 'b':
|
||||
case 'h':
|
||||
add_char (months[tm->tm_mon][0]);
|
||||
add_char (months[tm->tm_mon][1]);
|
||||
add_char (months[tm->tm_mon][2]);
|
||||
break;
|
||||
case 'B':
|
||||
length +=
|
||||
add_str (&string[length], months[tm->tm_mon], max - length);
|
||||
break;
|
||||
case 'c':
|
||||
length +=
|
||||
strftime (&string[length], max - length,
|
||||
"%a %b %d %H:%M:%S %Z %Y", tm);
|
||||
break;
|
||||
case 'C':
|
||||
length +=
|
||||
add_num2 (&string[length], (tm->tm_year + 1900) / 100,
|
||||
max - length, pad);
|
||||
break;
|
||||
case 'd':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_mday, max - length, pad);
|
||||
break;
|
||||
case 'e':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_mday, max - length, blank);
|
||||
break;
|
||||
case 'D':
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%m/%d/%y", tm);
|
||||
break;
|
||||
case 'j':
|
||||
length +=
|
||||
add_num3 (&string[length], tm->tm_yday + 1, max - length, pad);
|
||||
break;
|
||||
case 'm':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_mon + 1, max - length, pad);
|
||||
break;
|
||||
case 'U':
|
||||
length +=
|
||||
add_num2 (&string[length], sun_week (tm), max - length, pad);
|
||||
break;
|
||||
case 'w':
|
||||
add_char (tm->tm_wday + '0');
|
||||
break;
|
||||
case 'W':
|
||||
length +=
|
||||
add_num2 (&string[length], mon_week (tm), max - length, pad);
|
||||
break;
|
||||
case 'x':
|
||||
length +=
|
||||
strftime (&string[length], max - length, "%m/%d/%y", tm);
|
||||
break;
|
||||
case 'y':
|
||||
length +=
|
||||
add_num2 (&string[length], tm->tm_year % 100,
|
||||
max - length, pad);
|
||||
break;
|
||||
case 'Y':
|
||||
add_char ((tm->tm_year + 1900) / 1000 + '0');
|
||||
length +=
|
||||
add_num3 (&string[length],
|
||||
(1900 + tm->tm_year) % 1000, max - length, zero);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
add_char (0);
|
||||
return length - 1;
|
||||
}
|
||||
+11
-12
@@ -1,24 +1,25 @@
|
||||
/* strspn.c -- return numbers of chars at start of string in a class
|
||||
Copyright (C) 1987, 1990, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
|
||||
#if defined HAVE_STRING_H
|
||||
#if defined(HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
@@ -27,7 +28,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRSPN)
|
||||
int
|
||||
strspn (str, class)
|
||||
char *str, *class;
|
||||
@@ -38,4 +38,3 @@ strspn (str, class)
|
||||
++st;
|
||||
return st - str;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/* strstr.c -- return the offset of one string within another
|
||||
Copyright (C) 1989, 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by Mike Rendell <michael@cs.mun.ca>. */
|
||||
|
||||
/* Return the starting address of string S2 in S1;
|
||||
return 0 if it is not found. */
|
||||
|
||||
char *
|
||||
strstr (s1, s2)
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
int i;
|
||||
char *p1;
|
||||
char *p2;
|
||||
char *s = s1;
|
||||
|
||||
for (p2 = s2, i = 0; *s; p2 = s2, i++, s++)
|
||||
{
|
||||
for (p1 = s; *p1 && *p2 && *p1 == *p2; p1++, p2++)
|
||||
;
|
||||
if (!*p2)
|
||||
break;
|
||||
}
|
||||
if (!*p2)
|
||||
return s1 + i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if HAVE_LIMITS_H
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#ifndef ULONG_MAX
|
||||
#define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MAX
|
||||
#define LONG_MAX (~(1 << (sizeof (long) * 8 - 1)))
|
||||
#endif
|
||||
|
||||
#ifndef LONG_MIN
|
||||
#define LONG_MIN (-LONG_MAX - 1)
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#define NULL 0
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef UNSIGNED
|
||||
#define UNSIGNED 0
|
||||
#endif
|
||||
|
||||
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
|
||||
If BASE is 0 the base is determined by the presence of a leading
|
||||
zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
|
||||
If BASE is < 2 or > 36, it is reset to 10.
|
||||
If ENDPTR is not NULL, a pointer to the character after the last
|
||||
one converted is stored in *ENDPTR. */
|
||||
#if UNSIGNED
|
||||
unsigned long int
|
||||
#define strtol strtoul
|
||||
#else
|
||||
long int
|
||||
#endif
|
||||
strtol (nptr, endptr, base)
|
||||
const char *nptr;
|
||||
char **endptr;
|
||||
int base;
|
||||
{
|
||||
int negative;
|
||||
register unsigned long int cutoff;
|
||||
register unsigned int cutlim;
|
||||
register unsigned long int i;
|
||||
register const char *s;
|
||||
register unsigned char c;
|
||||
const char *save;
|
||||
int overflow;
|
||||
|
||||
if (base < 0 || base == 1 || base > 36)
|
||||
base = 10;
|
||||
|
||||
s = nptr;
|
||||
|
||||
/* Skip white space. */
|
||||
while (isspace (*s))
|
||||
++s;
|
||||
if (*s == '\0')
|
||||
goto noconv;
|
||||
|
||||
/* Check for a sign. */
|
||||
if (*s == '-')
|
||||
{
|
||||
negative = 1;
|
||||
++s;
|
||||
}
|
||||
else if (*s == '+')
|
||||
{
|
||||
negative = 0;
|
||||
++s;
|
||||
}
|
||||
else
|
||||
negative = 0;
|
||||
|
||||
if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
|
||||
s += 2;
|
||||
|
||||
/* If BASE is zero, figure it out ourselves. */
|
||||
if (base == 0)
|
||||
{
|
||||
if (*s == '0')
|
||||
{
|
||||
if (toupper (s[1]) == 'X')
|
||||
{
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
else
|
||||
base = 10;
|
||||
}
|
||||
|
||||
/* Save the pointer so we can check later if anything happened. */
|
||||
save = s;
|
||||
|
||||
cutoff = ULONG_MAX / (unsigned long int) base;
|
||||
cutlim = ULONG_MAX % (unsigned long int) base;
|
||||
|
||||
overflow = 0;
|
||||
i = 0;
|
||||
for (c = *s; c != '\0'; c = *++s)
|
||||
{
|
||||
if (isdigit (c))
|
||||
c -= '0';
|
||||
else if (isalpha (c))
|
||||
c = toupper (c) - 'A' + 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
/* Check for overflow. */
|
||||
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||
overflow = 1;
|
||||
else
|
||||
{
|
||||
i *= (unsigned long int) base;
|
||||
i += c;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if anything actually happened. */
|
||||
if (s == save)
|
||||
goto noconv;
|
||||
|
||||
/* Store in ENDPTR the address of one character
|
||||
past the last character we converted. */
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) s;
|
||||
|
||||
#if !UNSIGNED
|
||||
/* Check for a value that is within the range of
|
||||
`unsigned long int', but outside the range of `long int'. */
|
||||
if (i > (negative ?
|
||||
-(unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
|
||||
overflow = 1;
|
||||
#endif
|
||||
|
||||
if (overflow)
|
||||
{
|
||||
errno = ERANGE;
|
||||
#if UNSIGNED
|
||||
return ULONG_MAX;
|
||||
#else
|
||||
return negative ? LONG_MIN : LONG_MAX;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return the result of the appropriate sign. */
|
||||
return (negative ? -i : i);
|
||||
|
||||
noconv:;
|
||||
/* There was no number to convert. */
|
||||
if (endptr != NULL)
|
||||
*endptr = (char *) nptr;
|
||||
return 0L;
|
||||
}
|
||||
+8
-7
@@ -1,19 +1,20 @@
|
||||
/* wait.h -- POSIX macros for evaluating exit statuses
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <sys/types.h> /* For pid_t. */
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/* xgetcwd.c -- return current directory with unlimited length
|
||||
Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include "pathmax.h"
|
||||
|
||||
#ifndef HAVE_GETCWD
|
||||
char *getwd ();
|
||||
#define getcwd(buf, max) getwd (buf)
|
||||
#else
|
||||
char *getcwd ();
|
||||
#endif
|
||||
|
||||
/* Amount to increase buffer size by in each try. */
|
||||
#define PATH_INCR 32
|
||||
|
||||
char *xmalloc ();
|
||||
char *xrealloc ();
|
||||
void free ();
|
||||
|
||||
/* Return the current directory, newly allocated, arbitrarily long.
|
||||
Return NULL and set errno on error. */
|
||||
|
||||
char *
|
||||
xgetcwd ()
|
||||
{
|
||||
char *cwd;
|
||||
char *ret;
|
||||
unsigned path_max;
|
||||
|
||||
errno = 0;
|
||||
path_max = (unsigned) PATH_MAX;
|
||||
path_max += 2; /* The getcwd docs say to do this. */
|
||||
|
||||
cwd = xmalloc (path_max);
|
||||
|
||||
errno = 0;
|
||||
while ((ret = getcwd (cwd, path_max)) == NULL && errno == ERANGE)
|
||||
{
|
||||
path_max += PATH_INCR;
|
||||
cwd = xrealloc (cwd, path_max);
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
int save_errno = errno;
|
||||
free (cwd);
|
||||
errno = save_errno;
|
||||
return NULL;
|
||||
}
|
||||
return cwd;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/* xmalloc.c -- malloc with out of memory checking
|
||||
Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
#define VOID void
|
||||
#else
|
||||
#define VOID char
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
VOID *malloc ();
|
||||
VOID *realloc ();
|
||||
void free ();
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
|
||||
/* Exit value when the requested amount of memory is not available.
|
||||
The caller may set it to some other value. */
|
||||
int xmalloc_exit_failure = EXIT_FAILURE;
|
||||
|
||||
#if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT)
|
||||
void error (int, int, const char *, ...);
|
||||
#else
|
||||
void error ();
|
||||
#endif
|
||||
|
||||
static VOID *
|
||||
fixup_null_alloc (n)
|
||||
size_t n;
|
||||
{
|
||||
VOID *p;
|
||||
|
||||
p = 0;
|
||||
if (n == 0)
|
||||
p = malloc ((size_t) 1);
|
||||
if (p == 0)
|
||||
error (xmalloc_exit_failure, 0, "memory exhausted");
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Allocate N bytes of memory dynamically, with error checking. */
|
||||
|
||||
VOID *
|
||||
xmalloc (n)
|
||||
size_t n;
|
||||
{
|
||||
VOID *p;
|
||||
|
||||
p = malloc (n);
|
||||
if (p == 0)
|
||||
p = fixup_null_alloc (n);
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Change the size of an allocated block of memory P to N bytes,
|
||||
with error checking.
|
||||
If P is NULL, run xmalloc. */
|
||||
|
||||
VOID *
|
||||
xrealloc (p, n)
|
||||
VOID *p;
|
||||
size_t n;
|
||||
{
|
||||
if (p == 0)
|
||||
return xmalloc (n);
|
||||
p = realloc (p, n);
|
||||
if (p == 0)
|
||||
p = fixup_null_alloc (n);
|
||||
return p;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/* xstrdup.c -- copy a string with out of memory checking
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
char *xmalloc ();
|
||||
|
||||
/* Return a newly allocated copy of STRING. */
|
||||
|
||||
char *
|
||||
xstrdup (string)
|
||||
char *string;
|
||||
{
|
||||
return strcpy (xmalloc (strlen (string) + 1), string);
|
||||
}
|
||||
+24
-40
@@ -1,58 +1,42 @@
|
||||
# The default database to build and search.
|
||||
AUTOMAKE_OPTIONS = std-options
|
||||
LOCATE_DB = $(localstatedir)/locatedb
|
||||
localedir = $(datadir)/locale
|
||||
|
||||
AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = \
|
||||
frcode$(EXEEXT) \
|
||||
code$(EXEEXT) \
|
||||
bigram$(EXEEXT)
|
||||
bin_PROGRAMS = locate
|
||||
libexec_PROGRAMS = frcode code bigram
|
||||
bin_SCRIPTS = updatedb
|
||||
man_MANS = locate.1 updatedb.1 locatedb.5
|
||||
BUILT_SOURCES = dblocation.texi
|
||||
EXTRA_DIST = locatedb.h updatedb.sh $(man_MANS)
|
||||
CLEANFILES = updatedb dblocation.texi
|
||||
locate_SOURCES = locate.c word_io.c
|
||||
code_SOURCES = code.c word_io.c
|
||||
PROGRAMS = locate
|
||||
LIBPROGRAMS = frcode code bigram
|
||||
SCRIPTS = updatedb
|
||||
MANS = locate.1 updatedb.1 locatedb.5
|
||||
CONFIG_HEADER = ../config.h
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/lib -I../gnulib/lib -I$(top_srcdir)/gnulib/lib -I../intl -DLOCATE_DB=\"$(LOCATE_DB)\" -DLOCALEDIR=\"$(localedir)\"
|
||||
DIST_OTHER = locatedb.h updatedb.sh
|
||||
CLEANFILES = updatedb
|
||||
|
||||
LDADD = ../lib/libfind.a ../gnulib/lib/libgnulib.a @INTLLIBS@
|
||||
INCLUDES = -I.. -I$(top_srcdir)/lib -DLOCATE_DB=\"$(LOCATE_DB)\"
|
||||
|
||||
$(PROGRAMS) $(LIBPROGRAMS): ../lib/libfind.a ../gnulib/lib/libgnulib.a
|
||||
LDADD = ../find/version.o ../lib/libfind.a
|
||||
|
||||
$(PROGRAMS) $(LIBPROGRAMS): ../find/version.o ../lib/libfind.a
|
||||
|
||||
updatedb: updatedb.sh
|
||||
rm -f $@
|
||||
version=`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q $(top_srcdir)/find/version.c`; \
|
||||
find=`echo find|sed '$(transform)'`; \
|
||||
frcode=`echo frcode|sed '$(transform)'`; \
|
||||
bigram=`echo bigram|sed '$(transform)'`; \
|
||||
code=`echo code|sed '$(transform)'`; \
|
||||
sed \
|
||||
-e "s,@""bindir""@,$(bindir)," \
|
||||
-e "s,@""libexecdir""@,$(libexecdir)," \
|
||||
-e "s,@""LOCATE_DB""@,$(LOCATE_DB)," \
|
||||
-e "s,@""VERSION""@,@VERSION@," \
|
||||
-e "s,@""PACKAGE_NAME""@,@PACKAGE_NAME@," \
|
||||
-e "s,@""find""@,$${find}," \
|
||||
-e "s,@""frcode""@,$${frcode}," \
|
||||
-e "s,@""bigram""@,$${bigram}," \
|
||||
-e "s,@""code""@,$${code}," \
|
||||
-e "s,@""SORT""@,$(SORT)," \
|
||||
-e "s,@""SORT_SUPPORTS_Z""@,$(SORT_SUPPORTS_Z)," \
|
||||
-e "s,@bindir@,$(bindir)," \
|
||||
-e "s,@libexecdir@,$(libexecdir)," \
|
||||
-e "s,@LOCATE_DB@,$(LOCATE_DB)," \
|
||||
-e "s,@version@,$$version," \
|
||||
-e "s,@find@,$$find," \
|
||||
-e "s,@frcode@,$$frcode," \
|
||||
-e "s,@bigram@,$$bigram," \
|
||||
-e "s,@code@,$$code," \
|
||||
$(srcdir)/updatedb.sh > $@
|
||||
chmod +x $@
|
||||
|
||||
install-data-hook:
|
||||
$(top_srcdir)/build-aux/mkinstalldirs $(DESTDIR)$(localstatedir)
|
||||
install::
|
||||
$(top_srcdir)/mkinstalldirs $(localstatedir)
|
||||
|
||||
dblocation.texi: Makefile
|
||||
echo '@set LOCATE_DB $(LOCATE_DB)' > $@
|
||||
|
||||
SUBDIRS = . testsuite
|
||||
|
||||
dist-hook: findutils-check-manpages
|
||||
|
||||
findutils-check-manpages:
|
||||
$(top_srcdir)/build-aux/man-lint.sh $(srcdir) $(man_MANS)
|
||||
frcode.o code.o locate.o: locatedb.h
|
||||
locate.o: ../lib/fnmatch.h ../lib/getopt.h
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
# Makefile.in generated automatically by automake from Makefile.am.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
datadir = $(prefix)/share
|
||||
sysconfdir = $(prefix)/etc
|
||||
sharedstatedir = $(prefix)/com
|
||||
localstatedir = $(prefix)/var
|
||||
libdir = $(exec_prefix)/lib
|
||||
infodir = $(prefix)/info
|
||||
mandir = $(prefix)/man
|
||||
includedir = $(prefix)/include
|
||||
oldincludedir = /usr/include
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
ALL = ${PROGRAMS} ${LIBPROGRAMS} ${SCRIPTS} ${LIBSCRIPTS} ${LIBFILES}
|
||||
CC = @CC@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
ANSI2KNR = ./ansi2knr
|
||||
|
||||
DEFS = @DEFS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
|
||||
locate_SOURCES = locate.c
|
||||
locate_OBJECTS = locate.o
|
||||
frcode_SOURCES = frcode.c
|
||||
frcode_OBJECTS = frcode.o
|
||||
code_SOURCES = code.c
|
||||
code_OBJECTS = code.o
|
||||
bigram_SOURCES = bigram.c
|
||||
bigram_OBJECTS = bigram.o
|
||||
NROFF = nroff
|
||||
|
||||
SOURCES = locate.c frcode.c code.c bigram.c
|
||||
DIST_CONF = Makefile.am Makefile.in
|
||||
DIST_FILES = $(DIST_CONF) $(SOURCES) $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER)
|
||||
|
||||
# The default database to build and search.
|
||||
LOCATE_DB = $(localstatedir)/locatedb
|
||||
|
||||
PROGRAMS = locate
|
||||
LIBPROGRAMS = frcode code bigram
|
||||
SCRIPTS = updatedb
|
||||
MANS = locate.1 updatedb.1 locatedb.5
|
||||
CONFIG_HEADER = ../config.h
|
||||
|
||||
DIST_OTHER = locatedb.h updatedb.sh
|
||||
CLEANFILES = updatedb
|
||||
|
||||
INCLUDES = -I.. -I$(top_srcdir)/lib -DLOCATE_DB=\"$(LOCATE_DB)\"
|
||||
|
||||
LDADD = ../find/version.o ../lib/libfind.a
|
||||
|
||||
all:: ${ALL}
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $<
|
||||
|
||||
$(locate_OBJECTS): ../config.h
|
||||
$(frcode_OBJECTS): ../config.h
|
||||
$(code_OBJECTS): ../config.h
|
||||
$(bigram_OBJECTS): ../config.h
|
||||
install:: install-programs
|
||||
|
||||
install-programs: $(PROGRAMS) $(SCRIPTS)
|
||||
$(top_srcdir)/mkinstalldirs $(bindir)
|
||||
for p in $(PROGRAMS) $(SCRIPTS); do \
|
||||
$(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
uninstall:: uninstall-programs
|
||||
|
||||
uninstall-programs:
|
||||
for p in $(PROGRAMS) $(SCRIPTS); do \
|
||||
rm -f $(bindir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
install:: install-libprograms
|
||||
|
||||
install-libprograms: $(LIBPROGRAMS) $(LIBSCRIPTS)
|
||||
$(top_srcdir)/mkinstalldirs $(libexecdir)
|
||||
for p in $(LIBPROGRAMS) $(LIBSCRIPTS); do \
|
||||
$(INSTALL_PROGRAM) $$p $(libexecdir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
uninstall:: uninstall-libprograms
|
||||
|
||||
uninstall-libprograms:
|
||||
for p in $(LIBPROGRAMS) $(LIBSCRIPTS); do \
|
||||
rm -f $(libexecdir)/`echo $$p|sed '$(transform)'`; \
|
||||
done
|
||||
|
||||
locate: $(locate_OBJECTS)
|
||||
$(CC) -o $@ $(locate_OBJECTS) $(LDADD) $(LDFLAGS) $(LIBS)
|
||||
|
||||
frcode: $(frcode_OBJECTS)
|
||||
$(CC) -o $@ $(frcode_OBJECTS) $(LDADD) $(LDFLAGS) $(LIBS)
|
||||
|
||||
code: $(code_OBJECTS)
|
||||
$(CC) -o $@ $(code_OBJECTS) $(LDADD) $(LDFLAGS) $(LIBS)
|
||||
|
||||
bigram: $(bigram_OBJECTS)
|
||||
$(CC) -o $@ $(bigram_OBJECTS) $(LDADD) $(LDFLAGS) $(LIBS)
|
||||
|
||||
install:: install-man
|
||||
|
||||
install-man:
|
||||
for man in $(MANS); do \
|
||||
sect=`echo $$man|sed 's%.*\.\([0-9][a-z]*\)$$%\1%'`; \
|
||||
inst=`basename $$man $$sect|sed '$(transform)'`$$sect; \
|
||||
mdir=$(mandir)/man$$sect; \
|
||||
$(top_srcdir)/mkinstalldirs $$mdir; \
|
||||
echo installing $$man as $$mdir/$$inst; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$man $$mdir/$$inst; \
|
||||
cdir=$(mandir)/cat$$sect; \
|
||||
if test -d $$cdir; then \
|
||||
echo formatting $$man as $$cdir/$$inst; \
|
||||
$(NROFF) -man $(srcdir)/$$man > $$cdir/$$inst; \
|
||||
fi; \
|
||||
done
|
||||
|
||||
uninstall:: uninstall-man
|
||||
|
||||
uninstall-man:
|
||||
for man in $(MANS); do \
|
||||
sect=`echo $$man|sed 's%.*\(\.[0-9][a-z]*\)$$%\1%'; \
|
||||
inst=`basename $$man $sect|sed '$(transform)'`.$$sect; \
|
||||
mdir=$(mandir)/man$$sect; \
|
||||
cdir=$(mandir)/cat$$sect; \
|
||||
rm -f $$mdir/$$inst $$cdir/$$inst; \
|
||||
done
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.o core
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f $(PROGRAMS) $(LIBPROGRAMS) $(LIBFILES) $(TEXFILES) $(CLEANFILES)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *.tab.c $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS $(INFOS)
|
||||
|
||||
dist: $(DIST_FILES) $(DIST_DIRS)
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
@for file in $(DIST_FILES); do \
|
||||
echo linking $$file; \
|
||||
ln $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file || \
|
||||
{ echo copying $$file instead; cp -p $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file;}; \
|
||||
done
|
||||
|
||||
check dvi info install uninstall::
|
||||
|
||||
tags:: TAGS
|
||||
|
||||
TAGS::
|
||||
cd $(srcdir); etags $(SOURCES)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
$(PROGRAMS) $(LIBPROGRAMS): ../find/version.o ../lib/libfind.a
|
||||
|
||||
updatedb: updatedb.sh
|
||||
rm -f $@
|
||||
version=`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q $(top_srcdir)/find/version.c`; \
|
||||
find=`echo find|sed '$(transform)'`; \
|
||||
frcode=`echo frcode|sed '$(transform)'`; \
|
||||
bigram=`echo bigram|sed '$(transform)'`; \
|
||||
code=`echo code|sed '$(transform)'`; \
|
||||
sed \
|
||||
-e "s,@bindir@,$(bindir)," \
|
||||
-e "s,@libexecdir@,$(libexecdir)," \
|
||||
-e "s,@LOCATE_DB@,$(LOCATE_DB)," \
|
||||
-e "s,@version@,$$version," \
|
||||
-e "s,@find@,$$find," \
|
||||
-e "s,@frcode@,$$frcode," \
|
||||
-e "s,@bigram@,$$bigram," \
|
||||
-e "s,@code@,$$code," \
|
||||
$(srcdir)/updatedb.sh > $@
|
||||
chmod +x $@
|
||||
|
||||
install::
|
||||
$(top_srcdir)/mkinstalldirs $(localstatedir)
|
||||
|
||||
frcode.o code.o locate.o: locatedb.h
|
||||
locate.o: ../lib/fnmatch.h ../lib/getopt.h
|
||||
+23
-22
@@ -1,19 +1,19 @@
|
||||
/* bigram -- list bigrams for locate
|
||||
Copyright (C) 1994, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Usage: bigram < text > bigrams
|
||||
Use `code' to encode a file using this output.
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined HAVE_STRING_H || defined STDC_HEADERS
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
@@ -43,8 +43,7 @@
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <xalloc.h>
|
||||
#include "closeout.h"
|
||||
char *xmalloc ();
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
@@ -52,7 +51,8 @@ char *program_name;
|
||||
/* Return the length of the longest common prefix of strings S1 and S2. */
|
||||
|
||||
static int
|
||||
prefix_length (char *s1, char *s2)
|
||||
prefix_length (s1, s2)
|
||||
char *s1, *s2;
|
||||
{
|
||||
register char *start;
|
||||
|
||||
@@ -61,8 +61,10 @@ prefix_length (char *s1, char *s2)
|
||||
return s1 - start;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *path; /* The current input entry. */
|
||||
char *oldpath; /* The previous input entry. */
|
||||
@@ -70,17 +72,16 @@ main (int argc, char **argv)
|
||||
int line_len; /* Length of input line. */
|
||||
|
||||
program_name = argv[0];
|
||||
(void) argc;
|
||||
atexit (close_stdout);
|
||||
|
||||
pathsize = oldpathsize = 1026; /* Increased as necessary by getline. */
|
||||
|
||||
pathsize = oldpathsize = 1026; /* Increased as necessary by getstr. */
|
||||
path = xmalloc (pathsize);
|
||||
oldpath = xmalloc (oldpathsize);
|
||||
|
||||
/* Set to empty string, to force the first prefix count to 0. */
|
||||
oldpath[0] = '\0';
|
||||
/* Set to anything not starting with a slash, to force the first
|
||||
prefix count to 0. */
|
||||
strcpy (oldpath, " ");
|
||||
|
||||
while ((line_len = getline (&path, &pathsize, stdin)) > 0)
|
||||
while ((line_len = getstr (&path, &pathsize, stdin, '\n', 0)) > 0)
|
||||
{
|
||||
register int count; /* The prefix length. */
|
||||
register int j; /* Index into input line. */
|
||||
@@ -110,5 +111,5 @@ main (int argc, char **argv)
|
||||
free (path);
|
||||
free (oldpath);
|
||||
|
||||
return 0;
|
||||
exit (0);
|
||||
}
|
||||
|
||||
+47
-120
@@ -1,19 +1,19 @@
|
||||
/* code -- bigram- and front-encode filenames for locate
|
||||
Copyright (C) 1994, 2005, 2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Compress a sorted list.
|
||||
Works with `find' to encode a filename database to save space
|
||||
@@ -37,54 +37,32 @@
|
||||
|
||||
0-28 likeliest differential counts + offset (14) to make nonnegative
|
||||
30 escape code for out-of-range count to follow in next halfword
|
||||
128-255 bigram codes (the 128 most common, as determined by `updatedb')
|
||||
32-127 single character (printable) ASCII remainder
|
||||
128-255 bigram codes (the 128 most common, as determined by `updatedb')
|
||||
32-127 single character (printable) ASCII remainder
|
||||
|
||||
Written by James A. Woods <jwoods@adobe.com>.
|
||||
Modified by David MacKenzie <djm@gnu.org>. */
|
||||
Modified by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#define textdomain(Domain)
|
||||
#define bindtextdomain(Package, Directory)
|
||||
#endif
|
||||
#ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
#else
|
||||
/* See locate.c for explanation as to why not use (String) */
|
||||
# define N_(String) String
|
||||
#endif
|
||||
|
||||
#include "locatedb.h"
|
||||
#include "closeout.h"
|
||||
#include "xalloc.h"
|
||||
#include "gnulib-version.h"
|
||||
#include "progname.h"
|
||||
#include "error.h"
|
||||
#include "findutils-version.h"
|
||||
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
#endif
|
||||
|
||||
char *xmalloc ();
|
||||
|
||||
/* The name this program was run with. */
|
||||
const char *program_name;
|
||||
char *program_name;
|
||||
|
||||
/* The 128 most common bigrams in the file list, padded with NULs
|
||||
if there are fewer. */
|
||||
@@ -93,7 +71,8 @@ static char bigrams[257] = {0};
|
||||
/* Return the offset of PATTERN in STRING, or -1 if not found. */
|
||||
|
||||
static int
|
||||
strindex (char *string, char *pattern)
|
||||
strindex (string, pattern)
|
||||
char *string, *pattern;
|
||||
{
|
||||
register char *s;
|
||||
|
||||
@@ -113,7 +92,8 @@ strindex (char *string, char *pattern)
|
||||
/* Return the length of the longest common prefix of strings S1 and S2. */
|
||||
|
||||
static int
|
||||
prefix_length (char *s1, char *s2)
|
||||
prefix_length (s1, s2)
|
||||
char *s1, *s2;
|
||||
{
|
||||
register char *start;
|
||||
|
||||
@@ -122,41 +102,10 @@ prefix_length (char *s1, char *s2)
|
||||
return s1 - start;
|
||||
}
|
||||
|
||||
extern char *version_string;
|
||||
|
||||
static void
|
||||
usage (FILE *stream)
|
||||
{
|
||||
fprintf (stream, _("\
|
||||
Usage: %s [--version | --help]\n\
|
||||
or %s most_common_bigrams < file-list > locate-database\n"),
|
||||
program_name, program_name);
|
||||
fputs (_("\nReport bugs to <bug-findutils@gnu.org>.\n"), stream);
|
||||
}
|
||||
|
||||
|
||||
static void inerr (const char *filename) ATTRIBUTE_NORETURN;
|
||||
static void outerr(void) ATTRIBUTE_NORETURN;
|
||||
|
||||
static void
|
||||
inerr(const char *filename)
|
||||
{
|
||||
error(1, errno, "%s", filename);
|
||||
/*NOTREACHED*/
|
||||
abort();
|
||||
}
|
||||
|
||||
static void
|
||||
outerr(void)
|
||||
{
|
||||
error(1, errno, _("write error"));
|
||||
/*NOTREACHED*/
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *path; /* The current input entry. */
|
||||
char *oldpath; /* The previous input entry. */
|
||||
@@ -167,56 +116,41 @@ main (int argc, char **argv)
|
||||
FILE *fp; /* Most common bigrams file. */
|
||||
int line_len; /* Length of input line. */
|
||||
|
||||
set_program_name(argv[0]);
|
||||
atexit (close_stdout);
|
||||
program_name = argv[0];
|
||||
|
||||
bigram[2] = '\0';
|
||||
|
||||
if (argc != 2)
|
||||
{
|
||||
usage(stderr);
|
||||
return 2;
|
||||
fprintf (stderr, "Usage: %s most_common_bigrams < list > coded_list\n",
|
||||
argv[0]);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
if (0 == strcmp(argv[1], "--help"))
|
||||
{
|
||||
usage(stdout);
|
||||
return 0;
|
||||
}
|
||||
else if (0 == strcmp(argv[1], "--version"))
|
||||
{
|
||||
display_findutils_version("code");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
fp = fopen (argv[1], "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
fprintf (stderr, "%s: ", argv[0]);
|
||||
perror (argv[1]);
|
||||
return 1;
|
||||
exit (1);
|
||||
}
|
||||
|
||||
pathsize = oldpathsize = 1026; /* Increased as necessary by getline. */
|
||||
|
||||
pathsize = oldpathsize = 1026; /* Increased as necessary by getstr. */
|
||||
path = xmalloc (pathsize);
|
||||
oldpath = xmalloc (oldpathsize);
|
||||
|
||||
/* Set to empty string, to force the first prefix count to 0. */
|
||||
oldpath[0] = '\0';
|
||||
/* Set to anything not starting with a slash, to force the first
|
||||
prefix count to 0. */
|
||||
strcpy (oldpath, " ");
|
||||
oldcount = 0;
|
||||
|
||||
/* Copy the list of most common bigrams to the output,
|
||||
padding with NULs if there are <128 of them. */
|
||||
if (NULL == fgets (bigrams, 257, fp))
|
||||
inerr(argv[1]);
|
||||
|
||||
if (256 != fwrite (bigrams, 1, 256, stdout))
|
||||
outerr();
|
||||
fgets (bigrams, 257, fp);
|
||||
fwrite (bigrams, 1, 256, stdout);
|
||||
fclose (fp);
|
||||
|
||||
if (EOF == fclose (fp))
|
||||
inerr(argv[1]);
|
||||
|
||||
while ((line_len = getline (&path, &pathsize, stdin)) > 0)
|
||||
while ((line_len = getstr (&path, &pathsize, stdin, '\n', 0)) > 0)
|
||||
{
|
||||
char *pp;
|
||||
|
||||
@@ -225,7 +159,8 @@ main (int argc, char **argv)
|
||||
/* Squelch unprintable chars in path so as not to botch decoding. */
|
||||
for (pp = path; *pp != '\0'; pp++)
|
||||
{
|
||||
if (!(*pp >= 040 && *pp < 0177))
|
||||
*pp &= 0177;
|
||||
if (*pp < 040 || *pp == 0177)
|
||||
*pp = '?';
|
||||
}
|
||||
|
||||
@@ -236,19 +171,11 @@ main (int argc, char **argv)
|
||||
otherwise, two bytes plus a marker noting that fact. */
|
||||
if (diffcount < -LOCATEDB_OLD_OFFSET || diffcount > LOCATEDB_OLD_OFFSET)
|
||||
{
|
||||
if (EOF ==- putc (LOCATEDB_OLD_ESCAPE, stdout))
|
||||
outerr ();
|
||||
|
||||
if (!putword (stdout,
|
||||
diffcount+LOCATEDB_OLD_OFFSET,
|
||||
GetwordEndianStateNative))
|
||||
outerr ();
|
||||
putc (LOCATEDB_OLD_ESCAPE, stdout);
|
||||
putw (diffcount + LOCATEDB_OLD_OFFSET, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EOF == putc (diffcount + LOCATEDB_OLD_OFFSET, stdout))
|
||||
outerr ();
|
||||
}
|
||||
putc (diffcount + LOCATEDB_OLD_OFFSET, stdout);
|
||||
|
||||
/* Look for bigrams in the remainder of the path. */
|
||||
for (pp = path + count; *pp != '\0'; pp += 2)
|
||||
@@ -283,5 +210,5 @@ main (int argc, char **argv)
|
||||
free (path);
|
||||
free (oldpath);
|
||||
|
||||
return 0;
|
||||
exit (0);
|
||||
}
|
||||
|
||||
+58
-251
@@ -1,10 +1,10 @@
|
||||
/* frcode -- front-compress a sorted list
|
||||
Copyright (C) 1994,2005,2006,2007 Free Software Foundation, Inc.
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
the Free Software Foundation; either version 2, 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
|
||||
@@ -12,21 +12,22 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Usage: frcode < sorted-list > compressed-list
|
||||
|
||||
Uses front compression (also known as incremental encoding);
|
||||
see ";login:", March 1983, p. 8.
|
||||
|
||||
The input is a sorted list of NUL-terminated strings (or
|
||||
newline-terminated if the -0 option is not given).
|
||||
The input is a sorted list of NUL-terminated strings.
|
||||
(FIXME newline-terminated, until we figure out how to sort
|
||||
NUL-terminated strings.)
|
||||
|
||||
The output entries are in the same order as the input; each entry
|
||||
consists of a signed offset-differential count byte (the additional
|
||||
number of characters of prefix of the preceding entry to use beyond
|
||||
the number that the preceding entry is using of its predecessor),
|
||||
The output entries are in the same order as the input;
|
||||
each entry consists of an offset-differential count byte
|
||||
(the additional number of characters of prefix of the preceding entry to
|
||||
use beyond the number that the preceding entry is using of its predecessor),
|
||||
followed by a null-terminated ASCII remainder.
|
||||
|
||||
If the offset-differential count is larger than can be stored
|
||||
@@ -58,21 +59,13 @@
|
||||
(6 = 14 - 8, and -9 = 5 - 14)
|
||||
|
||||
Written by James A. Woods <jwoods@adobe.com>.
|
||||
Modified by David MacKenzie <djm@gnu.org>.
|
||||
Modified by James Youngman <jay@gnu.org>.
|
||||
*/
|
||||
Modified by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if defined HAVE_STRING_H || defined STDC_HEADERS
|
||||
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
@@ -82,282 +75,96 @@
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# define _(Text) Text
|
||||
#define textdomain(Domain)
|
||||
#define bindtextdomain(Package, Directory)
|
||||
#endif
|
||||
#ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
#else
|
||||
/* We used to use (String) instead of just String, but apparently ISO C
|
||||
* doesn't allow this (at least, that's what HP said when someone reported
|
||||
* this as a compiler bug). This is HP case number 1205608192. See
|
||||
* also http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11250 (which references
|
||||
* ANSI 3.5.7p14-15). The Intel icc compiler also rejects constructs
|
||||
* like: static const char buf[] = ("string");
|
||||
*/
|
||||
# define N_(String) String
|
||||
#endif
|
||||
|
||||
|
||||
#include "locatedb.h"
|
||||
#include <getopt.h>
|
||||
#include "error.h"
|
||||
#include "closeout.h"
|
||||
#include "findutils-version.h"
|
||||
|
||||
char *xmalloc PARAMS((size_t));
|
||||
char *xmalloc ();
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
/* Write out a 16-bit int, high byte first (network byte order).
|
||||
* Return true iff all went well.
|
||||
*/
|
||||
static int
|
||||
put_short (int c, FILE *fp)
|
||||
/* Write out a 16-bit int, high byte first (network byte order). */
|
||||
|
||||
static void
|
||||
put_short (c, fp)
|
||||
int c;
|
||||
FILE *fp;
|
||||
{
|
||||
/* XXX: The value of c may be negative. ANSI C 1989 (section 6.3.7)
|
||||
* indicates that the result of shifting a negative value right is
|
||||
* implementation defined.
|
||||
*/
|
||||
assert (c <= SHRT_MAX);
|
||||
assert (c >= SHRT_MIN);
|
||||
return (putc (c >> 8, fp) != EOF) && (putc (c, fp) != EOF);
|
||||
putc (c >> 8, fp);
|
||||
putc (c, fp);
|
||||
}
|
||||
|
||||
/* Return the length of the longest common prefix of strings S1 and S2. */
|
||||
|
||||
static int
|
||||
prefix_length (char *s1, char *s2)
|
||||
prefix_length (s1, s2)
|
||||
char *s1, *s2;
|
||||
{
|
||||
register char *start;
|
||||
int limit = INT_MAX;
|
||||
|
||||
for (start = s1; *s1 == *s2 && *s1 != '\0'; s1++, s2++)
|
||||
{
|
||||
/* Don't emit a prefix length that will not fit into
|
||||
* our return type.
|
||||
*/
|
||||
if (0 == --limit)
|
||||
break;
|
||||
}
|
||||
;
|
||||
return s1 - start;
|
||||
}
|
||||
|
||||
static struct option const longopts[] =
|
||||
{
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"version", no_argument, NULL, 'v'},
|
||||
{"null", no_argument, NULL, '0'},
|
||||
{NULL, no_argument, NULL, 0}
|
||||
};
|
||||
|
||||
extern char *version_string;
|
||||
|
||||
/* The name this program was run with. */
|
||||
char *program_name;
|
||||
|
||||
|
||||
static void
|
||||
usage (FILE *stream)
|
||||
{
|
||||
fprintf (stream,
|
||||
_("Usage: %s [-0 | --null] [--version] [--help]\n"),
|
||||
program_name);
|
||||
fputs (_("\nReport bugs to <bug-findutils@gnu.org>.\n"), stream);
|
||||
}
|
||||
|
||||
static long
|
||||
get_seclevel(char *s)
|
||||
{
|
||||
long result;
|
||||
char *p;
|
||||
|
||||
/* Reset errno in oreder to be able to distinguish LONG_MAX/LONG_MIN
|
||||
* from values whichare actually out of range
|
||||
*/
|
||||
errno = 0;
|
||||
|
||||
result = strtol(s, &p, 10);
|
||||
if ((0==result) && (p == optarg))
|
||||
{
|
||||
error(1, 0, _("You need to specify a security level as a decimal integer."));
|
||||
/*NOTREACHED*/
|
||||
return -1;
|
||||
}
|
||||
else if ((LONG_MIN==result || LONG_MAX==result) && errno)
|
||||
|
||||
{
|
||||
error(1, 0, _("Security level %s is outside the convertible range."), s);
|
||||
/*NOTREACHED*/
|
||||
return -1;
|
||||
}
|
||||
else if (*p)
|
||||
{
|
||||
/* Some suffix exists */
|
||||
error(1, 0, _("Security level %s has unexpected suffix %s."), s, p);
|
||||
/*NOTREACHED*/
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
outerr(void)
|
||||
{
|
||||
/* Issue the same error message as closeout() would. */
|
||||
error(1, errno, _("write error"));
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
void
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *path; /* The current input entry. */
|
||||
char *oldpath; /* The previous input entry. */
|
||||
size_t pathsize, oldpathsize; /* Amounts allocated for them. */
|
||||
int count, oldcount, diffcount; /* Their prefix lengths & the difference. */
|
||||
int line_len; /* Length of input line. */
|
||||
int delimiter = '\n';
|
||||
int optc;
|
||||
int slocate_compat = 0;
|
||||
long slocate_seclevel = 0L;
|
||||
|
||||
program_name = argv[0];
|
||||
if (!program_name)
|
||||
program_name = "frcode";
|
||||
atexit (close_stdout);
|
||||
|
||||
pathsize = oldpathsize = 1026; /* Increased as necessary by getline. */
|
||||
pathsize = oldpathsize = 1026; /* Increased as necessary by getstr. */
|
||||
path = xmalloc (pathsize);
|
||||
oldpath = xmalloc (oldpathsize);
|
||||
|
||||
oldpath[0] = 0;
|
||||
/* Set to anything not starting with a slash, to force the first
|
||||
prefix count to 0. */
|
||||
strcpy (oldpath, " ");
|
||||
oldcount = 0;
|
||||
|
||||
fwrite (LOCATEDB_MAGIC, sizeof (LOCATEDB_MAGIC), 1, stdout);
|
||||
|
||||
while ((optc = getopt_long (argc, argv, "hv0S:", longopts, (int *) 0)) != -1)
|
||||
switch (optc)
|
||||
{
|
||||
case '0':
|
||||
delimiter = 0;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
slocate_compat = 1;
|
||||
slocate_seclevel = get_seclevel(optarg);
|
||||
if (slocate_seclevel < 0 || slocate_seclevel > 1)
|
||||
{
|
||||
error(1, 0,
|
||||
_("slocate security level %ld is unsupported."),
|
||||
slocate_seclevel);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage (stdout);
|
||||
return 0;
|
||||
|
||||
case 'v':
|
||||
display_findutils_version("frcode");
|
||||
return 0;
|
||||
|
||||
default:
|
||||
usage (stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We expect to have no arguments. */
|
||||
if (optind != argc)
|
||||
{
|
||||
usage (stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (slocate_compat)
|
||||
{
|
||||
fputc(slocate_seclevel ? '1' : '0', stdout);
|
||||
fputc(0, stdout);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* GNU LOCATE02 format */
|
||||
if (fwrite (LOCATEDB_MAGIC, 1, sizeof (LOCATEDB_MAGIC), stdout)
|
||||
!= sizeof(LOCATEDB_MAGIC))
|
||||
{
|
||||
error(1, errno, _("Failed to write to standard output"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while ((line_len = getdelim (&path, &pathsize, delimiter, stdin)) > 0)
|
||||
/* FIXME temporary: change the \n to \0 when we figure out how to sort
|
||||
null-terminated strings. */
|
||||
while ((line_len = getstr (&path, &pathsize, stdin, '\n', 0)) > 0)
|
||||
{
|
||||
path[line_len - 1] = '\0'; /* FIXME temporary: nuke the newline. */
|
||||
|
||||
count = prefix_length (oldpath, path);
|
||||
diffcount = count - oldcount;
|
||||
if ( (diffcount > SHRT_MAX) || (diffcount < SHRT_MIN) )
|
||||
{
|
||||
/* We do this to prevent overflow of the value we
|
||||
* write with put_short()
|
||||
*/
|
||||
count = 0;
|
||||
diffcount = (-oldcount);
|
||||
}
|
||||
oldcount = count;
|
||||
|
||||
if (slocate_compat)
|
||||
/* If the difference is small, it fits in one byte;
|
||||
otherwise, two bytes plus a marker noting that fact. */
|
||||
if (diffcount < -127 || diffcount > 127)
|
||||
{
|
||||
/* Emit no count for the first pathname. */
|
||||
slocate_compat = 0;
|
||||
putc (LOCATEDB_ESCAPE, stdout);
|
||||
put_short (diffcount, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the difference is small, it fits in one byte;
|
||||
otherwise, two bytes plus a marker noting that fact. */
|
||||
if (diffcount < LOCATEDB_ONEBYTE_MIN
|
||||
|| diffcount > LOCATEDB_ONEBYTE_MAX)
|
||||
{
|
||||
if (EOF == putc (LOCATEDB_ESCAPE, stdout))
|
||||
outerr();
|
||||
if (!put_short (diffcount, stdout))
|
||||
outerr();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EOF == putc (diffcount, stdout))
|
||||
outerr();
|
||||
}
|
||||
}
|
||||
putc (diffcount, stdout);
|
||||
|
||||
if ( (EOF == fputs (path + count, stdout))
|
||||
|| (EOF == putc ('\0', stdout)))
|
||||
{
|
||||
outerr();
|
||||
}
|
||||
fputs (path + count, stdout);
|
||||
putc ('\0', stdout);
|
||||
|
||||
if (1)
|
||||
{
|
||||
/* Swap path and oldpath and their sizes. */
|
||||
char *tmppath = oldpath;
|
||||
size_t tmppathsize = oldpathsize;
|
||||
oldpath = path;
|
||||
oldpathsize = pathsize;
|
||||
path = tmppath;
|
||||
pathsize = tmppathsize;
|
||||
}
|
||||
{
|
||||
/* Swap path and oldpath and their sizes. */
|
||||
char *tmppath = oldpath;
|
||||
size_t tmppathsize = oldpathsize;
|
||||
oldpath = path;
|
||||
oldpathsize = pathsize;
|
||||
path = tmppath;
|
||||
pathsize = tmppathsize;
|
||||
}
|
||||
}
|
||||
|
||||
free (path);
|
||||
free (oldpath);
|
||||
|
||||
return 0;
|
||||
exit (0);
|
||||
}
|
||||
|
||||
+8
-189
@@ -1,13 +1,9 @@
|
||||
.TH LOCATE 1 \" -*- nroff -*-
|
||||
.TH LOCATE 1L \" -*- nroff -*-
|
||||
.SH NAME
|
||||
locate \- list files in databases that match a pattern
|
||||
.SH SYNOPSIS
|
||||
.B locate
|
||||
[\-d path | \-\-database=path] [\-e | \-E | \-\-[non\-]existing] [\-i
|
||||
| \-\-ignore-case] [\-0 | \-\-null] [\-c | \-\-count] [\-w | \-\-wholename]
|
||||
|\-b | \-\-basename] [\-l N | \-\-limit=N] [\-S | \-\-statistics] [\-r
|
||||
| \-\-regex ] [\-\-max-database-age D] [\-P | \-H | \-\-nofollow] [\-L
|
||||
| \-\-follow] [\-\-version] [\-A | \-\-all] [\-p | \-\-print] [\-\-help] pattern...
|
||||
[\-d path] [\-\-database=path] [\-\-version] [\-\-help] pattern...
|
||||
.SH DESCRIPTION
|
||||
This manual page
|
||||
documents the GNU version of
|
||||
@@ -38,52 +34,22 @@ The file name databases contain lists of files that were on the system
|
||||
when the databases were last updated. The system administrator can
|
||||
choose the file name of the default database, the frequency with which
|
||||
the databases are updated, and the directories for which they contain
|
||||
entries; see \fBupdatedb\fP(1).
|
||||
.P
|
||||
If
|
||||
.BR locate 's
|
||||
output is going to a terminal, unusual characters in the output are
|
||||
escaped in the same way as for the \-print action of the
|
||||
.B find
|
||||
command. If the output is not going to a terminal, file names are
|
||||
printed exactly as-is.
|
||||
|
||||
entries; see \fBupdatedb\fP(1L).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I "\-0, \-\-null"
|
||||
Use ASCII NUL as a separator, instead of newline.
|
||||
.TP
|
||||
.I "\-A, \-\-all"
|
||||
Print only names which match all non-option arguments, not those matching
|
||||
one or more non-option arguments.
|
||||
.TP
|
||||
.I "\-b, \-\-basename"
|
||||
Results are considered to match if the pattern specified matches the
|
||||
final component of the name of a file as listed in the database.
|
||||
This final component is usually referred to as the `base name'.
|
||||
.TP
|
||||
.I "\-c, \-\-count"
|
||||
Instead of printing the matched filenames, just print the total
|
||||
number of matches we found, unless \-\-\fIprint\fP (\-p) is also present.
|
||||
.TP
|
||||
.I "\-d \fIpath\fP, \-\-database=\fIpath\fP"
|
||||
Instead of searching the default file name database, search the file
|
||||
name databases in \fIpath\fP, which is a colon-separated list of
|
||||
database file names. You can also use the environment variable
|
||||
.B LOCATE_PATH
|
||||
to set the list of database files to search.
|
||||
The option overrides the environment variable if both are used. Empty
|
||||
elements in the path are taken to be synonyms for the file name of the
|
||||
default database.
|
||||
A database can be supplied on stdin, using `\-' as an element
|
||||
of \fIpath\fP. If more than one element of \fIpath\fP is `\-',
|
||||
later instances are ignored (and a warning message is printed).
|
||||
.IP
|
||||
The option overrides the environment variable if both are used.
|
||||
.P
|
||||
The file name database format changed starting with GNU
|
||||
.B find
|
||||
and
|
||||
.B locate
|
||||
version 4.0 to allow machines with different byte orderings to share
|
||||
version 4.0 to allow machines with diffent byte orderings to share
|
||||
the databases. This version of
|
||||
.B locate
|
||||
can automatically recognize and read databases produced for older
|
||||
@@ -93,167 +59,20 @@ or Unix versions of
|
||||
.B locate
|
||||
or
|
||||
.BR find .
|
||||
Support for the old locate database format will be discontinued in a
|
||||
future release.
|
||||
.TP
|
||||
.I "\-e, \-\-existing"
|
||||
Only print out such names that currently exist (instead of such names
|
||||
that existed when the database was created).
|
||||
Note that this may slow down the program a lot, if there are many matches
|
||||
in the database. If you are using this option within a program,
|
||||
please note that it is possible for the file to be deleted after
|
||||
.B locate
|
||||
has checked that it exists, but before you use it.
|
||||
.TP
|
||||
.I "\-E, \-\-non\-existing"
|
||||
Only print out such names that currently do not exist (instead of such names
|
||||
that existed when the database was created).
|
||||
Note that this may slow down the program a lot, if there are many matches
|
||||
in the database.
|
||||
.TP
|
||||
.I "\-\-help"
|
||||
Print a summary of the options to
|
||||
.B locate
|
||||
and exit.
|
||||
.TP
|
||||
.I "\-i, \-\-ignore-case"
|
||||
Ignore case distinctions in both the pattern and the file names.
|
||||
.TP
|
||||
.I "\-l N, \-\-limit=N"
|
||||
Limit the number of matches to N. If a limit is set via this option,
|
||||
the number of results printed for the \-c option will never be larger
|
||||
than this number.
|
||||
.TP
|
||||
.I "\-L, \-\-follow"
|
||||
If testing for the existence of files (with the \-e or \-E options),
|
||||
consider broken symbolic links to be non-existing. This is the default.
|
||||
.TP
|
||||
.I "\-\-max-database-age D"
|
||||
Normally,
|
||||
.B locate
|
||||
will issue a warning message when it searches a database which is more
|
||||
than 8 days old. This option changes that value to something other
|
||||
than 8. The effect of specifying a negative value is undefined.
|
||||
.TP
|
||||
.I "\-m, \-\-mmap"
|
||||
Accepted but does nothing, for compatibility with BSD
|
||||
.BR locate .
|
||||
.TP
|
||||
.I "\-P, \-H, \-\-nofollow"
|
||||
If testing for the existence of files (with the \-e or \-E options), treat
|
||||
broken symbolic links as if they were existing files. The \-H
|
||||
form of this option is provided purely for similarity with
|
||||
.BR find ;
|
||||
the use of \-P is recommended over \-H.
|
||||
.TP
|
||||
.I "\-p, \-\-print"
|
||||
Print search results when they normally would not, because of the presence
|
||||
of \-\-statistics (\-S) or \-\-count (\-c).
|
||||
.TP
|
||||
.I "\-r, \-\-regex "
|
||||
The pattern specified on the command line is understood to be a
|
||||
regular expression, as opposed to a glob pattern. The Regular
|
||||
expressions work in the same was as in
|
||||
.B emacs
|
||||
and
|
||||
.BR find ,
|
||||
except for the fact that "." will match a newline.
|
||||
Filenames whose full paths match the specified regular expression are
|
||||
printed (or, in the case of the \-c option, counted). If you wish to
|
||||
anchor your regular expression at the ends of the full path name, then
|
||||
as is usual with regular expressions, you should use the characters ^
|
||||
and $ to signify this.
|
||||
.TP
|
||||
.I "\-s, \-\-stdio"
|
||||
Accepted but does nothing, for compatibility with BSD
|
||||
.BR locate .
|
||||
.TP
|
||||
.I "\-S, \-\-statistics"
|
||||
Print various statistics about each locate database and then exit
|
||||
without performing a search, unless non-option arguments are given.
|
||||
For compatibility with BSD, \-S is accepted as a synonym
|
||||
for \-\-statistics. However, the ouptut of
|
||||
.B locate \-S
|
||||
is different for the GNU and BSD implementations of
|
||||
.BR locate .
|
||||
.TP
|
||||
.I "\-\-version"
|
||||
Print the version number of
|
||||
.B locate
|
||||
and exit.
|
||||
.TP
|
||||
.I "\-w, \-\-wholename"
|
||||
Match against the whole name of the file as listed in the database.
|
||||
This is the default.
|
||||
.SH ENVIRONMENT
|
||||
.TP
|
||||
.B LOCATE_PATH
|
||||
Colon-separated list of databases to search. If the value has a
|
||||
leading or trailing colon, or has two colons in a row, you may get
|
||||
results that vary between different versions of
|
||||
.BR locate .
|
||||
|
||||
Colon-separated list of databases to search.
|
||||
.SH "SEE ALSO"
|
||||
\fBfind\fP(1), \fBlocatedb\fP(5), \fBupdatedb\fP(1), \fBxargs\fP(1),
|
||||
\fBglob\fP(3),
|
||||
\fBfind\fP(1L), \fBlocatedb\fP(5L), \fBupdatedb\fP(1L), \fBxargs\fP(1L)
|
||||
\fBFinding Files\fP (on-line in Info, or printed)
|
||||
.SH "HISTORY"
|
||||
The
|
||||
.B locate
|
||||
program started life as the BSD fast find program, contributed to BSD
|
||||
by James A. Woods. This was described by his paper
|
||||
.I Finding Files Fast
|
||||
which was published in Usenix
|
||||
.IR ;login: ,
|
||||
Vol 8, No 1, February/March, 1983, pp. 8-10. When the
|
||||
.B find
|
||||
program began to assume a default
|
||||
.B -print
|
||||
action if no action was specified, this changed the interpretation of
|
||||
.B find
|
||||
.BR pattern .
|
||||
The BSD developers therefore moved the fast find functionality into
|
||||
.BR locate .
|
||||
The GNU implementation of
|
||||
.B locate
|
||||
appears to be derived from the same code.
|
||||
.P
|
||||
Significant changes to
|
||||
.B locate
|
||||
in reverse order:
|
||||
.TS
|
||||
tab(|);
|
||||
LL.
|
||||
4.3.7 | Byte-order independent support for old database format
|
||||
4.3.3 | locate \fI\-i\fR supports multi-byte characters correctly
|
||||
| Introduced \fI\-\-max_db_age\fR
|
||||
4.3.2 | Support for the slocate database format
|
||||
4.2.22| Introduced the \fI\-\-all\fR option
|
||||
4.2.15| Introduced the \fI\-\-regex\fR option
|
||||
4.2.14| Introduced options \fI\-L, \-P, \-H\fR
|
||||
4.2.12| Empty items in \fBLOCATE_PATH\fR now indicate the default database
|
||||
4.2.11| Introduced the \fI\-\-statistics\fR option
|
||||
4.2.4 | Introduced \fI\-\-count\fR and \fI\-\-limit\fR
|
||||
4.2.0 | Glob characters cause matching against the whole file name
|
||||
4.0 | Introduced the LOCATE02 database format
|
||||
3.7 | Locate can search multiple databases
|
||||
.TE
|
||||
.SH "BUGS"
|
||||
.P
|
||||
The locate database correctly handles filenames containing newlines,
|
||||
but only if the system's sort command has a working
|
||||
\-z
|
||||
option. If you suspect that
|
||||
.B locate
|
||||
may need to return filenames containing newlines, consider using its
|
||||
.I \-\-null
|
||||
option.
|
||||
.P
|
||||
The best way to report a bug is to use the form at
|
||||
http://savannah.gnu.org/bugs/?group=findutils.
|
||||
The reason for this is that you will then be able to track progress in
|
||||
fixing the problem. Other comments about \fBlocate\fP(1) and about
|
||||
the findutils package in general can be sent to the
|
||||
.I bug-findutils
|
||||
mailing list. To join the list, send email to
|
||||
.IR bug-findutils-request@gnu.org .
|
||||
|
||||
+269
-1808
File diff suppressed because it is too large
Load Diff
+15
-62
@@ -1,4 +1,4 @@
|
||||
.TH LOCATEDB 5 \" -*- nroff -*-
|
||||
.TH LOCATEDB 5L \" -*- nroff -*-
|
||||
.SH NAME
|
||||
locatedb \- front-compressed file name database
|
||||
.SH DESCRIPTION
|
||||
@@ -10,39 +10,31 @@ particular directory trees when the databases were last updated.
|
||||
.P
|
||||
There can be multiple databases. Users can select which databases
|
||||
\fBlocate\fP searches using an environment variable or command line
|
||||
option; see \fBlocate\fP(1). The system administrator can choose the
|
||||
option; see \fBlocate\fP(1L). The system administrator can choose the
|
||||
file name of the default database, the frequency with which the
|
||||
databases are updated, and the directories for which they contain
|
||||
entries. Normally, file name databases are updated by running the
|
||||
\fBupdatedb\fP program periodically, typically nightly; see
|
||||
\fBupdatedb\fP(1).
|
||||
|
||||
.SH GNU LOCATE02 database format
|
||||
This is the default format of databases produced by
|
||||
.BR updatedb .
|
||||
The
|
||||
.B updatedb
|
||||
program runs
|
||||
.B frcode
|
||||
to compress the list of file names using front-compression, which
|
||||
reduces the database size by a factor of 4 to 5. Front-compression
|
||||
(also known as incremental encoding) works as follows.
|
||||
\fBupdatedb\fP(1L).
|
||||
.P
|
||||
\fBupdatedb\fP runs a program called \fBfrcode\fP to compress the list
|
||||
of file names using front-compression, which reduces
|
||||
the database size by a factor of 4 to 5. Front-compression (also
|
||||
known as incremental encoding) works as follows.
|
||||
.P
|
||||
The database entries are a sorted list (case-insensitively, for users'
|
||||
convenience). Since the list is sorted, each entry is likely to share
|
||||
a prefix (initial string) with the previous entry. Each database
|
||||
entry begins with an signed offset-differential count byte, which is
|
||||
the additional number of characters of prefix of the preceding entry
|
||||
to use beyond the number that the preceding entry is using of its
|
||||
entry begins with an offset-differential count byte, which is the
|
||||
additional number of characters of prefix of the preceding entry to
|
||||
use beyond the number that the preceding entry is using of its
|
||||
predecessor. (The counts can be negative.) Following the count is a
|
||||
null-terminated ASCII remainder \(em the part of the name that follows
|
||||
the shared prefix.
|
||||
.P
|
||||
If the offset-differential count is larger than can be stored in a
|
||||
signed byte (+/\-127), the byte has the value 0x80 (binary 10000000)
|
||||
and the actual count follows in a 2-byte word, with the high byte
|
||||
first (network byte order). This count can also be negative (the sign
|
||||
bit being in the first of the two bytes).
|
||||
byte (+/\-127), the byte has the value 0x80 and the count follows in a
|
||||
2-byte word, with the high byte first (network byte order).
|
||||
.P
|
||||
Every database begins with a dummy entry for a file called `LOCATE02',
|
||||
which \fBlocate\fP checks for to ensure that the database file has the
|
||||
@@ -51,37 +43,8 @@ correct format; it ignores the entry in doing the search.
|
||||
Databases can not be concatenated together, even if the first
|
||||
(dummy) entry is trimmed from all but the first database. This
|
||||
is because the offset-differential count in the first entry of the
|
||||
second and following databases will be wrong.
|
||||
second and following databases will be wrong.
|
||||
.P
|
||||
In the future, the data within the locate database may not be sorted
|
||||
in any particular order. To obtain sorted results, pipe the output of
|
||||
.B locate
|
||||
through
|
||||
.BR "sort -f" .
|
||||
.SH slocate database format
|
||||
The
|
||||
.B slocate
|
||||
program uses a database format similar to, but not quite the same as,
|
||||
GNU
|
||||
.BR locate .
|
||||
The first byte of the database specifies its
|
||||
.I security
|
||||
.IR level .
|
||||
If the security level is 0,
|
||||
.B slocate
|
||||
will read, match and print filenames on the basis of the information
|
||||
in the database only. However, if the security level byte is 1,
|
||||
.B slocate
|
||||
omits entries from its output if the invoking user is unable to access
|
||||
them. The second byte of the database is zero. The second byte is
|
||||
followed by the first database entry. The first entry in the database
|
||||
is not preceded by any differential count or dummy entry. Instead
|
||||
the differential count for the first item is assumed to be zero.
|
||||
.P
|
||||
Starting with the second entry (if any) in the database, data is
|
||||
interpreted as for the GNU LOCATE02 format.
|
||||
|
||||
.SH Old Locate Database format
|
||||
There is also an old database format, used by Unix
|
||||
.B locate
|
||||
and
|
||||
@@ -139,15 +102,5 @@ and count bytes made printable:
|
||||
(6 = 14 \- 8, and \-9 = 5 \- 14)
|
||||
.fi
|
||||
.SH "SEE ALSO"
|
||||
\fBfind\fP(1), \fBlocate\fP(1), \fBlocatedb\fP(5), \fBxargs\fP(1),
|
||||
\fBfind\fP(1L), \fBlocate\fP(1L), \fBlocatedb\fP(5L), \fBxargs\fP(1L)
|
||||
\fBFinding Files\fP (on-line in Info, or printed)
|
||||
.SH "BUGS"
|
||||
.P
|
||||
The best way to report a bug is to use the form at
|
||||
http://savannah.gnu.org/bugs/?group=findutils.
|
||||
The reason for this is that you will then be able to track progress in
|
||||
fixing the problem. Other comments about \fBlocate\fP(1) and about
|
||||
the findutils package in general can be sent to the
|
||||
.I bug-findutils
|
||||
mailing list. To join the list, send email to
|
||||
.IR bug-findutils-request@gnu.org .
|
||||
|
||||
+7
-45
@@ -1,19 +1,19 @@
|
||||
/* locatedb.h -- declarations for the locate database
|
||||
Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
the Free Software Foundation; either version 2, 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/>.
|
||||
*/
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _LOCATEDB_H
|
||||
#define _LOCATEDB_H 1
|
||||
@@ -30,19 +30,6 @@
|
||||
This value (which is -128) indicates that the difference is
|
||||
too large to fit into one byte, and a two-byte integer follows. */
|
||||
#define LOCATEDB_ESCAPE 0x80
|
||||
#define LOCATEDB_ONEBYTE_MAX (127)
|
||||
#define LOCATEDB_ONEBYTE_MIN (-127)
|
||||
|
||||
|
||||
/* If it is ever possible to try to encode LOCATEDB_MAGIC as a
|
||||
* single-byte offset, then an unfortunate length of common prefix
|
||||
* will produce a spurious escape character, desynchronising the data
|
||||
* stream. We use a compile-time check in the preprocessor to prevent
|
||||
* this.
|
||||
*/
|
||||
#if LOCATEDB_ESCAPE <= LOCATEDB_ONEBYTE_MAX
|
||||
#error "You have a bad combination of LOCATEDB_ESCAPE and LOCATEDB_ONEBYTE_MAX, see above"
|
||||
#endif
|
||||
|
||||
/* These are used for old, bigram-encoded databases: */
|
||||
|
||||
@@ -52,29 +39,4 @@
|
||||
/* Offset added to differential counts to encode them as positive numbers. */
|
||||
#define LOCATEDB_OLD_OFFSET 14
|
||||
|
||||
# ifndef PARAMS
|
||||
# if defined PROTOTYPES || (defined __STDC__ && __STDC__)
|
||||
# define PARAMS(Args) Args
|
||||
# else
|
||||
# define PARAMS(Args) ()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GetwordEndianStateInitial = 0,
|
||||
GetwordEndianStateNative = 1,
|
||||
GetwordEndianStateSwab = 2
|
||||
} GetwordEndianState;
|
||||
|
||||
int getword (FILE *fp, const char *filename,
|
||||
size_t minvalue, size_t maxvalue,
|
||||
GetwordEndianState *endian_state_flag);
|
||||
|
||||
bool putword (FILE *fp, int word,
|
||||
GetwordEndianState endian_state_flag);
|
||||
|
||||
|
||||
#define SLOCATE_DB_MAGIC_LEN 2
|
||||
|
||||
#endif /* !_LOCATEDB_H */
|
||||
|
||||
+7
-73
@@ -1,4 +1,4 @@
|
||||
.TH UPDATEDB 1 \" -*- nroff -*-
|
||||
.TH UPDATEDB 1L \" -*- nroff -*-
|
||||
.SH NAME
|
||||
updatedb \- update a file name database
|
||||
.SH SYNOPSIS
|
||||
@@ -23,14 +23,14 @@ the root of each filesystem, containing the entries for that filesystem.
|
||||
is then run for each filesystem on the fileserver where that
|
||||
filesystem is on a local disk, to prevent thrashing the network.
|
||||
Users can select which databases \fBlocate\fP searches using an
|
||||
environment variable or command line option; see \fBlocate\fP(1).
|
||||
environment variable or command line option; see \fBlocate\fP(1L).
|
||||
Databases can not be concatenated together.
|
||||
.P
|
||||
The file name database format changed starting with GNU
|
||||
.B find
|
||||
and
|
||||
.B locate
|
||||
version 4.0 to allow machines with different byte orderings to share
|
||||
version 4.0 to allow machines with diffent byte orderings to share
|
||||
the databases. The new GNU
|
||||
.B locate
|
||||
can read both the old and new database formats.
|
||||
@@ -41,104 +41,38 @@ and
|
||||
produce incorrect results if given a new-format database.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-\-findoptions='\fI\-option1 \-option2...\fP'
|
||||
Global options to pass on to \fBfind\fP.
|
||||
The environment variable \fBFINDOPTIONS\fP also sets this value.
|
||||
Default is none.
|
||||
.TP
|
||||
.B \-\-localpaths='\fIpath1 path2...\fP'
|
||||
Non-network directories to put in the database.
|
||||
Default is /.
|
||||
.TP
|
||||
.B \-\-netpaths='\fIpath1 path2...\fP'
|
||||
Network (NFS, AFS, RFS, etc.) directories to put in the database.
|
||||
The environment variable \fBNETPATHS\fP also sets this value.
|
||||
Default is none.
|
||||
.TP
|
||||
.B \-\-prunepaths='\fIpath1 path2...\fP'
|
||||
Directories to not put in the database, which would otherwise be.
|
||||
Remove any trailing slashes from the path names, otherwise
|
||||
.B updatedb
|
||||
won\'t recognise the paths you want to omit (because it uses them as
|
||||
regular expression patterns).
|
||||
The environment variable \fBPRUNEPATHS\fP also sets this value.
|
||||
Default is /tmp /usr/tmp /var/tmp /afs.
|
||||
.TP
|
||||
.B \-\-prunefs='\fIpath...\fP'
|
||||
File systems to not put in the database, which would otherwise be.
|
||||
Note that files are pruned when a file system is reached;
|
||||
Any file system mounted under an undesired file system will be
|
||||
ignored.
|
||||
The environment variable
|
||||
\fBPRUNEFS\fP also sets this value.
|
||||
Default is \fInfs NFS proc\fP.
|
||||
.TP
|
||||
.B \-\-output=\fIdbfile\fP
|
||||
The database file to build.
|
||||
Default is system-dependent. In Debian GNU/Linux, the default
|
||||
is /var/cache/locate/locatedb.
|
||||
.TP
|
||||
.B \-\-localuser=\fIuser\fP
|
||||
The user to search non-network directories as, using \fBsu\fP(1).
|
||||
Default is to search the non-network directories as the current user.
|
||||
You can also use the environment variable \fBLOCALUSER\fP to set this user.
|
||||
Default is system-dependent, but typically /usr/local/var/locatedb.
|
||||
.TP
|
||||
.B \-\-netuser=\fIuser\fP
|
||||
The user to search network directories as, using \fBsu\fP(1).
|
||||
Default is \fBdaemon\fP.
|
||||
You can also use the environment variable \fBNETUSER\fP to set this user.
|
||||
.TP
|
||||
.B \-\-old\-format
|
||||
Create the database in the old format. This is a synonym for
|
||||
.BR \-\-dbformat=old .
|
||||
.TP
|
||||
.B \-\-dbformat=F
|
||||
Create the database in format F. The default format is called LOCATE02.
|
||||
F can be
|
||||
.B old
|
||||
to select the old database format (this is the same as specifying
|
||||
.BR \-\-old\-format ).
|
||||
Alternatively the
|
||||
.B slocate
|
||||
format is also supported. When the
|
||||
.B slocate
|
||||
format is in use, the database produced is marked as having security
|
||||
level 1. If you want to build a system-wide
|
||||
.B slocate
|
||||
database, you may want to run
|
||||
.B updatedb
|
||||
as root.
|
||||
Create the database in the old format instead of the new one.
|
||||
.TP
|
||||
.B \-\-version
|
||||
Print the version number of
|
||||
.B updatedb
|
||||
and exit.
|
||||
.TP
|
||||
.B "\-\-help"
|
||||
.I "\-\-help"
|
||||
Print a summary of the options to
|
||||
.B updatedb
|
||||
and exit.
|
||||
.SH "SEE ALSO"
|
||||
\fBfind\fP(1), \fBlocate\fP(1), \fBlocatedb\fP(5), \fBxargs\fP(1)
|
||||
\fBfind\fP(1L), \fBlocate\fP(1L), \fBlocatedb\fP(5L), \fBxargs\fP(1L)
|
||||
\fBFinding Files\fP (on-line in Info, or printed)
|
||||
.SH "BUGS"
|
||||
.P
|
||||
The
|
||||
.B updatedb
|
||||
program correctly handles filenames containing newlines,
|
||||
but only if the system's sort command has a working
|
||||
.I \-z
|
||||
option. If you suspect that
|
||||
.B locate
|
||||
may need to return filenames containing newlines, consider using its
|
||||
.I \-\-null
|
||||
option.
|
||||
.P
|
||||
The best way to report a bug is to use the form at
|
||||
http://savannah.gnu.org/bugs/?group=findutils.
|
||||
The reason for this is that you will then be able to track progress in
|
||||
fixing the problem. Other comments about \fBupdatedb\fP(1) and about
|
||||
the findutils package in general can be sent to the
|
||||
.I bug-findutils
|
||||
mailing list. To join the list, send email to
|
||||
.IR bug-findutils-request@gnu.org .
|
||||
|
||||
+50
-272
@@ -1,156 +1,51 @@
|
||||
#! /bin/sh
|
||||
#!/bin/sh
|
||||
# updatedb -- build a locate pathname database
|
||||
# Copyright (C) 1994, 1996, 1997, 2000, 2001, 2003, 2004, 2005, 2006
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# 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.
|
||||
#
|
||||
# the Free Software Foundation; either version 2, 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/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# csh original by James Woods; sh conversion by David MacKenzie.
|
||||
|
||||
#exec 2> /tmp/updatedb-trace.txt
|
||||
#set -x
|
||||
|
||||
version='
|
||||
updatedb (@PACKAGE_NAME@) @VERSION@
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
This is free software: you are free to change and redistribute it.
|
||||
There is NO WARRANTY, to the extent permitted by law.
|
||||
|
||||
Written by Eric B. Decker, James Youngman, and Kevin Dalley.
|
||||
'
|
||||
|
||||
|
||||
usage="\
|
||||
Usage: $0 [--findoptions='-option1 -option2...']
|
||||
[--localpaths='dir1 dir2...'] [--netpaths='dir1 dir2...']
|
||||
[--prunepaths='dir1 dir2...'] [--prunefs='fs1 fs2...']
|
||||
[--output=dbfile] [--netuser=user] [--localuser=user]
|
||||
[--old-format] [--dbformat] [--version] [--help]
|
||||
Usage: updatedb [--localpaths='dir1 dir2...'] [--netpaths='dir1 dir2...']
|
||||
[--prunepaths='dir1 dir2...'] [--output=dbfile] [--netuser=user]
|
||||
[--old-format] [--version] [--help]"
|
||||
|
||||
Report bugs to <bug-findutils@gnu.org>."
|
||||
changeto=/
|
||||
old=no
|
||||
for arg
|
||||
do
|
||||
# If we are unable to fork, the back-tick operator will
|
||||
# fail (and the shell will emit an error message). When
|
||||
# this happens, we exit with error value 71 (EX_OSERR).
|
||||
# Alternative candidate - 75, EX_TEMPFAIL.
|
||||
opt=`echo $arg|sed 's/^\([^=]*\).*/\1/'` || exit 71
|
||||
val=`echo $arg|sed 's/^[^=]*=\(.*\)/\1/'` || exit 71
|
||||
opt=`echo $arg|sed 's/^\([^=]*\).*/\1/'`
|
||||
val=`echo $arg|sed 's/^[^=]*=\(.*\)/\1/'`
|
||||
case "$opt" in
|
||||
--findoptions) FINDOPTIONS="$val" ;;
|
||||
--localpaths) SEARCHPATHS="$val" ;;
|
||||
--netpaths) NETPATHS="$val" ;;
|
||||
--prunepaths) PRUNEPATHS="$val" ;;
|
||||
--prunefs) PRUNEFS="$val" ;;
|
||||
--output) LOCATE_DB="$val" ;;
|
||||
--netuser) NETUSER="$val" ;;
|
||||
--localuser) LOCALUSER="$val" ;;
|
||||
--old-format) old=yes ;;
|
||||
--changecwd) changeto="$val" ;;
|
||||
--dbformat) dbformat="$val" ;;
|
||||
--version) fail=0; echo "$version" || fail=1; exit $fail ;;
|
||||
--help) fail=0; echo "$usage" || fail=1; exit $fail ;;
|
||||
--version) echo "GNU updatedb version @version@"; exit 0 ;;
|
||||
--help) echo "$usage"; exit 0 ;;
|
||||
*) echo "updatedb: invalid option $opt
|
||||
$usage" >&2
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
|
||||
|
||||
|
||||
case "${dbformat:+yes}_${old}" in
|
||||
yes_yes)
|
||||
echo "The --dbformat and --old cannot both be specified." >&2
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$old" = yes || test "$dbformat" = "old" ; then
|
||||
echo "Warning: future versions of findutils will shortly discontinue support for the old locate database format." >&2
|
||||
old=yes
|
||||
sort="@SORT@"
|
||||
print_option="-print"
|
||||
frcode_options=""
|
||||
else
|
||||
frcode_options=""
|
||||
case "$dbformat" in
|
||||
"")
|
||||
# Default, use LOCATE02
|
||||
;;
|
||||
LOCATE02)
|
||||
;;
|
||||
slocate)
|
||||
frcode_options="$frcode_options -S 1"
|
||||
;;
|
||||
*)
|
||||
echo "Unsupported locate database format ${dbformat}: Supported formats are:" >&2
|
||||
echo "LOCATE02, slocate, old" >&2
|
||||
exit 1
|
||||
esac
|
||||
|
||||
|
||||
if @SORT_SUPPORTS_Z@
|
||||
then
|
||||
sort="@SORT@ -z"
|
||||
print_option="-print0"
|
||||
frcode_options="$frcode_options -0"
|
||||
else
|
||||
sort="@SORT@"
|
||||
print_option="-print"
|
||||
fi
|
||||
fi
|
||||
|
||||
getuid() {
|
||||
# format of "id" output is ...
|
||||
# uid=1(daemon) gid=1(other)
|
||||
# for `id's that don't understand -u
|
||||
id | cut -d'(' -f 1 | cut -d'=' -f2
|
||||
}
|
||||
|
||||
# figure out if su supports the -s option
|
||||
select_shell() {
|
||||
if su "$1" -s $SHELL -c false < /dev/null ; then
|
||||
# No.
|
||||
echo ""
|
||||
else
|
||||
if su "$1" -s $SHELL -c true < /dev/null ; then
|
||||
# Yes.
|
||||
echo "-s $SHELL"
|
||||
else
|
||||
# su is unconditionally failing. We won't be able to
|
||||
# figure out what is wrong, so be conservative.
|
||||
echo ""
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# You can set these in the environment, or use command-line options,
|
||||
# to override their defaults:
|
||||
|
||||
# Any global options for find?
|
||||
: ${FINDOPTIONS=}
|
||||
|
||||
# What shell shoud we use? We should use a POSIX-ish sh.
|
||||
: ${SHELL="/bin/sh"}
|
||||
|
||||
# Non-network directories to put in the database.
|
||||
: ${SEARCHPATHS="/"}
|
||||
|
||||
@@ -158,17 +53,7 @@ select_shell() {
|
||||
: ${NETPATHS=}
|
||||
|
||||
# Directories to not put in the database, which would otherwise be.
|
||||
: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /sfs /proc"}
|
||||
|
||||
# Trailing slashes result in regex items that are never matched, which
|
||||
# is not what the user will expect. Therefore we now reject such
|
||||
# constructs.
|
||||
for p in $PRUNEPATHS; do
|
||||
case "$p" in
|
||||
/*/) echo "$0: $p: pruned paths should not contain trailing slashes" >&2
|
||||
exit 1
|
||||
esac
|
||||
done
|
||||
: ${PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs"}
|
||||
|
||||
# The same, in the form of a regex that find can use.
|
||||
test -z "$PRUNEREGEX" &&
|
||||
@@ -180,117 +65,51 @@ test -z "$PRUNEREGEX" &&
|
||||
# Directory to hold intermediate files.
|
||||
if test -d /var/tmp; then
|
||||
: ${TMPDIR=/var/tmp}
|
||||
elif test -d /usr/tmp; then
|
||||
: ${TMPDIR=/usr/tmp}
|
||||
else
|
||||
: ${TMPDIR=/tmp}
|
||||
: ${TMPDIR=/usr/tmp}
|
||||
fi
|
||||
export TMPDIR
|
||||
|
||||
# The user to search network directories as.
|
||||
: ${NETUSER=daemon}
|
||||
|
||||
# The directory containing the subprograms.
|
||||
if test -n "$LIBEXECDIR" ; then
|
||||
: LIBEXECDIR already set, do nothing
|
||||
else
|
||||
: ${LIBEXECDIR=@libexecdir@}
|
||||
fi
|
||||
: ${LIBEXECDIR=@libexecdir@}
|
||||
|
||||
# The directory containing find.
|
||||
if test -n "$BINDIR" ; then
|
||||
: BINDIR already set, do nothing
|
||||
else
|
||||
: ${BINDIR=@bindir@}
|
||||
fi
|
||||
: ${BINDIR=@bindir@}
|
||||
|
||||
# The names of the utilities to run to build the database.
|
||||
: ${find:=${BINDIR}/@find@}
|
||||
: ${frcode:=${LIBEXECDIR}/@frcode@}
|
||||
: ${bigram:=${LIBEXECDIR}/@bigram@}
|
||||
: ${code:=${LIBEXECDIR}/@code@}
|
||||
: ${find=@find@}
|
||||
: ${frcode=@frcode@}
|
||||
: ${bigram=@bigram@}
|
||||
: ${code=@code@}
|
||||
|
||||
|
||||
checkbinary () {
|
||||
if test -x "$1" ; then
|
||||
: ok
|
||||
else
|
||||
eval echo "updatedb needs to be able to execute $1, but cannot." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
for binary in $find $frcode $bigram $code
|
||||
do
|
||||
checkbinary $binary
|
||||
done
|
||||
|
||||
|
||||
PATH=/bin:/usr/bin:${BINDIR}; export PATH
|
||||
|
||||
: ${PRUNEFS="nfs NFS proc afs proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs sysfs shfs"}
|
||||
|
||||
if test -n "$PRUNEFS"; then
|
||||
prunefs_exp=`echo $PRUNEFS |sed -e 's/\([^ ][^ ]*\)/-o -fstype \1/g' \
|
||||
-e 's/-o //' -e 's/$/ -o/'`
|
||||
else
|
||||
prunefs_exp=''
|
||||
fi
|
||||
PATH=$LIBEXECDIR:$BINDIR:/usr/ucb:/bin:/usr/bin:$PATH export PATH
|
||||
|
||||
# Make and code the file list.
|
||||
# Sort case insensitively for users' convenience.
|
||||
|
||||
rm -f $LOCATE_DB.n
|
||||
trap 'rm -f $LOCATE_DB.n; exit' HUP TERM
|
||||
|
||||
if test $old = no; then
|
||||
# LOCATE02 or slocate format
|
||||
if {
|
||||
cd "$changeto"
|
||||
|
||||
# FIXME figure out how to sort null-terminated strings, and use -print0.
|
||||
{
|
||||
if test -n "$SEARCHPATHS"; then
|
||||
if [ "$LOCALUSER" != "" ]; then
|
||||
# : A1
|
||||
su $LOCALUSER `select_shell $LOCALUSER` -c \
|
||||
"$find $SEARCHPATHS $FINDOPTIONS \
|
||||
\\( $prunefs_exp \
|
||||
-type d -regex '$PRUNEREGEX' \\) -prune -o $print_option"
|
||||
else
|
||||
# : A2
|
||||
$find $SEARCHPATHS $FINDOPTIONS \
|
||||
\( $prunefs_exp \
|
||||
-type d -regex "$PRUNEREGEX" \) -prune -o $print_option
|
||||
fi
|
||||
$find $SEARCHPATHS \
|
||||
\( -fstype nfs -o -fstype NFS -o -type d -regex "$PRUNEREGEX" \) -prune -o -print
|
||||
fi
|
||||
|
||||
if test -n "$NETPATHS"; then
|
||||
myuid=`getuid`
|
||||
if [ "$myuid" = 0 ]; then
|
||||
# : A3
|
||||
su $NETUSER `select_shell $NETUSER` -c \
|
||||
"$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" ||
|
||||
exit $?
|
||||
else
|
||||
# : A4
|
||||
$find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option ||
|
||||
exit $?
|
||||
fi
|
||||
fi
|
||||
} | $sort -f | $frcode $frcode_options > $LOCATE_DB.n
|
||||
then
|
||||
: OK so far
|
||||
true
|
||||
else
|
||||
rv=$?
|
||||
echo "Failed to generate $LOCATE_DB.n" >&2
|
||||
rm -f $LOCATE_DB.n
|
||||
exit $rv
|
||||
su $NETUSER -c \
|
||||
"$find $NETPATHS \\( -type d -regex \"$PRUNEREGEX\" -prune \\) -o -print"
|
||||
fi
|
||||
} | sort -f | $frcode > $LOCATE_DB.n
|
||||
|
||||
# To avoid breaking locate while this script is running, put the
|
||||
# results in a temp file, then rename it atomically.
|
||||
if test -s $LOCATE_DB.n; then
|
||||
chmod 644 ${LOCATE_DB}.n
|
||||
mv ${LOCATE_DB}.n $LOCATE_DB
|
||||
rm -f $LOCATE_DB
|
||||
mv $LOCATE_DB.n $LOCATE_DB
|
||||
chmod 644 $LOCATE_DB
|
||||
else
|
||||
echo "updatedb: new database would be empty" >&2
|
||||
rm -f $LOCATE_DB.n
|
||||
@@ -298,73 +117,32 @@ fi
|
||||
|
||||
else # old
|
||||
|
||||
if ! bigrams=`mktemp -t updatedbXXXXXXXXX`; then
|
||||
echo mktemp failed >&2
|
||||
exit 1
|
||||
fi
|
||||
bigrams=$TMPDIR/f.bigrams$$
|
||||
filelist=$TMPDIR/f.list$$
|
||||
trap 'rm -f $bigrams $filelist; exit' 1 15
|
||||
|
||||
if ! filelist=`mktemp -t updatedbXXXXXXXXX`; then
|
||||
echo mktemp failed >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rm -f $LOCATE_DB.n
|
||||
trap 'rm -f $bigrams $filelist $LOCATE_DB.n; exit' HUP TERM
|
||||
|
||||
# Alphabetize subdirectories before file entries using tr. James Woods says:
|
||||
# Alphabetize subdirectories before file entries using tr. James says:
|
||||
# "to get everything in monotonic collating sequence, to avoid some
|
||||
# breakage i'll have to think about."
|
||||
{
|
||||
cd "$changeto"
|
||||
if test -n "$SEARCHPATHS"; then
|
||||
if [ "$LOCALUSER" != "" ]; then
|
||||
# : A5
|
||||
su $LOCALUSER `select_shell $LOCALUSER` -c \
|
||||
"$find $SEARCHPATHS $FINDOPTIONS \
|
||||
\( $prunefs_exp \
|
||||
-type d -regex '$PRUNEREGEX' \) -prune -o $print_option" || exit $?
|
||||
else
|
||||
# : A6
|
||||
$find $SEARCHPATHS $FINDOPTIONS \
|
||||
\( $prunefs_exp \
|
||||
-type d -regex "$PRUNEREGEX" \) -prune -o $print_option || exit $?
|
||||
fi
|
||||
$find $SEARCHPATHS \
|
||||
\( -fstype nfs -o -fstype NFS -o -type d -regex "$PRUNEREGEX" \) -prune -o -print
|
||||
fi
|
||||
|
||||
if test -n "$NETPATHS"; then
|
||||
myuid=`getuid`
|
||||
if [ "$myuid" = 0 ]; then
|
||||
# : A7
|
||||
su $NETUSER `select_shell $NETUSER` -c \
|
||||
"$find $NETPATHS $FINDOPTIONS \\( -type d -regex '$PRUNEREGEX' -prune \\) -o $print_option" ||
|
||||
exit $?
|
||||
else
|
||||
# : A8
|
||||
$find $NETPATHS $FINDOPTIONS \( -type d -regex "$PRUNEREGEX" -prune \) -o $print_option ||
|
||||
exit $?
|
||||
fi
|
||||
su $NETUSER -c \
|
||||
"$find $NETPATHS \\( -type d -regex \"$PRUNEREGEX\" -prune \\) -o -print"
|
||||
fi
|
||||
} | tr / '\001' | $sort -f | tr '\001' / > $filelist
|
||||
} | tr / '\001' | sort -f | tr '\001' / > $filelist
|
||||
|
||||
# Compute the (at most 128) most common bigrams in the file list.
|
||||
$bigram $bigram_opts < $filelist | sort | uniq -c | sort -nr |
|
||||
$bigram < $filelist | sort | uniq -c | sort -nr |
|
||||
awk '{ if (NR <= 128) print $2 }' | tr -d '\012' > $bigrams
|
||||
|
||||
# Code the file list.
|
||||
$code $bigrams < $filelist > $LOCATE_DB.n
|
||||
$code $bigrams < $filelist > $LOCATE_DB
|
||||
chmod 644 $LOCATE_DB
|
||||
|
||||
rm -f $bigrams $filelist
|
||||
|
||||
# To reduce the chances of breaking locate while this script is running,
|
||||
# put the results in a temp file, then rename it atomically.
|
||||
if test -s $LOCATE_DB.n; then
|
||||
chmod 644 ${LOCATE_DB}.n
|
||||
mv ${LOCATE_DB}.n $LOCATE_DB
|
||||
else
|
||||
echo "updatedb: new database would be empty" >&2
|
||||
rm -f $LOCATE_DB.n
|
||||
fi
|
||||
rm -f $bigrams $filelist $errs
|
||||
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
# mkinstalldirs --- make directory hierarchy
|
||||
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||
# Created: 1993-05-16
|
||||
# Last modified: 1994-03-25
|
||||
# Public domain
|
||||
|
||||
errstatus=0
|
||||
|
||||
for file in ${1+"$@"} ; do
|
||||
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||
shift
|
||||
|
||||
pathcomp=
|
||||
for d in ${1+"$@"} ; do
|
||||
pathcomp="$pathcomp$d"
|
||||
case "$pathcomp" in
|
||||
-* ) pathcomp=./$pathcomp ;;
|
||||
esac
|
||||
|
||||
if test ! -d "$pathcomp"; then
|
||||
echo "mkdir $pathcomp" 1>&2
|
||||
mkdir "$pathcomp" || errstatus=$?
|
||||
fi
|
||||
|
||||
pathcomp="$pathcomp/"
|
||||
done
|
||||
done
|
||||
|
||||
exit $errstatus
|
||||
|
||||
# mkinstalldirs ends here
|
||||
+1
-1
@@ -1 +1 @@
|
||||
timestamp
|
||||
Tue Oct 4 11:24:03 EDT 1994
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
XARGS = ../xargs/xargs
|
||||
XARGSFLAGS =
|
||||
|
||||
RUNTEST= runtest
|
||||
RUNTESTFLAGS=
|
||||
|
||||
DIST_OTHER = config/*.exp inputs/*.xi xargs.*/*.exp xargs.*/*.xo
|
||||
DIST_DIRS = config inputs xargs.gnu xargs.posix xargs.sysv
|
||||
|
||||
CLEANFILES = *.log *.sum site.exp site.bak
|
||||
|
||||
check:: site.exp
|
||||
@echo This only works if you have the DejaGNU runtest program installed...
|
||||
$(RUNTEST) $(RUNTESTFLAGS) --tool xargs XARGS=${XARGS} \
|
||||
XARGSFLAGS="${XARGSFLAGS}" --srcdir $(srcdir)
|
||||
|
||||
site.exp:
|
||||
@echo "Making a new site.exp file..."
|
||||
-@rm -f site.bak
|
||||
-@mv site.exp site.bak
|
||||
@echo "## these variables are automatically generated by make ##" > site.exp
|
||||
@echo "# Do not edit here. If you wish to override these values" >> site.exp
|
||||
@echo "# add them to the last section" >> site.exp
|
||||
@echo "set tool xargs" >> site.exp
|
||||
@echo "set srcdir ${srcdir}" >> site.exp
|
||||
@echo "set objdir `pwd`" >> site.exp
|
||||
@echo "## All variables above are generated by configure. Do Not Edit ##" >> site.exp
|
||||
-@sed '1,/^## All variables above are.*##/ d' site.bak >> site.exp
|
||||
|
||||
$(DIST_DIRS): FORCE
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
-for d in $(DIST_DIRS); do \
|
||||
echo mkdir ../`cat ../distname`/$(subdir)/$$d; \
|
||||
mkdir ../`cat ../distname`/$(subdir)/$$d; done
|
||||
|
||||
FORCE:
|
||||
@@ -0,0 +1,118 @@
|
||||
# Makefile.in generated automatically by automake from Makefile.am.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
datadir = $(prefix)/share
|
||||
sysconfdir = $(prefix)/etc
|
||||
sharedstatedir = $(prefix)/com
|
||||
localstatedir = $(prefix)/var
|
||||
libdir = $(exec_prefix)/lib
|
||||
infodir = $(prefix)/info
|
||||
mandir = $(prefix)/man
|
||||
includedir = $(prefix)/include
|
||||
oldincludedir = /usr/include
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
transform = @program_transform_name@
|
||||
|
||||
ALL = ${PROGRAMS} ${LIBPROGRAMS} ${SCRIPTS} ${LIBSCRIPTS} ${LIBFILES}
|
||||
SOURCES =
|
||||
DIST_CONF = Makefile.am Makefile.in
|
||||
DIST_FILES = $(DIST_CONF) $(SOURCES) $(TEXINFOS) $(INFOS) $(MANS) $(DIST_OTHER)
|
||||
|
||||
XARGS = ../xargs/xargs
|
||||
XARGSFLAGS =
|
||||
|
||||
RUNTEST= runtest
|
||||
RUNTESTFLAGS=
|
||||
|
||||
DIST_OTHER = config/*.exp inputs/*.xi xargs.*/*.exp xargs.*/*.xo
|
||||
DIST_DIRS = config inputs xargs.gnu xargs.posix xargs.sysv
|
||||
|
||||
CLEANFILES = *.log *.sum site.exp site.bak
|
||||
|
||||
all:: ${ALL}
|
||||
|
||||
mostlyclean:
|
||||
rm -f *.o core
|
||||
|
||||
clean: mostlyclean
|
||||
rm -f $(PROGRAMS) $(LIBPROGRAMS) $(LIBFILES) $(TEXFILES) $(CLEANFILES)
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile *.tab.c $(DISTCLEANFILES)
|
||||
rm -f config.cache config.log config.status ${CONFIG_HEADER} stamp-h
|
||||
|
||||
realclean: distclean
|
||||
rm -f TAGS $(INFOS)
|
||||
|
||||
dist: $(DIST_FILES) $(DIST_DIRS)
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
@for file in $(DIST_FILES); do \
|
||||
echo linking $$file; \
|
||||
ln $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file || \
|
||||
{ echo copying $$file instead; cp -p $(srcdir)/$$file ../`cat ../distname`/$(subdir)/$$file;}; \
|
||||
done
|
||||
|
||||
check dvi info install uninstall::
|
||||
|
||||
tags:: TAGS
|
||||
|
||||
TAGS::
|
||||
cd $(srcdir); etags $(SOURCES)
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
|
||||
check:: site.exp
|
||||
@echo This only works if you have the DejaGNU runtest program installed...
|
||||
$(RUNTEST) $(RUNTESTFLAGS) --tool xargs XARGS=${XARGS} \
|
||||
XARGSFLAGS="${XARGSFLAGS}" --srcdir $(srcdir)
|
||||
|
||||
site.exp:
|
||||
@echo "Making a new site.exp file..."
|
||||
-@rm -f site.bak
|
||||
-@mv site.exp site.bak
|
||||
@echo "## these variables are automatically generated by make ##" > site.exp
|
||||
@echo "# Do not edit here. If you wish to override these values" >> site.exp
|
||||
@echo "# add them to the last section" >> site.exp
|
||||
@echo "set tool xargs" >> site.exp
|
||||
@echo "set srcdir ${srcdir}" >> site.exp
|
||||
@echo "set objdir `pwd`" >> site.exp
|
||||
@echo "## All variables above are generated by configure. Do Not Edit ##" >> site.exp
|
||||
-@sed '1,/^## All variables above are.*##/ d' site.bak >> site.exp
|
||||
|
||||
$(DIST_DIRS): FORCE
|
||||
-mkdir ../`cat ../distname`/$(subdir)
|
||||
-for d in $(DIST_DIRS); do \
|
||||
echo mkdir ../`cat ../distname`/$(subdir)/$$d; \
|
||||
mkdir ../`cat ../distname`/$(subdir)/$$d; done
|
||||
|
||||
FORCE:
|
||||
@@ -0,0 +1,109 @@
|
||||
# -*- TCL -*-
|
||||
# Test-specific TCL procedures required by DejaGNU.
|
||||
# Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
# Modified by David MacKenzie <djm@gnu.ai.mit.edu> from the gcc files
|
||||
# written by Rob Savoye <rob@cygnus.com>.
|
||||
|
||||
|
||||
# Called by runtest.
|
||||
# Extract and print the version number of xargs.
|
||||
proc xargs_version {} {
|
||||
global XARGS
|
||||
global XARGSFLAGS
|
||||
|
||||
if {[which $XARGS] != 0} then {
|
||||
set tmp [ eval exec $XARGS $XARGSFLAGS --version </dev/null ]
|
||||
regexp "version.*$" $tmp version
|
||||
if [info exists version] then {
|
||||
clone_output "[which $XARGS] $version\n"
|
||||
} else {
|
||||
warning "cannot get version from $tmp."
|
||||
}
|
||||
} else {
|
||||
warning "$XARGS, program does not exist"
|
||||
}
|
||||
}
|
||||
|
||||
# Run xargs and leave the output in $comp_output.
|
||||
# Called by individual test scripts.
|
||||
proc xargs_start { passfail options infile } {
|
||||
global verbose
|
||||
global XARGS
|
||||
global XARGSFLAGS
|
||||
global comp_output
|
||||
|
||||
if {[which $XARGS] == 0} then {
|
||||
error "$XARGS, program does not exist"
|
||||
exit 1
|
||||
}
|
||||
|
||||
set fail_good [string match "f*" $passfail]
|
||||
|
||||
set scriptname [uplevel {info script}]
|
||||
set testbase [file rootname $scriptname]
|
||||
set testname [file tail $testbase]
|
||||
|
||||
set outfile "$testbase.xo"
|
||||
if {$infile != ""} then {
|
||||
set infile "[file dirname [file dirname $testbase]]/inputs/$infile"
|
||||
} else {
|
||||
set infile /dev/null
|
||||
}
|
||||
|
||||
set cmd "$XARGS $XARGSFLAGS $options < $infile > xargs.out"
|
||||
send_log "$cmd\n"
|
||||
if $verbose>1 then {
|
||||
send_user "Spawning \"$cmd\"\n"
|
||||
}
|
||||
|
||||
catch "exec $cmd" comp_output
|
||||
if {$comp_output != ""} then {
|
||||
send_log "$comp_output\n"
|
||||
if $verbose>1 then {
|
||||
send_user "$comp_output\n"
|
||||
}
|
||||
if $fail_good then {
|
||||
pass "$testname"
|
||||
} else {
|
||||
fail "$testname, $comp_output"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if [file exists $outfile] then {
|
||||
set cmp_cmd "cmp xargs.out $outfile"
|
||||
send_log "$cmp_cmd\n"
|
||||
catch "exec $cmp_cmd" cmpout
|
||||
if {$cmpout != ""} then {
|
||||
fail "$testname, $cmpout"
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if {[file size xargs.out] != 0} then {
|
||||
fail "$testname, output should be empty"
|
||||
return
|
||||
}
|
||||
}
|
||||
pass "$testname"
|
||||
}
|
||||
|
||||
# Called by runtest.
|
||||
# Clean up (remove temporary files) before runtest exits.
|
||||
proc xargs_exit {} {
|
||||
catch "exec rm -f xargs.out"
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
firstline
|
||||
secondline
|
||||
_
|
||||
thirdline
|
||||
fourthline
|
||||
@@ -0,0 +1,5 @@
|
||||
firstline
|
||||
secondline
|
||||
EOF
|
||||
thirdline
|
||||
fourthline
|
||||
@@ -0,0 +1,22 @@
|
||||
/src/gnu/autoconf-1.11
|
||||
/src/gnu/autoconf-1.11/README
|
||||
/src/gnu/autoconf-1.11/Makefile.in
|
||||
/src/gnu/autoconf-1.11/INSTALL
|
||||
/src/gnu/autoconf-1.11/NEWS
|
||||
/src/gnu/autoconf-1.11/COPYING
|
||||
/src/gnu/autoconf-1.11/ChangeLog
|
||||
/src/gnu/autoconf-1.11/autoconf.texi
|
||||
/src/gnu/autoconf-1.11/acconfig.h
|
||||
/src/gnu/autoconf-1.11/autoconf.sh
|
||||
/src/gnu/autoconf-1.11/acgeneral.m4
|
||||
/src/gnu/autoconf-1.11/acspecific.m4
|
||||
/src/gnu/autoconf-1.11/configure
|
||||
/src/gnu/autoconf-1.11/configure.in
|
||||
/src/gnu/autoconf-1.11/autoheader.sh
|
||||
/src/gnu/autoconf-1.11/mkinstalldirs
|
||||
/src/gnu/autoconf-1.11/install.sh
|
||||
/src/gnu/autoconf-1.11/autoconf.info
|
||||
/src/gnu/autoconf-1.11/standards.texi
|
||||
/src/gnu/autoconf-1.11/make-stds.texi
|
||||
/src/gnu/autoconf-1.11/standards.info
|
||||
/src/gnu/autoconf-1.11/texinfo.tex
|
||||
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
this is
|
||||
"quoted stuff"
|
||||
and \
|
||||
an embedded newline
|
||||
with 'single quotes' as well.
|
||||
@@ -0,0 +1 @@
|
||||
xargs_start p {-0 -n3} files0.xi
|
||||
@@ -0,0 +1,8 @@
|
||||
/src/gnu/autoconf-1.11 /src/gnu/autoconf-1.11/README /src/gnu/autoconf-1.11/Makefile.in
|
||||
/src/gnu/autoconf-1.11/INSTALL /src/gnu/autoconf-1.11/NEWS /src/gnu/autoconf-1.11/COPYING
|
||||
/src/gnu/autoconf-1.11/ChangeLog /src/gnu/autoconf-1.11/autoconf.texi /src/gnu/autoconf-1.11/acconfig.h
|
||||
/src/gnu/autoconf-1.11/autoconf.sh /src/gnu/autoconf-1.11/acgeneral.m4 /src/gnu/autoconf-1.11/acspecific.m4
|
||||
/src/gnu/autoconf-1.11/configure /src/gnu/autoconf-1.11/configure.in /src/gnu/autoconf-1.11/autoheader.sh
|
||||
/src/gnu/autoconf-1.11/mkinstalldirs /src/gnu/autoconf-1.11/install.sh /src/gnu/autoconf-1.11/autoconf.info
|
||||
/src/gnu/autoconf-1.11/standards.texi /src/gnu/autoconf-1.11/make-stds.texi /src/gnu/autoconf-1.11/standards.info
|
||||
/src/gnu/autoconf-1.11/texinfo.tex
|
||||
@@ -0,0 +1 @@
|
||||
xargs_start p {echo this plus that} {}
|
||||
@@ -0,0 +1 @@
|
||||
this plus that
|
||||
@@ -0,0 +1 @@
|
||||
xargs_start p {-r echo this plus that} {}
|
||||
@@ -0,0 +1 @@
|
||||
xargs_start p {-s470 echo hi there} files.xi
|
||||
@@ -0,0 +1,2 @@
|
||||
hi there /src/gnu/autoconf-1.11 /src/gnu/autoconf-1.11/README /src/gnu/autoconf-1.11/Makefile.in /src/gnu/autoconf-1.11/INSTALL /src/gnu/autoconf-1.11/NEWS /src/gnu/autoconf-1.11/COPYING /src/gnu/autoconf-1.11/ChangeLog /src/gnu/autoconf-1.11/autoconf.texi /src/gnu/autoconf-1.11/acconfig.h /src/gnu/autoconf-1.11/autoconf.sh /src/gnu/autoconf-1.11/acgeneral.m4 /src/gnu/autoconf-1.11/acspecific.m4 /src/gnu/autoconf-1.11/configure
|
||||
hi there /src/gnu/autoconf-1.11/configure.in /src/gnu/autoconf-1.11/autoheader.sh /src/gnu/autoconf-1.11/mkinstalldirs /src/gnu/autoconf-1.11/install.sh /src/gnu/autoconf-1.11/autoconf.info /src/gnu/autoconf-1.11/standards.texi /src/gnu/autoconf-1.11/make-stds.texi /src/gnu/autoconf-1.11/standards.info /src/gnu/autoconf-1.11/texinfo.tex
|
||||
@@ -0,0 +1 @@
|
||||
xargs_start p {-n3} files.xi
|
||||
@@ -0,0 +1,8 @@
|
||||
/src/gnu/autoconf-1.11 /src/gnu/autoconf-1.11/README /src/gnu/autoconf-1.11/Makefile.in
|
||||
/src/gnu/autoconf-1.11/INSTALL /src/gnu/autoconf-1.11/NEWS /src/gnu/autoconf-1.11/COPYING
|
||||
/src/gnu/autoconf-1.11/ChangeLog /src/gnu/autoconf-1.11/autoconf.texi /src/gnu/autoconf-1.11/acconfig.h
|
||||
/src/gnu/autoconf-1.11/autoconf.sh /src/gnu/autoconf-1.11/acgeneral.m4 /src/gnu/autoconf-1.11/acspecific.m4
|
||||
/src/gnu/autoconf-1.11/configure /src/gnu/autoconf-1.11/configure.in /src/gnu/autoconf-1.11/autoheader.sh
|
||||
/src/gnu/autoconf-1.11/mkinstalldirs /src/gnu/autoconf-1.11/install.sh /src/gnu/autoconf-1.11/autoconf.info
|
||||
/src/gnu/autoconf-1.11/standards.texi /src/gnu/autoconf-1.11/make-stds.texi /src/gnu/autoconf-1.11/standards.info
|
||||
/src/gnu/autoconf-1.11/texinfo.tex
|
||||
@@ -0,0 +1 @@
|
||||
xargs_start p {} quotes.xi
|
||||
@@ -0,0 +1,2 @@
|
||||
this is quoted stuff and
|
||||
an embedded newline with single quotes as well.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user